After spending countless hours developing a high-quality app experience, it's time to build monetisation features into your product. An effective way to do this is by implementing an in-app purchasing (IAP) system and deploy your app across multiple platforms and app stores.
By utlizing powerful cross-platform app development frameworks such as Flutter, you are able to build your app once and deploy it across both iOS and Android. Integrating In-app purchasing across app stores can be challenging when having to manage multiple SDKs.
Over the past few months, I've been interested in building a Flutter app that integrates in-app purchasing across Google Play, Apple Appstore and Amazon Appstore. I was interested in proving this out with Flutter specifically to test out their "platform channels" feature for building with platform-specific code. This enables me to integrate each In-app purchasing SDK in one code base. While this is possible, I'm aware that this can easily become a lengthy process.
Thankfully the open source community has built a related project: Introducing the flutter_inapp_purchase library. This project is an interesting open-sourced plugin for easily integrating in-app purchasing for each of the app stores mentioned above.
For this guide, walk-through how to integrate a sample music artist's app that integrates with the Amazon Appstore SDK for in-app purchasing and subscriptions. Let's dive in.
Case Study: GIOLAQ's Music App 💿👨🎤
Let's pretend that "GIOLAQ" is a fictional singer with an international fan base. In order to grow revenue, his record label launched an artist app for his music and merchandise to be available to purchase around the world.
Fan's of GIOLAQ can listen to the music albums if they pay to unlock the exclusive content. The in-app purchasing options for the app are:
- Entitlements - Unlocking one of GIOLAQ's albums for your account to listen
- Subscriptions - An annual pass to listen to all the music produced by GIOLAQ
- Consumables - Concert tickets to GIOLAQ's live music concerts
Setup for In-app purchasing
Before going through the code, let's first take care of the in-app purchase setup on the back-end.
💡 Note: If your need to integrate in-app purchasing with Flutter and Google Play or Apple, check out some excellent community tutorials on how to do it. You'll notice the integration steps are almost the same, which includes activating IAP services in each of the app store console and creating the IAP items in your developer settings.
For integrating In-app purchasing for the Amazon Appstore, make sure to also reference the official guide in the Appstore docs.
For building GIOLAQ Music I've created 3 IAP items:
- An Entitlement IAP item to buy the whole album of GIOLAQ
- A yearly subscription to grant all the music for one year.
- A consumable item for the live music tickets.
In order to test the GIOLAQ app, make sure to create the same IAP items that map to their unique identifiers which are referred to to as SKUs
In addition to creating products with mapping SKUS remember to download the JSON file with the items. To this this, you'll navigate to the In-App Items tab of your app and click the Export Multiple IAPs button with JSON as the selected format.
Once you take these steps, the downloaded JSON file will used during testing. My sample JSON file for testing is here if you would like to follow along.
The code base
For the GIOLAQ Music project, I've inserted all the business logic for in-app purchasing in a file named iap_handler.dart
. The 3 additional files I've built are:
-
main.dart
which handles the the main widget of the app and navigation between the two screens -
music.dart
handles the music UI screen for displaying the album cover and the locked/unlocked state of the purchasable items -
purchase_page.dart
is where you can spend your virtual money to buy the purchasable items
Here are UI examples of these files in action:
Integrating the Flutter IAP plugin
Step 1: Add the Flutter IAP package as a dependency
To start using the Flutter IAP Plugin from dooboolab remember to add the dependency on the pubspec.yaml
so that you can then import all the packages objects and classes into your application.
dependencies:
flutter:
sdk: flutter
flutter_inapp_purchase: ^5.3.1
Step 2: Initialize the plugin
Initialize the plugin with
FlutterInappPurchase.instance.initialize();
💡 Note: This has to be done before purchasing, on iOS it also checks if the client can make payments.
In my app, I've initialized the plugin and wrapped the instance in a class as a singleton. This is useful if you want to adopt different SDKs in the future or for easy testing.
Step 3: Subscribe to the IAP connections
In the IAP_HANDLE
widget, you'll write some code to subscribe to StreamSubscription
in order to listen for IAP Connection status, Purchases status, and Errors.
Here's an example of how to listen for these events:
_connectionSubscription =
FlutterInappPurchase.connectionUpdated.listen((connected) {
// Do something with the connection status
});
_purchaseUpdatedSubscription =
FlutterInappPurchase.purchaseUpdated.listen((productItem) {
// Update the UI with updated status of the purchase
});
_purchaseErrorSubscription =
FlutterInappPurchase.purchaseError.listen((purchaseError) {
// Handle IAP Error
});
Step 4: Load the purchasable objects
Next, you will load the Purchasable objects according to their SKUs. In this line of code, I am populating a list of purchasable items in order to display them in the purchase screen:
iapItems = await FlutterInappPurchase.instance.getProducts(skuList);
Step 5: Make a test purchase!
To purchase an item, go ahead and call the following method with the SKU of the item you want to purchase:
FlutterInappPurchase.instance.requestPurchase(sku);
The purchase confirmation will arrive on the _purchaseUpdatedSubscription
where you can handle the updates of your UI based once the purchase is successful.
In GIOLAQ Music app the requestPurchase()
call is wrapped into a buy
function. This function is called by the onPressed
of the widgets within the Purchase screen to associate the objects to buy.
Step 6: Handle the purchase update
Remember to handle purchase result using the callbacks you registered in Step 3 Subscribe to the IAP connections. For this example, I've used the following snippet to propagate the purchase state in the Music screen to unlock the music or increment the quantity of purchased ticket.
FlutterInappPurchase.purchaseUpdated.listen((productItem) {
_purchasesUpdate(productItem!);
_updateStreamOnDone();
});
Step 7: Clean up when you leave!
Remember to cancel the StreamSubscription
when you are no longer using. The following code within the dispose
method of the IAP_Handler
widget is an example of how to get this done:
_connectionSubscription.cancel();
_purchaseUpdatedSubscription.cancel();
_purchaseErrorSubscription.cancel();
Testing phase
To test the app , make sure to pick up an Amazon Fire tablet for yourself and active the developer options in order to support sideloading test apps from Android Studio. Using Android debug bridge (adb), upload the IAP JSON file to the device using the following command:
adb push <_Your_JSON_File_Folder_>/amazon.sdktester.json /sdcard/amazon.sdktester.json
In addition, enable sandbox mode with the command:
adb shell setprop debug.amazon.sandboxmode debug
After this make sure you have installed the Amazon App Tester on the Tablet. Once thats done, you can build and run the app from your IDE.
Wrap Up
I'm always delighted when I discover new ways the open-source community is fixing issues and covering needs. Special thanks to the open source maintainers at dooboolab for building and maintaining this flutter community plugin
If you want to check out the source code of my sample GIOLAQ Music app and review how I built in in-app purchasing for Amazon Appstore, head over head to GitHub to try the
flutter_amazon_iap_demo project for yourself.
To know more about Amazon In-App Purchasing SDK head over to the official docs
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
About the author
Giovanni ("Gio") Laquidara is a Senior Dev Advocate at Amazon, where he works on supporting developers around the world using the Amazon Appstore across many devices.
Previously, Gio worked as a software engineer building mobile apps, real-time defence systems, and VR/AR experiences. For fun, Gio enjoys low level programming, IoT hacking, and command line apps ⌨️✨.
You can connect with Gio on Twitter, Linkedin, and giolaq.dev.