Add In App Purchases To Your Ionic Cordova App - Step By Step Guide With An Example App

If you look at the list of top grossing iOS and Android apps, you'll notice that most of the apps on the list are free to download and offer in app purchases. This is the most profitable monetization model for mobile apps because users prefer to try the app for free first and only then decide if they want to spend money on it. In addition to that, with such an abundance of free apps, users tend to avoid apps they have to pay for upfront.

cordova-plugin-inapppurchase provides a simple promise-based API to add in app purchases to a cordova app on both iOS and Android. To get started with in app purchases and see an example ionic app that implements all the different product types, clone the cordova-inapppurchases-app:

$ git clone https://github.com/AlexDisler/cordova-inapppurchases-app.git

Then, make sure you have all the required plugins istalled, including cordova-plugin-inapppurchase:

$ cordova plugin add cordova-plugin-inapppurchase

To learn about how in app purchases work on each of the platforms, read Apple's In-App Purchase Programming Guide and Google's In-app Billing Overview.

The first step is to configure your app and the products you would like to offer on iTunes Connect and Google Play Developer Console.

Once you have your app bundle id (such as com.yourcompany.appname) and the product's ids (such as com.yourcompany.appname.product1 etc), set your app bundle id in the config.xml file and add the products to the productIds array in the www/js/app.js file.

If you are building an app for iOS you are ready to go. On Android, you need to find your Android Billing Key under the "Services & APIs" section in the Google Play Developer console, and add it to the www/manifest.json file.

Note that on Android, you must sign and publish your app as alpha or beta version and then make sure your Google account is set as a tester for this app. On Apple, you will need to configure and set up a test user account and login with this account to iTunes on your decvice.

The main page

The demo app is based on ionic's blank starter project. It has only one page with two buttons: "Load Products" and "Restore Purchases". Once the "Load Products" button is tapped, the app will load the product's titles and prices, and list them. The markup for the main page is:

<button ng-show="!products" ng-click="loadProducts()" class="button button-block button-balanced">
  <i class="ion-arrow-down-c"></i> Load Products
</button>
<button ng-repeat="product in products" ng-click="buy(product.productId)" class="button button-block button-positive">
  { { product.title }} - { { product.price }}
</button>
<h3>Restore Purchases</h3>
<button ng-click="restore()" class="button button-block button-balanced">
  <i class="ion-refresh"></i> Restore
</button>

Loading Products

The first step is to load the products within the app from Apple or Google using the inAppPurchase.getProducts() function. This function takes an array of product ids that you defined earlier, as a parameter, and returns the full information for each product, such as localized title, description, price and the product id. It must be called before any purchase attempts are made.

In the $scope.loadProducts() handler, the following code loads the products and assigns them to the $scope.products variable:

inAppPurchase
  .getProducts(productIds)
  .then(function (products) {
    $scope.products = products;
  })
  .catch(function (err) {
    console.log(err);
  });

In App Purchase Product Types

There are 3 types of products that you can offer:

  • Non Consumable - Non consumable products let the user purchase digital goods (such as books or photos), unlock additional premium features or purchase new levels in a game. Non consumables can only be purchased once and the app has to provide a way for users to restore their purchases on a new download or a new device.

  • Consumable - Consumable products let the user purchase a virtual currency such as "coins" or "credits" within the app. Consumable products can be purchased repeatedly.

  • Subscription - Subscriptions give users access to premium services for a limited amount of time. Subscriptions can be free or paid and can be set up for different periods of time.

Apple's In App Purchase Guidelines provide a good description of in app purchase product types and what is allowed and forbidden.

On Android, consumable and non consumable products are grouped under the "Managed Product" category and you need to call the inAppPurchase.consume() function to consume them (we'll see an example below). On iOS, you need to specify which products are consumable and which aren't when you add them on iTunes Connect so there is no need to "consume" them in the code.

Purchasing a Product

In our example, when the user taps on one of the products that were loaded, the buy(product.productId) function will be called which in turn will call the inAppPurchase.buy() function:

inAppPurchase
  .buy(productId)
  .then(function (data) {
    console.log(JSON.stringify(data));
    // The consume() function should only be called after purchasing consumable products
    // otherwise, you should skip this step
    return inAppPurchase.consume(data.type, data.receipt, data.signature);
  })
  .then(function () {
    console.log('consume done!');
  })
  .catch(function (err) {
    console.log(err);
  });

The data object will contain the receipt and signature that you will need to validate your purchases.

Restoring purchases

The $scope.restore callback, will make a call to the inAppPurchase.restorePurchases() function, to load the non-consumable products that the user already purchased before:

inAppPurchase
  .restorePurchases()
  .then(function (purchases) {
    console.log(JSON.stringify(purchases));
  })
  .catch(function (err) {
    console.log(err);
  });

You will need to check which one of the non-consumable products the user already purchased, and give them access to the relevant content. Your app must provide this functionality if you are offering non-consumable products and will likely to be rejected if the reviewer will notice that it is missing. However, if you only plan to offer consumable products, you don't need to restore purchases.

To see the full version of the example app take a look at the cordova-inapppurchases-app repository on github and read the full documentation of the cordova-plugin-inapppurchase plugin.

Follow me for updates on similar new posts I write or tweet about this post.