""" Amazon FPS integration, currently not used. due to issues with Taxes """ import urlparse import urllib import datetime import time import logging from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_POST from django.core.urlresolvers import reverse from django.http import HttpResponseForbidden, HttpResponseRedirect, HttpResponse from billing.integrations.amazon_fps_integration import ( AmazonFpsIntegration as Integration, ) from billing.models import AmazonFPSResponse from billing.signals import transaction_was_successful, transaction_was_unsuccessful from store_order.models import Order, OrderPayment from cart import cart csrf_exempt_m = method_decorator(csrf_exempt) require_POST_m = method_decorator(require_POST) LOGGER = logging.getLogger("fps_integration") class FpsIntegration(Integration): @csrf_exempt_m @require_POST_m def fps_ipn_handler(self, request): LOGGER.debug("In fps_ipn_handler") uri = request.build_absolute_uri() parsed_url = urlparse.urlparse(uri) LOGGER.debug("[fps_ipn_handler] verify signiture") v_resp = self.fps_connection.verify_signature( UrlEndPoint="%s://%s%s" % (parsed_url.scheme, parsed_url.netloc, parsed_url.path), HttpParameters=request.raw_post_data, ) LOGGER.debug("[fps_ipn_handler] v_resp = ".format(v_resp)) LOGGER.debug( "[fps_ipn_handler] v_resp.VerifySignatureResult = ".format( v_resp.VerifySignatureResult ) ) LOGGER.debug( "[fps_ipn_handler] v_resp.VerifySignatureResult.VerificationStatus = ".format( v_resp.VerifySignatureResult.VerificationStatus ) ) if not v_resp.VerifySignatureResult.VerificationStatus == "Success": LOGGER.debug("[fps_ipn_handler] Signature bad") return HttpResponseForbidden() LOGGER.debug("[fps_ipn_handler] Signature good") data = dict(map(lambda x: x.split("="), request.raw_post_data.split("&"))) LOGGER.debug("[fps_ipn_handler] data: {0}".format(data)) for (key, val) in data.iteritems(): data[key] = urllib.unquote_plus(val) if AmazonFPSResponse.objects.filter( transactionId=data["transactionId"] ).count(): LOGGER.debug("[fps_ipn_handler] have an object already") resp = AmazonFPSResponse.objects.get(transactionId=data["transactionId"]) else: LOGGER.debug("[fps_ipn_handler] no object create one") resp = AmazonFPSResponse() for (key, val) in data.iteritems(): attr_exists = hasattr(resp, key) if attr_exists and not callable(getattr(resp, key, None)): if key == "transactionDate": # TODO: add timezone info .gets this RuntimeWarning: DateTimeField received a naive datetime (2013-02-03 10:58:51) while time zone support is active. val = datetime.datetime(*time.localtime(float(val))[:6]) setattr(resp, key, val) resp.save() LOGGER.debug("[fps_ipn_handler] saved object") if resp.statusCode == "Success": LOGGER.debug("[fps_ipn_handler] success") transaction_was_successful.send( sender=self.__class__, type=data["operation"], response=resp ) else: LOGGER.debug( "[fps_ipn_handler] not success it is {0}".format(resp.statusCode) ) if not "Pending" in resp.statusCode: LOGGER.debug("[fps_ipn_handler] send unsuccessful signal") transaction_was_unsuccessful.send( sender=self.__class__, type=data["operation"], response=resp ) # Associate the amazon payment with our order from before. # TODO: this needs to be fully tested.. all scenerios # new payments and updates. LOGGER.debug("[fps_ipn_handler] add info to Order ") try: LOGGER.debug("Cart_id = {0}".format(resp.callerReference)) order = Order.objects.get(cart_id=resp.callerReference) try: order_payment = order.orderpayment except OrderPayment.DoesNotExist: LOGGER.debug("Order_payment does't exist add one") order_payment = OrderPayment() order.orderpayment = order_payment LOGGER.debug("order_payment = {0}".format(order_payment)) try: amazon_payment = order_payment.amazon_payment LOGGER.debug( "There is an amazon_payment already {0}".format(amazon_payment) ) if not amazon_payment: LOGGER.debug("Amazon payment is null, need to set it.") order_payment.amazon_payment = resp except AmazonFPSResponse.DoesNotExist: LOGGER.debug("amazon_payment does't exist add one") order_payment.amazon_payment = resp LOGGER.debug("Save order payment") order_payment.save() LOGGER.debug("Set order status to submitted") order.status = Order.SUBMITTED # TODO: Make sure status is set correctly. order.save() except Exception as e: # TODO log error, send email. LOGGER.debug("Error = {0}".format(e)) # Return a HttpResponse to prevent django from complaining LOGGER.debug("[fps_ipn_handler] Done") return HttpResponse(resp.statusCode) def transaction(self, request): """Ideally at this method, you will check the caller reference against a user id or uniquely identifiable attribute (if you are already not using it as the caller reference) and the type of transaction (either pay, reserve etc). For the sake of the example, we assume all the users get charged $100""" """ {'status': 'SC', 'city': 'Dallas', 'signatureVersion': '2', 'zip': '73933', 'tokenID': 'F3B8EXIKM4RMLDLRDIHH3LGPTSLAMHTPJMQBEUBCFH24HAAZ339CSD2S8RR9LNPF', 'country': 'United+States', 'signature': 'Wc038ij3U0ZmUmKgiFq455WQPz0q7D9TTfUsxNx8WC6Rk%2FGBpGEiFb4gSnQBxY437oAKqEgoaVMF%0AVoWaKw%2Fmp0b88N%2BQpW048l%2FFbgaWr%2FSz3Vs5AamL0JrDfJ7nd3iF3%2BtPU3gmG4D2qfTwBHu%2FQlLk%0A3bHukecNPRpcmPo1jJQ%3D', 'state': 'TX', 'certificateUrl': 'https%3A%2F%2Ffps.sandbox.amazonaws.com%2Fcerts%2F090911%2FPKICert.pem%3FrequestId%3D1mmly3b6mqxve2fuq5vof9sb27gj2nbgt4e0ipj3ff5sxbmo1j', 'expiry': '01%2F2015', 'signatureMethod': 'RSA-SHA1', 'callerReference': '366dcf11-6111-4efb-ac1a-0d0f906cbc62', 'addressLine2': 'Apt.+2B+-+92+DfkR', 'addressLine1': '123+Main+St%2C+200+EduFeG', 'phoneNumber': '5551234567', 'addressName': 'Ken+Cochrane'} """ request_url = request.build_absolute_uri() LOGGER.debug("request_url = {0}".format(request_url)) parsed_url = urlparse.urlparse(request_url) LOGGER.debug("parsed_url = {0}".format(parsed_url)) query = parsed_url.query LOGGER.debug(query) # resp = self.purchase(100, data) LOGGER.debug("---") data = dict(map(lambda x: x.split("="), query.split("&"))) LOGGER.debug(data) LOGGER.debug("---") for (key, val) in data.iteritems(): data[key] = urllib.unquote_plus(val) # if AmazonFPSResponse.objects.filter(transactionId=data["transactionId"]).count(): # resp = AmazonFPSResponse.objects.get(transactionId=data["transactionId"]) # else: # resp = AmazonFPSResponse() # data['TransactionAmount'] = '100' # data['TransactionAmount.Value'] = 1 LOGGER.debug(data) LOGGER.debug("session_key = {0}".format(request.session.session_key)) shopping_cart = cart.get_cart(request) LOGGER.debug("Cart = {0}".format(shopping_cart)) order = Order.objects.get(cart_id=shopping_cart.cart_id) LOGGER.debug("Order = {0}".format(order)) order.phone = data.get("phoneNumber", None) order.shipping_name = data.get("addressName", None) order.shipping_address_1 = data.get("addressLine1", None) order.shipping_address_2 = data.get("addressLine2", None) order.shipping_city = data.get("city", None) order.shipping_state = data.get("state", None) order.shipping_country = data.get("country", None) order.shipping_zip = data.get("zip", None) order.billing_name = data.get("addressName", None) order.billing_address_1 = data.get("addressLine1", None) order.billing_address_2 = data.get("addressLine2", None) order.billing_city = data.get("city", None) order.billing_state = data.get("state", None) order.billing_country = data.get("country", None) order.billing_zip = data.get("zip", None) order.save() # TODO: order.total needs to be more then 0.0 if not, problem. resp = self.purchase(order.total, data) LOGGER.debug(resp["status"]) return HttpResponseRedirect( "%s?status=%s" % (reverse("checkout_receipt"), resp["status"]) )