Amazon Flexible Payment Service¶
Amazon FPS, is a service that allows for building very flexible payment systems. The service can be classified as a part Gateway and part Integration (offsite processor). This is because the customer is redirected to the Amazon site where he authorizes the payment and after this the customer is redirected back to the merchant site with a token that is used by the merchant to transact with the customer. In plain offsite processors, the authorization and transaction take place in one shot almost simultaneously.
Since the service isn’t conventional (though very flexible), implementing FPS in merchant takes a couple of steps more.
The documentation for the service is available at Amazon FPS Docs.
Note
This integration has a dependency on boto
, a popular AWS library for python.
Settings attributes required for this integration are:
AWS_ACCESS_KEY
: The Amazon AWS access key available from the user’s AWS dashboard.AWS_SECRET_ACCESS_KEY
: The Amazon AWS secret access key also available from the user’s dashboard. Shouldn’t be distributed to anyone.
Settings attributes:
MERCHANT_TEST_MODE = True
MERCHANT_SETTINGS = {
"amazon_fps": {
"AWS_ACCESS_KEY": "???",
"AWS_SECRET_ACCESS_KEY": "???"
}
}
Here are the methods and attributes implemented on the AmazonFpsIntegration
class:
__init__(options = {})
: The constructor takes a dictionary of options that are used to initialize the underlyingFPSConnection
that is bundled withboto
.service_url
: A property that returns the API Endpoint depending on whether the the integration is intest_mode
or not.link_url
: A property that returns the link which redirects the customer to the Amazon Payments site to authorize the transaction.purchase(amount, options={})
: The method that charges a customer right away for the amountamount
after receiving a successful token from Amazon. Theoptions
dictionary is generated from thereturn_url
on successful redirect from the Amazon payments page. This method returns a dictionary with two items,status
representing the status andresponse
representing the response as described byboto.fps.response.FPSResponse
.authorize(amount, options={})
: Similar to thepurchase
method except that it reserves the payment and doesn’t not charge until acapture
(settle) is not called. The response is the same as that ofpurchase
.capture(amount, options={})
: Captures funds from an authorized transaction. The response is the same as the above two methods.credit(amount, options={})
: Refunds a part of full amount of the transaction.void(identification, options={})
: Cancel/Null an authorized transaction.fps_ipn_handler
: A method that handles the asynchronous HTTP POST request from the Amazon IPN and saves into theAmazonFPSResponse
model.fps_return_url
: This method verifies the source of the return URL from Amazon and directs to the transaction.transaction
: This is the main method that charges/authorizes funds from the customer. This method has to be subclassed to implement the logic for the transaction on return from the Amazon Payments page.
Example¶
In any app that is present in the settings.INSTALLED_APPS
, subclass the
AmazonFpsIntegration
and implement the transaction
method. The file
should be available under <app>/integrations/<integration_name>_integration.py
:
class FpsIntegration(AmazonFpsIntegration):
# The class name is based on the filename.
# So if the files exists in <app>/integrations/fps_integration.py
# then the class name should be FpsIntegration
def transaction(self, request):
# Logic to decide if the user should
# be charged immediately or funds
# authorized and then redirect the user
# Below is an example:
resp = self.purchase(10, {...})
if resp["status"] == "Success":
return HttpResponseRedirect("/success/")
return HttpResponseRedirect("/failure/")
In urls.py:
from billing import get_integration
amazon_fps = get_integration("fps")
urlpatterns += patterns('',
(r'^amazon_fps/', include(amazon_fps.urls)),
# You'll have to register /amazon_fps/fps-notify-handler/ in the
# Amazon FPS admin dashboard for the notification URL
)
In views.py:
from billing import get_integration
def productPage(request):
amazon_fps = get_integration("fps")
url_scheme = "http"
if request.is_secure():
url_scheme = "https"
domain = RequestSite(request).domain
fields = {"transactionAmount": "100",
"pipelineName": "SingleUse",
"paymentReason": "Merchant Test",
"paymentPage": request.build_absolute_uri(),
# Send the correct url where the redirect should happen
"returnURL": "%s://%s%s" % (url_scheme,
domain,
reverse("fps_return_url")),
}
# You might want to save the fields["callerReference"] that
# is auto-generated in the db or session to uniquely identify
# this user (or use the user id as the callerReference) because
# amazon passes this callerReference back in the return URL.
amazon_fps.add_fields(fields)
return render_to_response("some_template.html",
{"fps": amazon_fps},
context_instance=RequestContext(request))
In some_template.html:
{% load render_integration from billing_tags %}
{% render_integration fps %}
The above template renders the following code:
<p><a href="https://authorize.payments-sandbox.amazon.com/cobranded-ui/actions/start?callerKey=AKIAI74UIJQ37QS6XLTA&callerReference=5d37ac69-82ac-4bb1-98a4-18c3f9ff15f4&paymentReason=Merchant%20Test&pipelineName=SingleUse&returnURL=http%3A%2F%2Fmerchant.agiliq.com%2Ffps%2Ffps-return-url%2F&signature=wh9PSXAyKfPKizPL%2FRdrYbb24XsoE0efrtMGQBBSs3k%3D&signatureMethod=HmacSHA256&signatureVersion=2&transactionAmount=100"><img src="http://g-ecx.images-amazon.com/images/G/01/cba/b/p3.gif" alt="Amazon Payments" /></a>