Misc Google Checkout fixes #21

Closed
wants to merge 8 commits into
from
@@ -6,7 +6,7 @@
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django.http import HttpResponse
-from billing.signals import transaction_was_successful, transaction_was_unsuccessful
+from billing import signals
from django.conf.urls.defaults import patterns
from django.utils.decorators import method_decorator
@@ -64,6 +64,11 @@ def generate_cart_xml(self):
items = doc.createElement('items')
cart.appendChild(items)
+ merchant_private_data = doc.createElement('merchant-private-data')
+ cart.appendChild(merchant_private_data)
+ private_data = unicode(self.fields.get("private_data", ""))
+ merchant_private_data.appendChild(doc.createTextNode(private_data))
+
ip_items = self.fields.get("items", [])
for item in ip_items:
it = doc.createElement("item")
@@ -93,6 +98,7 @@ def generate_cart_xml(self):
return_url.appendChild(doc.createTextNode(self.fields["return_url"]))
merchant_checkout_flow.appendChild(return_url)
+
cart_xml = doc.toxml(encoding="utf-8")
hmac_signature = hmac.new(settings.GOOGLE_CHECKOUT_MERCHANT_KEY,
cart_xml,
@@ -112,6 +118,10 @@ def gc_notify_handler(self, request):
self.gc_new_order_notification(request)
elif request.POST['_type'] == 'order-state-change-notification':
self.gc_order_state_change_notification(request)
+ elif request.POST['_type'] == 'charge-amount-notification':
+ # TODO add support for this later
+ pass
+
return HttpResponse(request.POST['serial-number'])
def gc_cart_items_blob(self, post_data):
@@ -173,6 +183,7 @@ def gc_new_order_notification(self, request):
"financial-order-state" : "financial_order_state",
"fulfillment-order-state" : "fulfillment_order_state",
"timestamp" : "timestamp",
+ "shopping-cart.merchant-private-data": "private_data",
}
for (key, val) in resp_fields.iteritems():
@@ -181,24 +192,18 @@ def gc_new_order_notification(self, request):
data['num_cart_items'] = len(post_data.getlist('shopping-cart.items'))
data['cart_items'] = self.gc_cart_items_blob(post_data)
- try:
- resp = GCNewOrderNotification.objects.create(**data)
- # TODO: Make the type more generic
- # TODO: The person might have got charged and yet transaction
- # might have failed here. Need a better way to communicate it
- transaction_was_successful.send(sender=self.__class__, type="purchase", response=resp)
- status = "SUCCESS"
- except:
- transaction_was_unsuccessful.send(sender=self.__class__, type="purchase", response=post_data)
- status = "FAILURE"
-
- return HttpResponse(status)
-
+ resp = GCNewOrderNotification.objects.create(**data)
def gc_order_state_change_notification(self, request):
post_data = request.POST.copy()
order = GCNewOrderNotification.objects.get(google_order_number=post_data['google-order-number'])
order.financial_order_state = post_data['new-financial-order-state']
+ # Send success signal when order state is charged
+ if order.financial_order_state == 'CHARGED':
+ signals.transaction_was_successful.send(sender=self.__class__,
+ type="purchase",
+ response=order)
+
order.fulfillment_order_state = post_data['new-fulfillment-order-state']
order.save()
@@ -6,6 +6,9 @@ class GCNewOrderNotification(models.Model):
serial_number = models.CharField(max_length=255)
google_order_number = models.CharField(max_length=255)
buyer_id = models.CharField(max_length=255)
+
+ # Private merchant data
+ private_data = models.CharField(max_length=255, blank=True)
# Buyer Shipping Address details
shipping_contact_name = models.CharField(max_length=255, blank=True)
@@ -4,6 +4,8 @@
from django import template
from django.template.loader import render_to_string
+register = template.Library()
+
class GoogleCheckoutNode(template.Node):
def __init__(self, integration):
self.integration = template.Variable(integration)
@@ -15,6 +17,7 @@ def render(self, context):
context)
return form_str
+@register.tag
def google_checkout(parser, token):
try:
tag, int_obj = token.split_contents()
@@ -1,27 +1,42 @@
'''
Template tags for paypal offsite payments
'''
-from paypal.standard.forms import PayPalPaymentsForm
+from paypal.standard.forms import PayPalPaymentsForm, PayPalEncryptedPaymentsForm
from django import template
from django.template.loader import render_to_string
register = template.Library()
class PayPalNode(template.Node):
- def __init__(self, integration):
+ def __init__(self, integration, encrypted=False):
self.integration = template.Variable(integration)
+ self.encrypted = encrypted
def render(self, context):
int_obj = self.integration.resolve(context)
+ if self.encrypted:
+ form_class = PayPalEncryptedPaymentsForm
+ else:
+ form_class = PayPalPaymentsForm
form_str = render_to_string("billing/paypal.html",
- {"form": PayPalPaymentsForm(initial=int_obj.fields),
+ {"form": form_class(initial=int_obj.fields),
"integration": int_obj}, context)
return form_str
+
@register.tag
def paypal(parser, token):
try:
tag, int_obj = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError("%r was expecting a single argument" %token.split_contents()[0])
return PayPalNode(int_obj)
+
+
+@register.tag
+def paypal_encrypted(parser, token):
+ try:
+ tag, int_obj = token.split_contents()
+ except ValueError:
+ raise template.TemplateSyntaxError("%r was expecting a single argument" %token.split_contents()[0])
+ return PayPalNode(int_obj, encrypted=True)
@@ -49,7 +49,7 @@ In views.py::
In some_template.html::
- {% load billing_tags %}
+ {% load google_checkout from google_checkout_tags %}
{% google_checkout obj %}
Template renders to something like below::