Home > air, flex, payment gateways, tutorials > Using Amazon Flexible Payment System with Flex & AIR

Using Amazon Flexible Payment System with Flex & AIR

July 26th, 2009

I’ve already talked about using Flex with Amazon FPS, so now let’s see what is involved in taking this out of the browser into an AIR app. I recommend reading that article before reading this one, since many of the security considerations described there in detail are valid for AIR applications also. In this article I will only highlight the differences between building a Flex application that runs in the browser and one that runs on the desktop.

Although AIR applications run on the desktop and the local security constraints are different from those in the browser, from a payment gateway point of view things don’t change at all. As a result, we can conclude that because AIR is a client technology hardcoding sensitive information into an AIR app is highly insecure (even though the code is compiled into bytecode). This means that any signature related computation should NOT be made in AIR and the Amazon Secret Key should NOT under any circumstance be put into an AIR App.

Architectural Approach and UI solutions

Summing this up, our architectural solution has to comply with two concurrent demands:

  • an AIR front-end that is stateful and is built following the single page app paradigm
  • the security need that the AIR app should NOT deal with Amazon Security Key plus the need to go to the Amazon co-branded page to authenticate the users
    In order to address these I propose the following approach:

  • All payment related processing should be done on the server side to protect the Amazon Secret Key. Of course this means that the AIR app must be on-line when the payment takes place.
  • The access to the co-branded page should be done in a browser page. IMPORTANT SECURITY NOTE:  Although technically it might be possible to use the HTML container of the AIR runtime this is an unsecure practice because the end user cannot visually verify that he is entering his credentials on the Amazon site. In the browser he can check the URL and the security certificate.

Calling the Amazon Co-Branded User Interface

So the Amazon co-branded UI should be open in a browser window. Here is how to do that in the AIR app.

var url:URLRequest = new URLRequest("http://localhost/amazonAIR/startPayment.php");
url.data = new URLVariables();
var obj:URLVariables = new URLVariables();
url.data.movieId = 1;
url.data.paymentReason = 'Enter The Matrix';
url.method = "GET";
navigateToURL(url, "new");

Everything else is pretty similar with how you call the Amazon co-branded UI from a Flex app that runs in the browser.

Exactly the same goes with returning from Amazon and making the Pay request.

Using LocalConnection to notify the AIR App

The only thing left now is to notify the AIR application and bring it to front.

To do that we need to communicate between the browser app and the AIR app. In order to achieve this we can use the LocalConnection mechanism. LocalConnection objects can communicate among files that are running on the same client computer, but they can be running in different applications — for example, a file running in a browser and a SWF file running in Adobe AIR.

Now there is one important thing to remember about LocalConnection. It can be tricked using techniques like DNS rewriting. So we will not pass any sensitive information through LocalConnection. However, since the AIR app is independent from the browser this means that our browser app has a different server session than the AIR App. So a simple notification is not enough, we need to also pass the session id. This is not sensitive information, but it will allow the AIR application to retrieve from the server any sensitive information that the browser application has set.

Let’s take a look what we need to do right after the return.php page made the PAY operation.

For simplicity the returnAir.php page will have a link to a little Flex app that will communicate with the AIR app. All it needs to do is to get the cookie information and send it through LocalConnection to the AIR app:

private var outbound:LocalConnection = new LocalConnection();

private function gotoAIR():void {
	//get the cookie string
	ExternalInterface.call('eval','window.cookieStr = function () {return document.cookie};')
	var cookieStr:String = ExternalInterface.call('cookieStr');

	outbound.connect("paymentSample");
	outbound.send("app#amazonAIR:paymentSample","notifyPayment",cookieStr);
	//outbound.send("app#testAmazonAir.F0B3F68E1857B8A07069FED1D0638CAF200F76EB.1:paymentSample","notifyPayment",cookieStr);
	outbound.close();
}

Please notice that when launching from Flex Builder the AIR Application has no Publisher ID so the connection name is “app#amazonAIR:paymentSample”. After packaging and installation the AIR app will get a Publisher ID so the connection name becomes something like this: app#amazonAIR.F0B3F68E1857B8A07069FED1D0638CAF200F76EB.1:paymentSample

You can get the publisher ID of the installed AIR App by looking at the META-INF/AIR/publisherid file within the application install directory.

Back in our AIR app we need to expose a function to be available on LocalConnection.

//This will be used by return.php to notify the AIR App
//that the payment has been made
private var inbound:LocalConnection = new LocalConnection();

private function initApp():void {
	//only allow connections from localhost
	//you need to replace "localhost" with the final domain
	//where your application will be hosted
	inbound.allowDomain("localhost");
	inbound.client = new Object();
	//this is the function that will be called by the Browser App
	inbound.client.notifyPayment = paymentNotification;
	inbound.connect("paymentSample");
}

Where paymentNotification is a function that receives the cookie string as parameters and queries the server to check the transaction status:

public function paymentNotification(cookieStr:String):void {
	var srv:HTTPService = new HTTPService();
	srv.headers.Cookie = cookieStr;
	srv.url = "http://localhost/amazonAIR/paymentStatus.php";
	srv.addEventListener(ResultEvent.RESULT,function (event:ResultEvent):void {
		nativeApplication.activate();
		if (event.result.status == 'OK') {
			currentState = 'Succes';
		} else {
			currentState = 'Fail';
		}
	});
	srv.send();
}

Installing the sample files

  1. In Flash Builder click File->Import .. and choose Flash Builder Project
  2. Choose AmazonAIR.fxp
  3. Unzip amazonAIR.zip into your Web Root folder (For example: /work/www).
  4. Edit amazonAIR/amazon-fps/src/Amazon/FPS/Samples/.config.inc.php and replace
  5. define('AWS_ACCESS_KEY_ID', 'YOUR ACCESS KEY');
    define('AWS_SECRET_ACCESS_KEY', 'YOUR SECRET ACCESS KEY');
    

    with your own Amazon ACCESS key and SECRET_ACCESS_KEY.

  6. In Flash Builder click File->Import … and choose Flash Builder Project.
  7. Choose amazonAIRReturn.fxp
  8. Fill the Output Folder Location (this one should point to where you have unzipped amazonAIR.zip, in your web root), Web Root and Root URL with your values. It should look something like this:

Categories: air, flex, payment gateways, tutorials Tags:
  1. September 23rd, 2009 at 16:46 | #1

    Wow, I did not realise payment gateways were so complex. You never think of the back end when you are just working on the front end.
    Thanks for the in-depth explanation.

  2. Amit
    September 25th, 2009 at 09:42 | #2

    where i get AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY

Comments are closed.