Example #1
0
 def setUp(self):
     self.fps = FPSConnection(host='fps.sandbox.amazonaws.com')
     if advanced:
         self.activity = self.fps.get_account_activity(\
                             StartDate='2012-01-01')
         result = self.activity.GetAccountActivityResult
         self.transactions = result.Transaction
Example #2
0
 def __init__(self, *args, **kw):
     TestCase.__init__(self, *args, **kw)
     self.fps = FPSConnection(host='fps.sandbox.amazonaws.com')
     if advanced:
         self.activity = self.fps.get_account_activity(\
                             StartDate='2012-01-01')
         result = self.activity.GetAccountActivityResult
         self.transactions = result.Transaction
Example #3
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))
Example #4
0
 def __init__(self, options=None):
     if not options:
         options = {}
     self.aws_access_key = options.get("aws_access_key",
                                       None) or settings.AWS_ACCESS_KEY
     self.aws_secret_access_key = options.get(
         "aws_secret_access_key", None) or 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)
Example #5
0
def ask(request):
	user = request.user
	q = None
	if request.method == 'POST':
		questionForm = QuestionForm(user, request.POST)
		if questionForm.is_valid():
			if not user.is_authenticated():
				if questionForm.cleaned_data['newUser'] == u'True':
					email = questionForm.cleaned_data['email']
					user, password = createUserFromEmail(email, request)
					key = hashlib.sha256(user.password).hexdigest()[:8]
					activateUrl = 'http://' + SITE_DOMAIN + '/activate/' + email + '/' + key
					
					context = Context({
						'activateUrl': activateUrl,
						'password': password,
					})
					sendTemplateEmail('Welcome to code4cheap.com', email, 'questionerSignup', context)
				else:
					email = questionForm.cleaned_data['email']
					user = User.objects.filter(email = email)[0]
					user = authenticate(username = user.username, password = questionForm.cleaned_data['password'])
			q = Question.objects.create(
				text = questionForm.cleaned_data['text'],
				price = questionForm.cleaned_data['bounty'],
				user = user,
			)
			#redirect to amazon pipeline
			connection = FPSConnection(
				aws_access_key_id = AWS_KEY_ID,
				aws_secret_access_key = AWS_SECRET_KEY,
				is_secure = True,
				host = AMAZON_DOMAIN,
				path = '/',
			)
			url = connection.make_url(
				cobrandingUrl = AMAZON_COBRAND,
				returnURL = 'http://' + SITE_DOMAIN + '/thanks/' + str(q.id),
				paymentReason = 'Question on code4cheap',
				pipelineName = 'SingleUse',
				transactionAmount = str(q.price),
			)
			return HttpResponseRedirect(url)
	else:
		questionForm = QuestionForm(user, initial = {'bounty': u'10', 'newUser': '******'})
	return render_to_response('ask.html', {
		'questionForm': questionForm
	}, context_instance = RequestContext(request))
 def __init__(self, options=None):
     if not options:
         options = {}
     self.aws_access_key = options.get("aws_access_key", None) or settings.AWS_ACCESS_KEY
     self.aws_secret_access_key = options.get("aws_secret_access_key", None) or 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)
Example #7
0
 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)
Example #8
0
def get(amazonProvider):

    try:
        options = {}
        options['host'] = 'fps.amazonaws.com'
        boto_aws = FPSConnection(amazonProvider.getAccessKey(), amazonProvider.getSecretKey(), **options)

        options = {}
        options['StartDate'] = amazonProvider.getStartDate().strftime("%Y-%m-%d")
        options['EndDate'] = amazonProvider.getEndDate().strftime("%Y-%m-%d")

        obj = boto_aws.get_account_activity(**options)
        result = obj.GetAccountActivityResult
        amazonProvider._payments = result.Transaction

        return result.Transaction

    except Exception, e:
        log.writeError(e)
        return None
 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)
Example #10
0
def connect_fps(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
    """
    @type aws_access_key_id: string
    @param aws_access_key_id: Your AWS Access Key ID
    
    @type aws_secret_access_key: string
    @param aws_secret_access_key: Your AWS Secret Access Key
    
    @rtype: L{FPSConnection<boto.fps.connection.FPSConnection>}
    @return: A connection to FPS
    """
    from boto.fps.connection import FPSConnection
    return FPSConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
Example #11
0
def connect_fps(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):
    """
    :type aws_access_key_id: string
    :param aws_access_key_id: Your AWS Access Key ID

    :type aws_secret_access_key: string
    :param aws_secret_access_key: Your AWS Secret Access Key

    :rtype: :class:`boto.fps.connection.FPSConnection`
    :return: A connection to FPS
    """
    from boto.fps.connection import FPSConnection
    return FPSConnection(aws_access_key_id, aws_secret_access_key, **kwargs)
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 #13
0
def get_fps_connection():
    # Disabled SSL certificate verification due to GAE problems with Boto and SSL library
    # Reference: https://groups.google.com/forum/#!topic/boto-users/lzOKsZFKTM8
    return FPSConnection(settings.AWS_ACCESS_KEY_ID,
                         settings.AWS_SECRET_KEY_ID,
                         validate_certs=False)
Example #14
0
class FPSTestCase(unittest.TestCase):

    def setUp(self):
        self.fps = FPSConnection(host='fps.sandbox.amazonaws.com')
        if advanced:
            self.activity = self.fps.get_account_activity(\
                                StartDate='2012-01-01')
            result = self.activity.GetAccountActivityResult
            self.transactions = result.Transaction

    @unittest.skipUnless(simple, "skipping simple test")
    def test_get_account_balance(self):
        response = self.fps.get_account_balance()
        self.assertTrue(hasattr(response, 'GetAccountBalanceResult'))
        self.assertTrue(hasattr(response.GetAccountBalanceResult,
                                                'AccountBalance'))
        accountbalance = response.GetAccountBalanceResult.AccountBalance
        self.assertTrue(hasattr(accountbalance, 'TotalBalance'))
        self.assertIsInstance(accountbalance.TotalBalance, ComplexAmount)
        self.assertTrue(hasattr(accountbalance, 'AvailableBalances'))
        availablebalances = accountbalance.AvailableBalances
        self.assertTrue(hasattr(availablebalances, 'RefundBalance'))

    @unittest.skipUnless(simple, "skipping simple test")
    def test_complex_amount(self):
        response = self.fps.get_account_balance()
        accountbalance = response.GetAccountBalanceResult.AccountBalance
        asfloat = float(accountbalance.TotalBalance.Value)
        self.assertIn('.', str(asfloat))

    @unittest.skipUnless(simple, "skipping simple test")
    def test_required_arguments(self):
        with self.assertRaises(KeyError):
            self.fps.write_off_debt(AdjustmentAmount=123.45)

    @unittest.skipUnless(simple, "skipping simple test")
    def test_cbui_url(self):
        inputs = {
            'transactionAmount':    123.45,
            'pipelineName':         'SingleUse',
            'returnURL':            'https://localhost/',
            'paymentReason':        'a reason for payment',
            'callerReference':      'foo',
        }
        result = self.fps.cbui_url(**inputs)
        print "cbui_url() yields {0}".format(result)

    @unittest.skipUnless(simple, "skipping simple test")
    def test_get_account_activity(self):
        response = self.fps.get_account_activity(StartDate='2012-01-01')
        self.assertTrue(hasattr(response, 'GetAccountActivityResult'))
        result = response.GetAccountActivityResult
        self.assertTrue(hasattr(result, 'BatchSize'))
        try:
            int(result.BatchSize)
        except:
            self.assertTrue(False)

    @unittest.skipUnless(advanced, "skipping advanced test")
    def test_get_transaction(self):
        assert len(self.transactions)
        transactionid = self.transactions[0].TransactionId
        result = self.fps.get_transaction(TransactionId=transactionid)
        self.assertTrue(hasattr(result.GetTransactionResult, 'Transaction'))

    @unittest.skip('cosmetic')
    def test_bad_request(self):
        try:
            self.fps.write_off_debt(CreditInstrumentId='foo',
                                    AdjustmentAmount=123.45)
        except Exception as e:
            print e

    @unittest.skip('cosmetic')
    def test_repr(self):
        print self.fps.get_account_balance()
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 #16
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 #17
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)
Example #18
0
from boto.fps.connection import FPSConnection
conn = FPSConnection()
conn.install_caller_instruction()
conn.install_recipient_instruction()
Example #19
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
Example #20
0
class FPSTestCase(unittest.TestCase):
    def setUp(self):
        self.fps = FPSConnection(host="fps.sandbox.amazonaws.com")
        if advanced:
            self.activity = self.fps.get_account_activity(StartDate="2012-01-01")
            result = self.activity.GetAccountActivityResult
            self.transactions = result.Transaction

    @unittest.skipUnless(simple, "skipping simple test")
    def test_get_account_balance(self):
        response = self.fps.get_account_balance()
        self.assertTrue(hasattr(response, "GetAccountBalanceResult"))
        self.assertTrue(hasattr(response.GetAccountBalanceResult, "AccountBalance"))
        accountbalance = response.GetAccountBalanceResult.AccountBalance
        self.assertTrue(hasattr(accountbalance, "TotalBalance"))
        self.assertIsInstance(accountbalance.TotalBalance, ComplexAmount)
        self.assertTrue(hasattr(accountbalance, "AvailableBalances"))
        availablebalances = accountbalance.AvailableBalances
        self.assertTrue(hasattr(availablebalances, "RefundBalance"))

    @unittest.skipUnless(simple, "skipping simple test")
    def test_complex_amount(self):
        response = self.fps.get_account_balance()
        accountbalance = response.GetAccountBalanceResult.AccountBalance
        asfloat = float(accountbalance.TotalBalance.Value)
        self.assertIn(".", str(asfloat))

    @unittest.skipUnless(simple, "skipping simple test")
    def test_required_arguments(self):
        with self.assertRaises(KeyError):
            self.fps.write_off_debt(AdjustmentAmount=123.45)

    @unittest.skipUnless(simple, "skipping simple test")
    def test_cbui_url(self):
        inputs = {
            "transactionAmount": 123.45,
            "pipelineName": "SingleUse",
            "returnURL": "https://localhost/",
            "paymentReason": "a reason for payment",
            "callerReference": "foo",
        }
        result = self.fps.cbui_url(**inputs)
        print "cbui_url() yields {0}".format(result)

    @unittest.skipUnless(simple, "skipping simple test")
    def test_get_account_activity(self):
        response = self.fps.get_account_activity(StartDate="2012-01-01")
        self.assertTrue(hasattr(response, "GetAccountActivityResult"))
        result = response.GetAccountActivityResult
        self.assertTrue(hasattr(result, "BatchSize"))
        try:
            int(result.BatchSize)
        except:
            self.assertTrue(False)

    @unittest.skipUnless(advanced, "skipping advanced test")
    def test_get_transaction(self):
        assert len(self.transactions)
        transactionid = self.transactions[0].TransactionId
        result = self.fps.get_transaction(TransactionId=transactionid)
        self.assertTrue(hasattr(result.GetTransactionResult, "Transaction"))

    @unittest.skip("cosmetic")
    def test_bad_request(self):
        try:
            self.fps.write_off_debt(CreditInstrumentId="foo", AdjustmentAmount=123.45)
        except Exception, e:
            print e
from boto.fps.connection import FPSConnection
conn = FPSConnection()
conn.install_caller_instruction()
conn.install_recipient_instruction()