Example #1
0
def thanks(request, question_id):
	question = Question.objects.get(pk = question_id)
	
	connection = FPSConnection(
		aws_access_key_id = AWS_KEY_ID,
		aws_secret_access_key = AWS_SECRET_KEY,
		is_secure = True,
		host = AMAZON_DOMAIN,
		path = '/',
	)
	
	#verify signature
	returnUrl = 'http://' + SITE_DOMAIN + '/thanks/' + str(question_id)
	httpParameters = {}
	for k, v in dict(request.GET).items():
		httpParameters[k] = v[0]
	LogPipelineResponse.objects.create(question = question, response = str(httpParameters))
	httpParameters = urlencode(httpParameters)
	verifyResponse = connection.verify_signature(returnUrl, httpParameters).__dict__
	
	#check for errors
	if 'errorMessage' in request.GET:
		messages.error(request, request.GET['errorMessage'])
	#check if they're authorized
	if verifyResponse['Status'] == 'Success':
		#charge payment
		callerTokenId = connection.install_caller_instruction()
		LogCallerToken.objects.create(question = question, token = str(callerTokenId))
		recipientTokenId = connection.install_recipient_instruction()
		LogRecipientToken.objects.create(question = question, token = str(recipientTokenId))
		result = connection.pay(
			callerReference = request.GET['callerReference'],
			callerTokenId = callerTokenId,
			recipientTokenId = recipientTokenId,
			senderTokenId = request.GET['tokenID'],
			transactionAmount = str(question.price),
		)
	
		payResponse = result.__dict__
		LogPaymentResponse.objects.create(question = question, response = str(payResponse))
	
		#check for errors
		if 'Status' in payResponse and payResponse['Status']:
			question.published = True
			question.save()
			messages.success(request, 'Your question has been published!')
			
			context = Context({
				'questioner': question.user,
				'url': 'http://' + SITE_DOMAIN + '/question/' + str(question.id),
			})
			sendTemplateEmail('Question posted successfully!', question.user.email, 'questionerThanks', context)
			
			return HttpResponseRedirect('/question/' + str(question.id))
	messages.error(request, 'A problem occurred when processing your payment, please try again.')
	return HttpResponseRedirect('/question/' + str(question.id))
class AmazonFpsIntegration(Integration):
    """
    Fields required:
    transactionAmount: Amount to be charged/authorized
    paymentReason: Description of the transaction
    paymentPage: Page to direct the user on completion/failure of transaction
    """

    display_name = "Amazon Flexible Payment Service"

    def __init__(self, options=None):
        if not options:
            options = {}
        merchant_settings = getattr(settings, "MERCHANT_SETTINGS")
        if not merchant_settings or not merchant_settings.get("amazon_fps"):
            raise IntegrationNotConfigured("The '%s' integration is not correctly "
                                       "configured." % self.display_name)
        amazon_fps_settings = merchant_settings["amazon_fps"]
        self.aws_access_key = options.get("aws_access_key", None) or amazon_fps_settings['AWS_ACCESS_KEY']
        self.aws_secret_access_key = options.get("aws_secret_access_key", None) or amazon_fps_settings['AWS_SECRET_ACCESS_KEY']
        super(AmazonFpsIntegration, self).__init__(options=options)
        self.fps_connection = FPSConnection(self.aws_access_key, self.aws_secret_access_key, **options)

    @property
    def service_url(self):
        if self.test_mode:
            return FPS_SANDBOX_API_ENDPOINT
        return FPS_PROD_API_ENDPOINT

    @property
    def link_url(self):
        tmp_fields = self.fields.copy()
        tmp_fields.pop("aws_access_key", None)
        tmp_fields.pop("aws_secret_access_key", None)
        tmp_fields.pop("paymentPage", None)
        return self.fps_connection.make_url(tmp_fields.pop("returnURL"), 
                                            tmp_fields.pop("paymentReason"),
                                            tmp_fields.pop("pipelineName"),
                                            str(tmp_fields.pop("transactionAmount")),
                                            **tmp_fields)

    def purchase(self, amount, options=None):
        if not options:
            options = {}
        tmp_options = options.copy()
        permissible_options = ["senderTokenId", "recipientTokenId", 
            "chargeFeeTo", "callerReference", "senderReference", "recipientReference",
            "senderDescription", "recipientDescription", "callerDescription",
            "metadata", "transactionDate", "reserve"]
        tmp_options["senderTokenId"] = options["tokenID"]
        for key in options:
            if key not in permissible_options:
                tmp_options.pop(key)
        resp = self.fps_connection.pay(amount, tmp_options.pop("senderTokenId"), 
                                       callerReference=tmp_options.pop("callerReference"),
                                       **tmp_options)
        return {"status": resp[0].TransactionStatus, "response": resp[0]}

    def authorize(self, amount, options=None):
        if not options:
            options = {}
        options["reserve"] = True
        return self.purchase(amount, options)

    def capture(self, amount, options=None):
        if not options:
            options = {}
        assert "ReserveTransactionId" in options, "Expecting 'ReserveTransactionId' in options"
        resp = self.fps_connection.settle(options["ReserveTransactionId"], amount)
        return {"status": resp[0].TransactionStatus, "response": resp[0]}

    def credit(self, amount, options=None):
        if not options:
            options = {}
        assert "CallerReference" in options, "Expecting 'CallerReference' in options"
        assert "TransactionId" in options, "Expecting 'TransactionId' in options"
        resp = self.fps_connection.refund(options["CallerReference"],
                                          options["TransactionId"], 
                                          refundAmount=amount,
                                          callerDescription=options.get("description", None))
        return {"status": resp[0].TransactionStatus, "response": resp[0]}

    def void(self, identification, options=None):
        if not options:
            options = {}
        # Requires the TransactionID to be passed as 'identification'
        resp = self.fps_connection.cancel(identification, 
                                          options.get("description", None))
        return {"status": resp[0].TransactionStatus, "response": resp[0]}

    def get_urls(self):
        urlpatterns = patterns('',
           url(r'^fps-notify-handler/$', self.fps_ipn_handler, name="fps_ipn_handler"),
           url(r'^fps-return-url/$', self.fps_return_url, name="fps_return_url"),
                               )
        return urlpatterns

    @csrf_exempt_m
    @require_POST_m
    def fps_ipn_handler(self, request):
        uri = request.build_absolute_uri()
        parsed_url = urlparse.urlparse(uri)
        resp = self.fps_connection.verify_signature("%s://%s%s" %(parsed_url.scheme, 
                                                                  parsed_url.netloc, 
                                                                  parsed_url.path),
                                                    request.raw_post_data)
        if not resp[0].VerificationStatus == "Success":
            return HttpResponseForbidden()

        data = dict(map(lambda x: x.split("="), request.raw_post_data.split("&")))
        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()
        for (key, val) in data.iteritems():
            attr_exists = hasattr(resp, key)
            if attr_exists and not callable(getattr(resp, key, None)):
                if key == "transactionDate":
                    val = datetime.datetime(*time.localtime(float(val))[:6])
                setattr(resp, key, val)
        resp.save()
        if resp.statusCode == "Success":
            transaction_was_successful.send(sender=self.__class__, 
                                            type=data["operation"], 
                                            response=resp)
        else:
            if not "Pending" in resp.statusCode:
                transaction_was_unsuccessful.send(sender=self.__class__, 
                                                  type=data["operation"], 
                                                  response=resp)
        # Return a HttpResponse to prevent django from complaining
        return HttpResponse(resp.statusCode)

    def fps_return_url(self, request):
        uri = request.build_absolute_uri()
        parsed_url = urlparse.urlparse(uri)
        resp = self.fps_connection.verify_signature("%s://%s%s" %(parsed_url.scheme, 
                                                                  parsed_url.netloc, 
                                                                  parsed_url.path),
                                                    parsed_url.query)
        if not resp[0].VerificationStatus == "Success":
            return HttpResponseForbidden()

        return self.transaction(request)

    def transaction(self, request):
        """Has to be overridden by the subclasses"""
        raise NotImplementedError
Example #3
0
def test():
    conn = FPSConnection()
    # example response from the docs
    params = 'expiry=08%2F2015&signature=ynDukZ9%2FG77uSJVb5YM0cadwHVwYKPMKOO3PNvgADbv6VtymgBxeOWEhED6KGHsGSvSJnMWDN%2FZl639AkRe9Ry%2F7zmn9CmiM%2FZkp1XtshERGTqi2YL10GwQpaH17MQqOX3u1cW4LlyFoLy4celUFBPq1WM2ZJnaNZRJIEY%2FvpeVnCVK8VIPdY3HMxPAkNi5zeF2BbqH%2BL2vAWef6vfHkNcJPlOuOl6jP4E%2B58F24ni%2B9ek%2FQH18O4kw%2FUJ7ZfKwjCCI13%2BcFybpofcKqddq8CuUJj5Ii7Pdw1fje7ktzHeeNhF0r9siWcYmd4JaxTP3NmLJdHFRq2T%2FgsF3vK9m3gw%3D%3D&signatureVersion=2&signatureMethod=RSA-SHA1&certificateUrl=https%3A%2F%2Ffps.sandbox.amazonaws.com%2Fcerts%2F090909%2FPKICert.pem&tokenID=A5BB3HUNAZFJ5CRXIPH72LIODZUNAUZIVP7UB74QNFQDSQ9MN4HPIKISQZWPLJXF&status=SC&callerReference=callerReferenceMultiUse1'
    endpoint = 'http://vamsik.desktop.amazon.com:8080/ipn.jsp'
    conn.verify_signature(endpoint, params)
Example #4
0
class AmazonFpsIntegration(Integration):
    """
    Fields required:
    transactionAmount: Amount to be charged/authorized
    paymentReason: Description of the transaction
    paymentPage: Page to direct the user on completion/failure of transaction
    """

    display_name = "Amazon Flexible Payment Service"

    def __init__(self, options=None):
        if not options:
            options = {}
        merchant_settings = getattr(settings, "MERCHANT_SETTINGS")
        if not merchant_settings or not merchant_settings.get("amazon_fps"):
            raise IntegrationNotConfigured(
                "The '%s' integration is not correctly "
                "configured." % self.display_name)
        amazon_fps_settings = merchant_settings["amazon_fps"]
        self.aws_access_key = options.get(
            "aws_access_key", None) or amazon_fps_settings['AWS_ACCESS_KEY']
        self.aws_secret_access_key = options.get(
            "aws_secret_access_key",
            None) or amazon_fps_settings['AWS_SECRET_ACCESS_KEY']
        super(AmazonFpsIntegration, self).__init__(options=options)
        self.fps_connection = FPSConnection(self.aws_access_key,
                                            self.aws_secret_access_key,
                                            **options)

    @property
    def service_url(self):
        if self.test_mode:
            return FPS_SANDBOX_API_ENDPOINT
        return FPS_PROD_API_ENDPOINT

    @property
    def link_url(self):
        tmp_fields = self.fields.copy()
        tmp_fields.pop("aws_access_key", None)
        tmp_fields.pop("aws_secret_access_key", None)
        tmp_fields.pop("paymentPage", None)
        return self.fps_connection.make_url(
            tmp_fields.pop("returnURL"), tmp_fields.pop("paymentReason"),
            tmp_fields.pop("pipelineName"),
            str(tmp_fields.pop("transactionAmount")), **tmp_fields)

    def purchase(self, amount, options=None):
        if not options:
            options = {}
        tmp_options = options.copy()
        permissible_options = [
            "senderTokenId", "recipientTokenId", "chargeFeeTo",
            "callerReference", "senderReference", "recipientReference",
            "senderDescription", "recipientDescription", "callerDescription",
            "metadata", "transactionDate", "reserve"
        ]
        tmp_options["senderTokenId"] = options["tokenID"]
        for key in options:
            if key not in permissible_options:
                tmp_options.pop(key)
        resp = self.fps_connection.pay(
            amount,
            tmp_options.pop("senderTokenId"),
            callerReference=tmp_options.pop("callerReference"),
            **tmp_options)
        return {"status": resp[0].TransactionStatus, "response": resp[0]}

    def authorize(self, amount, options=None):
        if not options:
            options = {}
        options["reserve"] = True
        return self.purchase(amount, options)

    def capture(self, amount, options=None):
        if not options:
            options = {}
        assert "ReserveTransactionId" in options, "Expecting 'ReserveTransactionId' in options"
        resp = self.fps_connection.settle(options["ReserveTransactionId"],
                                          amount)
        return {"status": resp[0].TransactionStatus, "response": resp[0]}

    def credit(self, amount, options=None):
        if not options:
            options = {}
        assert "CallerReference" in options, "Expecting 'CallerReference' in options"
        assert "TransactionId" in options, "Expecting 'TransactionId' in options"
        resp = self.fps_connection.refund(options["CallerReference"],
                                          options["TransactionId"],
                                          refundAmount=amount,
                                          callerDescription=options.get(
                                              "description", None))
        return {"status": resp[0].TransactionStatus, "response": resp[0]}

    def void(self, identification, options=None):
        if not options:
            options = {}
        # Requires the TransactionID to be passed as 'identification'
        resp = self.fps_connection.cancel(identification,
                                          options.get("description", None))
        return {"status": resp[0].TransactionStatus, "response": resp[0]}

    def get_urls(self):
        urlpatterns = patterns(
            '',
            url(r'^fps-notify-handler/$',
                self.fps_ipn_handler,
                name="fps_ipn_handler"),
            url(r'^fps-return-url/$',
                self.fps_return_url,
                name="fps_return_url"),
        )
        return urlpatterns

    @csrf_exempt_m
    @require_POST_m
    def fps_ipn_handler(self, request):
        uri = request.build_absolute_uri()
        parsed_url = urlparse.urlparse(uri)
        resp = self.fps_connection.verify_signature(
            "%s://%s%s" %
            (parsed_url.scheme, parsed_url.netloc, parsed_url.path),
            request.raw_post_data)
        if not resp[0].VerificationStatus == "Success":
            return HttpResponseForbidden()

        data = dict(
            map(lambda x: x.split("="), request.raw_post_data.split("&")))
        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()
        for (key, val) in data.iteritems():
            attr_exists = hasattr(resp, key)
            if attr_exists and not callable(getattr(resp, key, None)):
                if key == "transactionDate":
                    val = datetime.datetime(*time.localtime(float(val))[:6])
                setattr(resp, key, val)
        resp.save()
        if resp.statusCode == "Success":
            transaction_was_successful.send(sender=self.__class__,
                                            type=data["operation"],
                                            response=resp)
        else:
            if not "Pending" in resp.statusCode:
                transaction_was_unsuccessful.send(sender=self.__class__,
                                                  type=data["operation"],
                                                  response=resp)
        # Return a HttpResponse to prevent django from complaining
        return HttpResponse(resp.statusCode)

    def fps_return_url(self, request):
        uri = request.build_absolute_uri()
        parsed_url = urlparse.urlparse(uri)
        resp = self.fps_connection.verify_signature(
            "%s://%s%s" %
            (parsed_url.scheme, parsed_url.netloc, parsed_url.path),
            parsed_url.query)
        if not resp[0].VerificationStatus == "Success":
            return HttpResponseForbidden()

        return self.transaction(request)

    def transaction(self, request):
        """Has to be overridden by the subclasses"""
        raise NotImplementedError
from boto.fps.connection import FPSConnection
conn = FPSConnection()
# example response from the docs
params = 'expiry=08%2F2015&signature=ynDukZ9%2FG77uSJVb5YM0cadwHVwYKPMKOO3PNvgADbv6VtymgBxeOWEhED6KGHsGSvSJnMWDN%2FZl639AkRe9Ry%2F7zmn9CmiM%2FZkp1XtshERGTqi2YL10GwQpaH17MQqOX3u1cW4LlyFoLy4celUFBPq1WM2ZJnaNZRJIEY%2FvpeVnCVK8VIPdY3HMxPAkNi5zeF2BbqH%2BL2vAWef6vfHkNcJPlOuOl6jP4E%2B58F24ni%2B9ek%2FQH18O4kw%2FUJ7ZfKwjCCI13%2BcFybpofcKqddq8CuUJj5Ii7Pdw1fje7ktzHeeNhF0r9siWcYmd4JaxTP3NmLJdHFRq2T%2FgsF3vK9m3gw%3D%3D&signatureVersion=2&signatureMethod=RSA-SHA1&certificateUrl=https%3A%2F%2Ffps.sandbox.amazonaws.com%2Fcerts%2F090909%2FPKICert.pem&tokenID=A5BB3HUNAZFJ5CRXIPH72LIODZUNAUZIVP7UB74QNFQDSQ9MN4HPIKISQZWPLJXF&status=SC&callerReference=callerReferenceMultiUse1'
endpoint = 'http://vamsik.desktop.amazon.com:8080/ipn.jsp'
conn.verify_signature(endpoint, params)
Example #6
0
from boto.fps.connection import FPSConnection
conn = FPSConnection()
# example response from the docs
params = 'expiry=08%2F2015&signature=ynDukZ9%2FG77uSJVb5YM0cadwHVwYKPMKOO3PNvgADbv6VtymgBxeOWEhED6KGHsGSvSJnMWDN%2FZl639AkRe9Ry%2F7zmn9CmiM%2FZkp1XtshERGTqi2YL10GwQpaH17MQqOX3u1cW4LlyFoLy4celUFBPq1WM2ZJnaNZRJIEY%2FvpeVnCVK8VIPdY3HMxPAkNi5zeF2BbqH%2BL2vAWef6vfHkNcJPlOuOl6jP4E%2B58F24ni%2B9ek%2FQH18O4kw%2FUJ7ZfKwjCCI13%2BcFybpofcKqddq8CuUJj5Ii7Pdw1fje7ktzHeeNhF0r9siWcYmd4JaxTP3NmLJdHFRq2T%2FgsF3vK9m3gw%3D%3D&signatureVersion=2&signatureMethod=RSA-SHA1&certificateUrl=https%3A%2F%2Ffps.sandbox.amazonaws.com%2Fcerts%2F090909%2FPKICert.pem&tokenID=A5BB3HUNAZFJ5CRXIPH72LIODZUNAUZIVP7UB74QNFQDSQ9MN4HPIKISQZWPLJXF&status=SC&callerReference=callerReferenceMultiUse1'
endpoint = 'http://vamsik.desktop.amazon.com:8080/ipn.jsp'
conn.verify_signature(endpoint, params)