Add one-time product-specific features

This document explains how to implement functionality specific to one-time products.

Google Play Billing supports the following types of one-time products:

  • Non-consumable one-time products are products that provide a permanent effect, such as a premium upgrade. To avoid users from repurchasing these products, you shouldn't indicate them as being consumed.

  • Consumable one-time products are products that provide temporary benefits and can be repurchased, such as additional in-game currency or extra game lives. To make a consumable one-time product available for purchase again, you need to send a consumption request to Google Play.

Indicate a one-time product has been consumed

To indicate that a one-time product has been consumed, call consumeAsync() on your instance of BillingClient and include the purchase token that Google Play should make available for repurchase. You must also pass an object that implements the ConsumeResponseListener interface. This object handles the result of the consumption operation. You can override the onConsumeResponse() method of the ConsumeResponseListener interface, which the Google Play Billing Library calls when the operation is complete.

Successful purchases generate a purchase token, which is a unique identifier representing a single in-app product that a user has purchased. You can also retrieve the token associated by calling getPurchaseToken() on a Purchase object.

The following example illustrates consuming a product using the associated purchase token:


val consumeParams =
        .setPurchaseToken(/* token */)
        .setDeveloperPayload(/* payload */)

billingClient.consumeAsync(consumeParams, { billingResult, outToken ->
    if (billingResult.responseCode == BillingResponse.OK) {
        // Handle the success of the consume operation.
        // For example, increase the number of coins inside the user's basket.


ConsumeParams consumeParams =
        .setPurchaseToken(/* token */)
        .setDeveloperPayload(/* payload */)

ConsumeResponseListener listener = new ConsumeResponseListener() {
    public void onConsumeResponse(BillingResult billingResult, String outToken) {
            if (billingResult.getResponseCode() == BillingResponse.OK) {
                // Handle the success of the consume operation.
                // For example, increase the number of coins inside the user's basket.

billingClient.consumeAsync(consumeParams, listener);

Because consumption requests can occasionally fail, you must check your secure backend server to ensure that each purchase token hasn't been used. Alternatively, you can wait until you receive a successful consumption response from Google Play before you provision the item. If you choose to withhold purchases from the user until Google Play sends a successful consumption response, you must be very careful not to lose track of the purchase after the consumption request.

Implement a promotion

Promotions, or promo codes, let you give one-time products away to a limited number of users free of charge. The user enters the promo code in your app or in the Google Play Store app and receives the item at no cost. You can use promo codes in many ways to creatively engage with users, such as the following:

  • You might distribute cards with promo codes at an event, and users would enter their promo codes to unlock a special in-game item.
  • You might give codes to employees so they can share them with their friends and family.
  • You might send a promo code to people who buy your app during a certain period of time.

Use the Google Play Console to assign promo codes for your one-time products. To create a promo code for a one-time product, refer to Create promotions.

Redeem a promo code

A user can redeem a promo code in one of the following ways:

  • Manually enter the code in the Google Play Store app.
  • Click on the down arrow next to the form of payment in the Google Play purchase screen and clicking the Redeem link.

Figure 1 shows the purchase screen with the down arrow. Figure 2 shows the Redeem link. Figure 3 shows the screen where users enter their promo code.

Figure 1. Google Play Redemption screen.
Figure 2. Google Play Redeem button.
Figure 3. The promo code screen.

Generate a promo URL

When redeeming a promo code, the user can manually type a promo code in the Google Play Store. Or, you can generate a URL that sends the user to the Google Play Store and auto-populates the Enter code field. Use the following format for a promo code URL:

Figure 4 shows the Google Play app Redeem Code dialog:

Figure 4. Google Play app Redeem Code dialog.

After the user presses Redeem, the Google Play Store prompts the user to open the app. Otherwise, the Google Play Store prompts the user to update or download your app.

Support promo codes in your app

To support promotion codes, your app must call queryPurchases() whenever the app starts or resumes. This method returns a bundle of all current, unconsumed purchases, including purchases the user made by redeeming a promo code. The simplest approach is to call queryPurchases() in your activity's onResume() method, since that callback fires when the activity is created, as well as when the activity is unpaused. Calling queryPurchases() in onStart() and onResume() guarantees that your app finds out about all purchases and redemptions the user may have made while the app wasn't running. Furthermore, if a user makes a purchase while the app is running, and your app misses the purchase for any reason, your app still finds out about the purchase the next time the activity resumes and calls queryPurchases().

Your Activity's onPurchasesUpdated() method receives a response intent identifying when a purchase is completed. However, your app should still call queryPurchases() in onStart() and onResume(), in the case the purchase and consumption workflow didn't complete. For example, if the user successfully redeems a promo code and then your app crashes before the item is consumed, your app still receives information about the purchase when the app calls queryPurchases() on its next startup.

Your app should also support the scenario where a user redeems a promo code in the Google Play Store app while the app is running. Your app can find out about the redemption through the onPurchasesUpdated() listener.

Next steps

After you have added one-time product-specific features, see Best Practices.