Most mobile games today use some form of in-app purchasing (IAP) as part of their monetization strategy. Using Amazon IAP in GameMaker: Studio is not particularly difficult – once you know how to do it. But getting to that stage takes some careful study and experimentation. Hopefully, I can help short cut that process for you as I describe how I built it for Retroids.
By now, I’m sure most of us are very familiar with IAP. There are three types of IAP items found in games—consumables, entitlements and subscriptions—with consumables and entitlements being far more common, so that is what we’ll cover here.
Consumable IAP items are things that are used, or consumed, during gameplay. Gold, gems, health, potions, etc. You might by a “Bag of 500 coins” and then use those coins to outfit your character, buy gas for a race car, etc.
Entitlement IAP items are things that are “unlocked” and continue to be available to the player forever after that point. Level packs or special items like a gun, sword or personalization items like a costume or theme pack are common entitlements.
One of the great things about IAP is that your game doesn’t have to deal with collecting the user payment information, authorizing and processing the payment, and all the other aspects of securely managing credit card information on your own. As you can imagine, users may be reluctant to enter their payment information separately in every game they are playing. You can rely on the Amazon Appstore to handle all those backend details and to provide a single place that customers already trust with their payment information.
On Amazon Appstore, as with other app stores, there are parts of the IAP that you configure on the server and parts that you code in the game. Each IAP item is referred to as a SKU (stock keeping unit, which is a legacy retail term for “an individual type of thing you are selling”). This includes the name of the SKU, the price and a few other pieces of metadata. The price that is configured in the Appstore is what the customer will be charged. Your game can’t change that at run time, but you can change it whenever you want—without requiring an app update—on the server.
So completing any purchase involves both your code and Amazon code on both the local device and the server. The general flow of an IAP transaction looks like this:
Check our Understanding In-App Purchasing documentation for more information.
To use Amazon IAP in your game, you need to add the Amazon GameCircle extension to the project. YoYo Games created this extension and provides it for free in the GameMaker Marketplace. You’ll use this same extension to add Amazon GameCircle support as well, which we’ll cover in a future post in this series. GameMaker also includes a demo project that includes IAP features. It’s called “Amazon_Game_Circle” and you can find it in the new project dialog on the Demos tab under “SDKs”. Unlike other demos and tutorials, you won’t be able to directly run this example because IAP and GameCircle require configuration on the Amazon Developer Portal.
The demo can be somewhat difficult to follow, so I’ve broken down the steps.
To add your IAP items, log in to your Amazon Developer Portal account at and click the button to add a new app. You’ll need to enter some basic information about your app, but you don’t need to be ready to upload or submit the app at this point. (You can find more information on getting started with setting up your apps and in-app items in the Amazon developer documentation.)
Once your app exists, click on the “In-App Items” link and use the buttons to add entitlement or consumable items.
The SKU names you select for your items can’t be changed so you should select them carefully. You don’t need to use the same scheme, but I like to use the package name of the app with a suffix to identify the IAP item. So if my app package name is “com.pocketsoftware.retroids”, I would use “com.pocketsoftware.retroids.premium” as my IAP SKU name.
In GameMaker: Studio, go to the Marketplace and search for “Amazon GameCircle”. Download this extension and add it to your project.
Early in your game startup code, you need to include this function call:
AmazonGameCircle_InitFeatures(AmazonGameCircle_IAP);
In my case, I have a room called “rmBootstrap” that contains no objects and is the first room in my project. In this room, I use the Creation Code to set up some global variables and a few other lines of code—including the line above. The last line in the Creation Code loads the next room, which will probably be a title screen, tutorial or gameplay screen.
In the same place you have the line from Step 3, include these lines to set up your IAP items:
var res = AmazonGameCircle_AddIAP_SKU("");
You will need one of these lines for each IAP item you have added to the Developer Portal in Step 1. Each line will have a different variable, but you won’t be referencing these afterwards. It doesn’t matter whether the IAP item is a consumable or entitlement, the line is the same.
Typically, a game will have a store where the player will see the list of items and prices, hopefully displayed in an appropriate look and feel for your game. You can present the items as a list or as a view of a room with different objects that you can tap on, or whatever makes sense. You can implement this as a room with a controller object and separate item objects or as a single IAP object (which works fine in simple cases) or whatever other method you choose. My game only has one IAP item so I have an IAP room and a single IAP object in that room. The IAP object acts as the controller and item.
In the initialization of this room, add these two lines of code:
AmazonGameCircle_GetProductData(); AmazonGameCircle_GetPurchasesData();
The first line gets the product data that you configured on the Developer Portal. The second line gets the information for any user purchases they have previously made.
The functions will trigger information to be sent to the asynchronous Social event that we will add in the next step.
In your store experience, when the user makes a purchase, add this line of code for a consumable item:
AmazonGameCircle_BuyIAP_SKU("com.pocketsoftware.retroids.gold");
Or this one for an entitlement item:
global.BuyExpansionHash = AmazonGameCircle_BuyIAP_SKU("com.pocketsoftware.retroids.premiumunlock");
Notice in this case we need to get the return value from the function call for later user.
The important thing here is that we are NOT crediting the user with the item at this point. For example, if the player purchased a bag of gold pieces, we are not adding some number of gold pieces to the number the player has. This is because the purchase has not been completed and confirmed. We’ve merely started the process.
In your IAP controller object, add the Asynchronous Social event. Then add an Execute Code action from the Control tab. Add the code below to this action. This code handles the responses that will come to your application.
var ident = ds_map_find_value(async_load, "id" ); if(ident == achievement_our_info) { AmazonGameCircle_GetProductData(); AmazonGameCircle_GetPurchasesData(); } else if(ident==2001) { var receipt = ds_map_find_value(async_load,"receipt_full"); var cancelled = ds_map_find_value(async_load,"receipt_cancelled"); if(!cancelled) { var receipt_sku =ds_map_find_value(async_load,"receipt_sku"); var receipt_id = ds_map_find_value(async_load,"receipt_id"); if(receipt_sku=="com.pocketsoftware.retroids.consumable_item") { // this is the place you give the player the items – gold, gems, whatever global.gold += 25; // the next line is how your app tells Amazon “I got the item and gave it to the customer” AmazonGameCircle_NotifyFulfillment(receipt_id); } else if(receipt_sku=="com.pocketsoftware.retroids.entitlement_unlock") { // we’ve received the receipt for this SKU so we’re ready to entitle it for the player global.unlocked = true; // now that it has been unlocked, we should keep track of this by storing it on the device // and perhaps in the cloud using GameCircle Whispersync or some other means } } else show_debug_message("cancelled"); } else if(ident==2002) { var status = ds_map_find_value(async_load,"purchase_status"); var user = ds_map_find_value(async_load,"request_user"); var hashcode = ds_map_find_value(async_load,"request_hash"); if(status=="ALREADY_PURCHASED") { // the server is telling us the user already paid for this entitlement item // this happens if we lose track of the purchase locally for whatever reason // but the user wasn’t charged for it again and we just catch this and give the // player access to the entitlement again if(hashcode == global.BuyExpansionHash) { if(user == global.playerid) { global.unlocked = true; } else show_debug_message("user mismatch"); } else { show_debug_message("hash mismatch"); } } }
Not that this code is in the Social event when using the Amazon extension rather than the IAP event. This is perhaps one of the key differences that is key to getting this to work.
There are two tools Amazon provides that will help you test your IAP implementation. One is the AppTester. This is an app you download from Amazon on the device you want to test on. This will be a totally disconnected test and you don't publish your app to Amazon first. To use the AppTester, you will need to download the IAP items JSON file from the Amazon Developer Portal - the same page where you see your IAP items listed. You copy this file to the device as described on the Developer Portal.
Now build your APK in GameMaker: Studio and install it on the device.
When you run your app, you will see essentially the same behavior you will see when you publish it. Not exactly, but good for immediate testing to make sure you have things working. Your next step when is to use Live App Testing (LAT) on Amazon. This publishes the app just like it would be for your final published app but in a controlled test. Nothing in the app will cost the testers actual money and only people you invite will be able to install the app.
I recommend you use AppTester in the early stages of your development but you should DEFINITELY use LAT before you submit your app to publish. It will really show you how it is going to all look and work for your customers when they play your game.
There you have it, your Amazon Appstore entitlement and consumable IAP should now be working in your GameMaker: Studio app.
Tune in next week for the final part of the series: Setting Up GameCircle
Part 2: Basic Controller Detection
Part 4: Fire TV Remote and Controller Selection