One-time purchase lifecycle

One-time purchase products have a simpler lifecycle than subscription products, but there are still several states and transition events that your backend needs to be able to handle properly.

Figure 1 Lifecycle states and transition events for one-time purchases.

New one-time product purchases

After the user completes the billing flow, your app can see information about the new purchase in one of the following ways:

After receiving the new purchase, use the getPurchaseState method or purchases.products.get in Play Developer API to determine the payment state of the new purchase.

Real-time developer notifications

When a user purchases or cancels the purchase of a one-time product, Google Play sends a OneTimeProductNotification message. To update your backend purchase state, use the purchase token provided in the OneTimeProductNotification object to call the purchases.products.get method. This method provides the latest purchase and consumption status given a purchase token.

You should handle transaction-related RTDNs in your secure backend.

Handle completed transactions

When a user completes a one-time product purchase, Google Play sends a OneTimeProductNotification message with the type ONE_TIME_PRODUCT_PURCHASED. When you receive this RTDN, process the purchase as described in Process one-time product purchases in your backend.

Handle canceled transactions

When a one-time product purchase is canceled, Google Play sends a OneTimeProductNotification message with the type ONE_TIME_PRODUCT_CANCELED if you have configured to receive real-time developer notifications. For example, this can occur if the user doesn't complete payment within the required timeframe, or if the purchase is revoked by the developer or by customer request. When your backend server receives this notification, call the purchases.products.get method to get the latest purchase state, then update your backend accordingly, including user entitlements.

If a one-time product purchase in Purchased state gets refunded, you will also be made aware via the Voided Purchases API.

Process one-time product purchases in your backend

Whether you have detected a new purchase via a ONE_TIME_PRODUCT_PURCHASED RTDN or you have been made aware in-app through PurchasesUpdatedListener or manually fetching purchases in your app's onResume() method, you must process the new purchase. We recommend that you handle purchase processing in your backend for better security.

Follow these steps to process a new one-time purchase:

  1. Query the purchases.products.get endpoint to obtain the latest one-time product purchase status. To call this method for a purchase, you need the corresponding purchaseToken either from your app or from the ONE_TIME_PRODUCT_PURCHASED RTDN.
  2. Call getPurchaseState() and make sure that the purchase state is PURCHASED.
  3. Verify the purchase.
  4. Give the user access to the content. The user account associated with the purchase can be identified with the obfuscatedExternalAccountId field from purchases.products.get, if one was set using setObfuscatedAccountId() when the purchase was made.
    1. For non-consumable product purchases, acknowledge delivery of the content by calling the purchases.products.acknowledge method. Make sure that the purchase hasn't been previously acknowledged by checking the acknowledgementState field.
    2. If the product is consumable, mark the item as consumed by calling the purchases.products.consume method so that the user can buy the item again after they have consumed it. This method also acknowledges the purchase.

There are also purchase acknowledgement and consume methods available in the Play Billing Library that allow you to process purchases from you app, but we recommend that you handle processing in your backend if you have one for a more secure implementation.