Working with Google Play Billing — Part 2

Caren Chang
Android Developers
Published in
4 min readSep 29, 2020

--

This is the second post in a series focused on integrating Google Play’s billing system into your Android app. If you want to start from the beginning, check out the first blog post on how to set up your Android app to start using the Google Play Billing Library.

In this post, we’ll take a closer look at the lifecycle of a one-time purchase, namely the process of selling and granting users the digital item they purchased in your app. For simplicity, we will focus on one-time purchases for now. In the next post, we will examine in detail the more complicated lifecycle of subscription purchases.

One-time products can either be consumable or non-consumable. A consumable product means that the user can purchase it again. For example, if your app is a game that allows users to buy coins, you can make the coins a consumable product so users can purchase it multiple times. A non-consumable product means the user can purchase it only once. A good example of a non-consumable product is a premium upgrade that includes extra in-app features.

Once you have configured your in-app products in the Google Play Console, the process of selling the products looks like the flow below:

Let’s break down each step of this process.

1. Set up BillingClient — The BillingClient class is what allows your app to communicate with the Play Billing Library. The first thing your app needs to do is set up a connection with Google Play by calling startConnection().

Connections are not guaranteed to stay alive, so your app must also handle reconnections by overriding the onBillingServiceDisconnected() callback to make sure the app is connected to Google Play before making any further requests.

2. Get user’s existing purchases — Once BillingClient is successfully set up, your app can now query for purchases that the user has previously made by calling queryPurchases().

3. Present products for sale — In the previous post, we talked about how to set up products in the Google Play Console and query for those products in your app. Once you call querySkuDetailsAsync() to get the SkuDetails for each product, you can then use the information to set up your UI accordingly.

4. Launch purchase flow — When the user taps on a product to buy it, your app should present the user with the Google Play purchase screen by calling launchBillingFlow() with the SkuDetails of the product. This will then bring up a screen similar to this:

5. Handle purchase result — When the user exits the Google Play purchase screen (either by tapping the ‘Buy’ button to complete the purchase, or by tapping a ‘Back’ button to cancel the purchase), the onPurchaseUpdated() callback sends the result of the purchase flow back to your app. Based on the BillingResult.responseCode, you can then determine whether the user successfully purchased the product. If responseCode == OK, that means the purchase was successfully completed.

onPurchaseUpdated() passes back a list of Purchase objects that includes all the purchases the user has made through the app. Among many other fields, each Purchase object contains the sku, purchaseToken, and isAcknowledged attributes. Using these fields, for each Purchase object you can then determine whether it is a new purchase that needs to be processed or an existing purchase that needs no further processing.

6. Verify and Acknowledge purchase — When using Play Billing Library 3.0, your app needs to acknowledge successful purchases to complete the purchase flow. If your app does not acknowledge a purchase within 72 hours, the user will be refunded and will no longer have access to the original purchase they made.

If your app has a validating server component, you should only acknowledge a purchase after successfully validating it. Verifying purchases is not required, but is considered a best practice when selling in-app products. For more about how to fight fraudulent purchases, check out this guide.

After verifying the purchase, your app then needs to acknowledge the purchase.

  • Non-consumable products must be acknowledged by calling acknowledgePurchase()
  • Consumable products must be marked as ‘consumed’ so users have the option to purchase it again. This is done with the consumeAsync() function. Calling consumeAsync() also sets the purchase as acknowledged, so there is no need to call acknowledgePurchase() on consumable products as long as consumeAsync() is called.

7. Grant user product — With the above steps complete, your app can now grant the user the in-app product they purchased!

If you want to check out resources for the Google Play Billing Library, you can visit the official documentation here. We also have a collection of samples that demonstrate best practices for implementing the Billing library here. Code samples for this blog post can be found on Github.

If your app is not currently using Play Billing Library 3, be sure to check out our migration guide for migrating your app to use the newest Play Billing Library.

--

--