Implementing the Amazon In-App Purchasing API in your HTML5 web apps

Via Amazon Mobile App Distribution Blog

Amazon allows you to distribute your web apps and mobile-optimized HTML5 websites to millions of Amazon Appstore customers in nearly 200 countries across the globe.  With Amazon’s In-App Purchasing API for JavaScript you can increase revenue by enabling compelling monetization strategies.  This includes a “freemium” model for your app where the app itself is free but you charge a premium for advanced services or functionality.  Your web app can offer customers in app currency, subscriptions and entitlements all through the secure Amazon checkout process.

GETTING STARTED

The first step in implementing In-App Purchasing in your web apps is to download the Amazon Mobile App SDK, then you will submit a new web app to the portal and then finally add a reference to the Amazon Web API libraries in your html.

The latest versions of the Amazon Web API libraries are hosted by Amazon for you.  The current urls can always be found in the LATEST_URLS.txt file located in the Amazon Mobile App SDK folder.

Simply add these references to your root html file like the index.html file of the Button-Clicker example below:

 

<!DOCTYPE html>

<html>

<head>

<title>Button Tester</title>

<!– Use of this sample code involves calling jQuery from Google

Hosted Libraries and is subject to the terms located here:

https://developers.google.com/speed/libraries/terms

–>

<script src=”https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js” type=”text/javascript”></script>

<script src=”https://amazon-web-app-resources.s3.amazonaws.com/v0/latest/Amazon-Web-App-API.min.js” type=”text/javascript”></script>

<script src=”https://amazon-web-app-resources.s3.amazonaws.com/v0/latest/Amazon-Web-App-API-tester.min.js” type=”text/javascript”></script>

<script src=”js/buttonclicker.js” type=”text/javascript”></script>

<link rel=”stylesheet” href=”buttons.css”/>

</head>

 

Once you have referenced these JavaScript files you will have everything you need to access the Amazon In-App Purchasing API from your web app.

SETTING UP YOUR CATALOG

Before you can make any In-App Purchase calls you need to have a catalog of SKUs set for your web app to use.  You can add SKUs to your web app’s catalog by opening the Developer Console, selecting Apps & Services, choosing the web app submission you want to add SKUs to and then clicking on the In-App Items link, which will take you to the list of SKUs currently offered in your web app.

There are three types of SKUs you can offer to your customers.

·         Consumables – This type of purchase is available only on the device it was purchased on.  Some consumable examples include in-game currency or an extra power up in a game.

·         Entitlements – This is content that requires access rights such as unlocking additional game levels or offering specific magazine issues.  Entitlements do not expire, are tied to a customer’s Amazon account and are available on any device they access the content from.

·         Subscriptions – These are entitlements that are bound by a period of time which auto-renews at the end of the period and is tied to the customer’s Amazon account. Subscriptions are available on any device a customer accesses the content from. You are allowed to have multiple subscriptions for purchase within your app.

 

Simply click on the type of SKU you would like to add and you will be taken to a new screen where you can provide information about the SKU.  For example, if I wanted to offer an Entitlement purchase for my World of Warcraft Realm Status app to track a single realm I would click Add an Entitlement and then enter a Title and SKU.

 

Next you will need to enter pricing information for your new SKU.  In this case, I want to sell a Track Single Realm for $1.00.  Amazon gives you the option of setting your own list price for each marketplace or it can match the prices based on your entered base price.

 

You can also enter a detailed description, along with keywords for the Entitlement.  Descriptions can be provided in multiple languages and if no translations are given the default English description will be used.

 

You also need to provide images of the item for users along with the image you want displayed upon a successful purchase.

 

Once you  have completed this, click Save, and then Submit In-App Item.  You will be taken back to our In-App Items screen with the new SKU now listed.  In the upper right corner will be a button to download a JSON Data file.

This JSON file will include a list of our SKUs that will be used by the SDK Tester Tool when we want to simulate a purchase in our development environment.

 

The SDK Tester Tool is included in the Amazon AVD Launcher emulators or it can be installed on a device via the APK included in the Amazon Mobile App SDK under the /Android/InAppPurchasing/tools.

The Button Clicker example includes a similar JSON file that covers all of the purchasable item types.

PURCHASE PROCESS FLOW

The JavaScript In-App Purchasing API is designed to encapsulate the complexity behind the purchase process while providing a fully featured API. While building your app, it is important to understand which parts of the purchase flow the app must implement, and which parts are handled by the Amazon Services library.

Note: In order to protect customers, we also require that you serve the page of your app that uses In-App Purchasing over  SSL/HTTPS. For more information, please refer to the Making Your Web App Safe documentation

Below is a simplified chart explaining responsibilities during the purchase flow.

 

In-App Purchasing API for JavaScript is comprised of three elements:

  • Amazon Services JavaScript – The class/API that manages the interaction between the application and Amazon’s native APIs.
  • Purchase Handlers – The object your application provides to respond to callbacks from the Amazon Services JavaScript. They are registered as an observer to the Amazon Services In-App Purchasing API.
  • Receipt Verification Service – An HTTP service you should use to validate the customer’s purchase receipt.

The process workflow between your JavaScript calls and the Amazon Services JavaScript library looks something like this:

 

You can deliver static content stored locally or dynamic content that is updated over time for customers.  For more details about the Purchase Process workflow and the types of deliverable content you refer to the Understanding In-App Purchasing for JavaScript API documentation here.

IMPLEMENTING AND TESTING PURCHASE CALLS

Now that you understand the process flow, have referenced the proper JavaScript libraries and have created a list of SKUs (or local JSON file) it’s time to call out to the Amazon Services in your own JavaScript.

Every call you initiate via the Amazon Services JavaScript Libraries results in a response received by the corresponding response handler specified in registerObserver(). Each of these responses makes use of a response object and includes the following:

  • GetUserIdResponse - Provides the app-specific UserID for the user currently logged into the Amazon Client
  • PurchaseUpdatesResponse - Provides a paginated list of receipts and revoked SKUs since the offset passed into the initiating request. Receipts are returned in a set and are unordered.
  • ItemDataResponse - Provides item data, keyed by SKU.
  • PurchaseResponse - Provides status on purchases initiated within your app. Any error for a purchase is automatically managed for you by In-App Purchasing API.

There are also purchase handlers, similar to the In-App Purchasing API for Android that have already been implemented for you inside the Amazon Services JavaScript files.  They include the following:

  • onSdkAvailable(onAvailableResponse) - This gets called when the In-App Purchasing services are ready to be called by your code. Production applications should not grant entitlements when they are run in sandbox mode.
  • onGetUserIdResponse(userIdResponse) - Called in response to GetUserId.
  • onItemDataResponse(itemDataResponse) - Called in response to GetItemData. data.itemData is a hash table of itemData objects keyed by SKU.
  • onPurchaseResponse(purchaseResponse) - Called to report the status of a purchase operation. purchaseResponse.purchaseRequestStatus contains the status of the response. If a prior session of the application shut down before a purchase response could be delivered, this function will be called when a new session of the application registers a purchase hander.
  • onPurchaseUpdateResponse(data) - Called with the list of entitlements that the user has been granted. data.receipts contains a hash table, keyed on SKU, that contains the receipts for the IAPs that have been granted to the user. data.revokedSkus has a list of SKUs that the user can no longer use.

Implementation of the Amazon Services JavaScript library is as follows:

  • Enable the API Tester
  • Register a Purchase Observer
  • Check to see if we are running in developer Sandbox Mode
  • Update any existing Purchases
  • Handle Purchase Responses
  • Store Receipts

For example, the Button-Clicker example starts off by calling an initialize() function which will set up an IAP observer usingamzn_w.IAP.registerObserver() and then checks the response object to see if the web app is in debug mode.  If it is an alert box is generated telling the user the app is in development mode.  If not it will check for updated Purchases.

Finally, the function sets up handlers for Purchase Response and Purchase Updates Response objects.

 

// Setup

 

function initialize() {

loadPageState();

amzn_wa.enableApiTester(amzn_wa_tester);

refreshPageState();

 

// Setup button press handlers

$(“#theButton”).click(function() { buttonPressed(); });

$(“#redButton”).click(function() { redButtonPressed(); });

$(“#greenButton”).click(function() { greenButtonPressed(); });

$(“#blueButton”).click(function() { blueButtonPressed(); });

 

// Ensure we can call the IAP API

if (amzn_wa.IAP == null) {

console.log(“Amazon In-App-Purchasing only works with Apps from the Appstore”);

} else {

// Registers the appropriate callback functions

amzn_wa.IAP.registerObserver({

// Called the the IAP API is available

‘onSdkAvailable’: function(resp) {

if (resp.isSandboxMode) {

// In a production application this should trigger either

// shutting down IAP functionality or redirecting to some

// page explaining that you should purchase this application

// from the Amazon Appstore.

//

// Not checking can leave your application in a state that

// is vulnerable to attacks. See the supplied documention

// for additional information.

alert(“Running in test mode”);

}

 

// You should call getPurchaseUpdates to get any purchases

// that could have been made in a previous run.

amzn_wa.IAP.getPurchaseUpdates(state.lastPurchaseCheckTime != null ?

state.lastPurchaseCheckTime : amzn_wa.IAP.Offset.BEGINNING);

},

 

// Called as response to getUserId

‘onGetUserIdResponse’: function(resp) {},

 

// Called as response to getItemData

‘onItemDataResponse’: function(data) {},

 

// Called as response to puchaseItem

‘onPurchaseResponse’: function(data) { onPurchaseResponse(data); },

 

// Called as response to getPurchaseUpdates

‘onPurchaseUpdatesResponse’: function(resp) { onPurchaseUpdatesResponse(resp);

}

});

}

}

 

$(function() {

initialize();

});

 

Once initialization is done you can make purchase calls by passing in your SKU title.  The example code here is making a call to purchase the more “sample.clicks” SKU.

 

function buyClicks() {

if (amzn_wa.IAP == null) {

alert(“You are out of clicks, however Amazon In-App-Purchasing works only with Apps from the Appstore.”);

} else if (confirm(“Buy more clicks?”)) {

amzn_wa.IAP.purchaseItem(“sample.clicks”);

}

 

The purchaseItem function will return a response object you need to handle and check for success or failure.

 

// purchaseItem will cause a purchase response with one receipt

function onPurchaseResponse(e) {

if (e.purchaseRequestStatus == amzn_wa.IAP.PurchaseStatus.SUCCESSFUL) {

handleReceipt(e.receipt);

} else if (e.purchaseRequestStatus == amzn_wa.IAP.PurchaseStatus.ALREADY_ENTITLED) {

// Somehow we are out of sync with the server, let’s refresh from the

// beginning of time.

amzn_wa.IAP.getPurchaseUpdates(amzn_wa.IAP.Offset.BEGINNING)

}

refreshPageState();

}

 

If it gets back a status of PurchaseStatus.SUCCESSFUL it will handle the receipt returned in the response object like so:

 

// In either case, the contents of the receipt are handled in the same way

function handleReceipt(receipt) {

if (receipt.sku == “sample.redbutton”) {

// Entitlement

state.hasRedButton = true;

} else if (receipt.sku == “sample.greenbutton”) {

// Entitlement

state.hasGreenButton = true;

} else if (receipt.sku.substring(0, 30) == “sample.bluebutton.subscription”) {

// Subscriptions sometimes return the parent’s ID so we compare to the

// parent’s ID

if (receipt.subscriptionPeriod != null) {

if (receipt.subscriptionPeriod.endDate == null) {

// endDate is null if we are in the current period

state.hasBlueButton = true;

}

}

} else if (receipt.sku == “sample.clicks”) {

// Consumable

state.clicksLeft += 10;

}

}

In this Button-Clicker example we are setting a Boolean value to true based on a successful purchase.  In a real web app you would want to save the purchase receipt to local storage or back to your own cloud storage so you can verify purchase receipts in the future.

USING THE SDK TESTER APP

If you are running in the development Sandbox Mode we mentioned above calls to the Amazon Services will go through the local SDK Tester App instead of to the Amazon Cloud.

This allows you to simulate purchasing SKUs in your web app without having to spend any actual currency.  You have the option to test a purchase inside the browser itself using the included Amazon Service JavaScript Libraries.

In this scenario you need to ensure your JSON file holding the SKUs is located in the same folder as you web app.  If you want to test the In-App Purchase on a device you can do so using the SDK Tester tool and a JSON file that has been copied to the SD Storage.

For a complete video walkthrough of the purchase process and SDK Tester tool you can watch the following screencast on our Youtube Channel.

CONCLUSION

By utilizing the Amazon In-App Purchasing API for JavaScript you are able to quickly implement and test purchases through your existing web app.  Customers can take advantage of in app items, subscriptions and entitlements you might offer all through the secure Amazon checkout process.

Be sure to check out our HTML5 Web App materials on the developer portal to get started today!

-Dave (TheDaveDev)