Configuring Cordova In App Purchases on iOS and Android
30 Apr 2016The first step of integrating in app purchases plugin into a cordova app is to decide what kind of products you want to offer and setup these products on iTunes Connect and Google Play.
This post goes over the differences between setting up consumable and non-consumable in app purchases on iOS and Android and restoring non-consumable purchases from different devices.
Non-Consumables
Non-Consumables are products that the user can purchase only once. For example, if you have a game with
multiple levels, you can configure every level to be a paid purchase and define a product for each level (such
as com.yourcompany.level1
, com.yourcompany.level2
, etc). When users purchase one of
these products, they should own it forever (or for as long as there are humans and iPhones) which means that
you have to provide a way to restore this product if the app is opened from another device using the same
iTunes/google account.
To purchase a consumable on iOS using the cordova-plugin-inapppurchase plugin,
use inAppPurchase.buy()
:
const productId = 'com.yourcompany.level1';
inAppPurchase
.buy(productId)
.then((res) => {
console.log('purchase completed!');
// unlock level 1
})
.catch(err => console.log(err) );
When you offer non-consumable products, you must provide functionality to restore these purchases so the user will not have to pay for them again if they re-download the app or use if from a different device.
To restore non-consumable purchases, use inAppPurchase.restorePurchases()
:
inAppPurchase
.restorePurchases()
.then((purchases) => {
purchases.forEach(purchase => console.log(purchase.productId + ' should be restored') );
// unlock the relevant feature based on this product id
})
.catch(err => console.log(err) );
Iterate over the purchases
array and unlock all the features for the products that were
previously purchased.
Consumables
Consumables are products that the user can purchase multiple times such as credits or coins. For example, in a slot machine app, you may charge the user 1 credit for each game and let them purchase a package of 20 credits by offering the product com.yourcompany.20_credits.
When you are adding a new consumable product on iOS, one of the options will be to add a consumable in app purchase:
On Android, there is no distinction between consumable and non-consumable products. They both fall under the "Managed Product" Category.
To indicate that this product is consumed, you need to call the inAppPurchase.consume(productId)
function. It's important to remember to consume the product, otherwise you will get an error the next time
you will try to purchase it.
To purchase a consumable product:
const productId = 'com.yourcompany.20_credits';
let validationData = {};
inAppPurchase
.buy(productId)
.then((res) => {
validationData = res;
// give the user credits for their purchase
return inAppPurchase.consume(productId); // <- consumable products must be consumed
})
.then(() => {
validateOnYourBackend({
receipt: validationData.receipt,
signature: validationData.signature,
});
})
.catch(err => console.log(err) )
It's important to validate consumable in app purchases on your backend to make sure that the purchase was authentic.
Consumable purchases cannot be restored like non-consumable purchases. You should avoid putting a "Restore Purchases" button if your app only offers consumable products. Instead ask the user to authenticate and sync their purchased consumable products.
When a user purchases credits, you will need to keep track how many credits the user owns and the usage of credits. You can do that by uniquely identifying the user (by his credentials or any other unique identifier) and sending the information about purchases and games played to your server to sync this data between devices. You can also store this data locally using any of the available storage solutions (local storage, sqlite, etc). If your app doesn't use a backend, there is a solution to persist the data on the device even if the app is uninstalled.