If you have an existing Android App that uses the Google Play Billing Library for in-app purchases (IAP) and subscriptions, you can use the Appstore Billing Compatibility (ABC) SDK to port it to the Amazon Appstore. Porting your app to the Amazon Appstore offers you a great opportunity to connect with engaged customers around the world — to date, there have been more than 200 million Fire TV devices sold globally.
Similar to the Google Play Billing Library versions 4.0 and 5.0, the Amazon Appstore Billing Compatibility SDK supports consumable, entitlement, and subscription IAPs. In this article, we'll walk through the step-by-step instructions to integrate the Appstore Billing Compatibility SDK into your app. I will use our Hello Pizza ordering app for the purposes of this article (because ordering and eating pizza is one of my favorite things to do when I'm not building apps).
Let’s dive in and get started. I’ve already built a Hello Pizza app that uses the Google Play Billing Library. Before porting the app to the Amazon Appstore, let’s go through a checklist of the items we need.
Checklist — what you’ll need to get started to port your Android app to the Amazon Appstore
Getting started is simple. Below are the three things you’ll need to port your app to the Amazon Appstore:
- An Android app that uses versions 4.0 or 5.0 of the Google Play Billing Library.
- An Amazon Developer Console Account (If you don’t have one, you can get it here.)
The Amazon Appstore Billing Compatibility SDK (you can download the latest version here — extract the zip file and copy the jar file).
Step 1: Integrate the Amazon Appstore SDK 📥
A. You’ve downloaded the Appstore Billing Compatibility SDK includes the JAR file and API documentation. Now, add the appstore-billing-compatibility-4.1.0.jar file to your app's libs folder.
B. Next, update your app's build.gradle file to include the SDK dependency:
Here’s the familiar looking code you would have for your Android app.
implementation(libs.google.billing)
But change this to
dependencies {
implementation files('libs/appstore-billing-compatibility-4.1.0.jar')
}
C. Now, sync your project to resolve the dependency.
Step 2: Configure Your App 🔧
It’s time to configure your app!
A. To get started, log in to the Amazon Developer Console and navigate to your app's page.
B. Generate a public key for your app and download the AppstoreAuthenticationKey.pem file. You can find more information here.
C. Next, copy the PEM file to your app's src/main/assets folder.
D. Update your AndroidManifest.xml
file to include the BillingResponseReceiver
. Remember, if your app targets Android 12 or higher, you must explicitly set android:exported
to true in the MainActivity
and ResponseReceiver
.
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.HelloPizza">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name="com.amazon.device.iap.billingclient.api.BillingResponseReceiver"
android:exported="true"
android:permission="com.amazon.inapp.purchasing.Permission.NOTIFY">
<intent-filter>
<action android:name="com.amazon.inapp.purchasing.NOTIFY" />
</intent-filter>
</receiver>
E. Update your app's import statements to use the Appstore Billing Compatibility SDK classes. Replace com.android.billingclient.api
with the com.amazon.device.iap.billingclient.api
).
F. Add your app IAP items to the Amazon Appstore Developer Console following the instructions here. This will allow you to do important things like charge for your pizza, and also the noble things like offer your pizza at a discount.
Step 3: Initialize the BillingClient 🚀
Now that you’ve configured your app, it’s time to initialize a BillingClient instance in your app. This is similar to how you would initialize a billing instance with Google Play Billing. The syntax to initalize the billing clients is the same with the two SDKs.
In Google Play Billing:
private val billingClient = BillingClient.newBuilder(application)
.setListener(this)
.enablePendingPurchases()
.build()
For the ABC SDK:
private val billingClient = BillingClient.newBuilder(application)
.setListener(this)
.enablePendingPurchases()
.build()
Step 4: Connect to the Amazon Appstore 🔗
Unlike Google Play Billing, the Amazon Appstore doesn't require you to maintain a connection. All you have to do is call startConnection()
on your BillingClient instance:
In Google Play Billing:
class GoogleIAPDataSource : BillingClientStateListener {
...
init {
billingClient.startConnection(this)
}
...
override fun onBillingSetupFinished(billingResult: BillingResult) {
when (billingResult.responseCode) {
BillingClient.BillingResponseCode.OK -> {
reconnectMilliseconds = RECONNECT_TIMER_START_MS
defaultScope.launch {
querySkuDetailsAsync()
refreshPurchasesAsync()
}
}
else -> {
onBillingServiceDisconnected()
}
}
}
override fun onBillingServiceDisconnected() {
reconnectMilliseconds = (reconnectMilliseconds * 2).coerceAtMost(RECONNECT_TIMER_MAX_MS)
billingClient.startConnection(this)
}
}
In ABC SDK:
override fun onBillingSetupFinished(billingResult: BillingResult) {
when (billingResult.responseCode) {
BillingClient.BillingResponseCode.OK -> {
reconnectMilliseconds = RECONNECT_TIMER_START_MS
defaultScope.launch {
querySkuDetailsAsync()
refreshPurchasesAsync()
}
}
else -> {
onBillingServiceDisconnected()
}
}
}
override fun onBillingServiceDisconnected() {
reconnectMilliseconds = (reconnectMilliseconds * 2).coerceAtMost(RECONNECT_TIMER_MAX_MS)
billingClient.startConnection(this)
}
Step 5: Query Product Details 🔍
To retrieve the details for your product, you can use either the queryProductDetailsAsync()
or querySkuDetailsAsync()
method. The syntax is the same between ABC and Google Play Billing.
val inAppSkuDetailsParams = SkuDetailsParams.newBuilder()
.setType(BillingClient.SkuType.INAPP)
.setSkusList(knownInAppSKUs)
.build()
billingClient.querySkuDetailsAsync(inAppSkuDetailsParams) { result, details ->
onSkuDetailsResponse(result, details)
}
Step 6: Launch the Purchase Flow 🚀
To start a purchase, simply call the launchBillingFlow()
method with a BillingFlowParams object containing the product details. The syntax is the same between ABC and Google Play Billing.
val billingFlowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build()
val billingResult = billingClient.launchBillingFlow(activity!!, billingFlowParams)
Note: The Appstore Billing Compatibility SDK allows only one product per purchase.
Step 7: Process Purchases 💰
After a successful purchase, process it in your PurchasesUpdatedListener's onPurchasesUpdated()
method.
override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List<Purchase>?) {
when (billingResult.responseCode) {
BillingClient.BillingResponseCode.OK -> purchases?.let { processPurchaseList(it, null) }
else -> {}
}
defaultScope.launch {
_billingFlowInProcess.emit(false)
}
For consumables, call consumeAsync()
to acknowledge delivery and mark the item as consumed.
billingClient.consumeAsync(consumeParams) { billingResult, _ ->
purchaseConsumptionInProcess.remove(purchase)
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
defaultScope.launch {
_purchaseConsumedFlow.emit(purchase.skus)
}
purchase.skus.forEach { sku ->
setSkuState(sku, SkuState.UNPURCHASED)
}
}
}
For entitlements, use acknowledgePurchase() to acknowledge delivery.
Step 8: Fetch Purchases 🛒
To retrieve a user's purchases, call queryPurchasesAsync()
.
billingClient.queryPurchasesAsync(BillingClient.SkuType.INAPP) { billingResult, purchases ->
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
processPurchaseList(purchases, knownInAppSKUs)
}
}
billingClient.queryPurchasesAsync(BillingClient.SkuType.SUBS) { billingResult, purchases ->
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
processPurchaseList(purchases, listOf(knownSubscriptionSKUs))
}
}
Step 9: Test Your App 🧪
To test your app's integration with the Appstore Billing Compatibility SDK, you can use the Live App Testing to test your app in a live production environment with a select group of users. To set up Live App Testing for your app follow the steps here.
Discount | Subscription | Entitlement |
---|---|---|
Important notes
- It’s easy to forget to place the file
AppstoreAuthenticationKey.pem
in the correct directory You should double check you performed all the steps in the Configure Your App 🔧 section above. - Check that the SKUs used in your app are the same that you defined in the Amazon Appstore Console (See the official guide)
Conclusion 🎉
If you’ve followed the steps above carefully, your app should be compatible with In-app purchasing on the Amazon Appstore. Here’s more resources to help ensure that you are getting the most bang for your buck from your development efforts on the Amazon Appstore. I hope you enjoyed this article. As for me, writing this demo has made me hungry. I’m now going to power off for the evening and get some pizza.
Stay updated
For the latest Amazon Appstore developer news, product releases, tutorials, and more:
📣 Follow @AmazonAppDev and our team on Twitter
📺 Subscribe to our YouTube channel
📧 Sign up for the Developer Newsletter