Important: If your application currently integrates Google Play's billing systemusing AIDL, view theAIDL to Google beat Billing Library hike guidefor a high-level summary of steps compelled to move from AIDL to theGoogle beat Billing Library.

You are watching: Which of these is an example of delayed purchasing

This topic describes how to incorporate the Google play Billing Library intoyour application to start selling products. Before reading this topic, be sureyou've set up her Google Play configuration beforehand by adhering to the stepsin obtaining ready.

This topic has code instances that are based upon the officialsample apps on GitHub. Seeadditional resourcesfor a finish list the sample apps and also other sources that you have the right to usewhile integrating.

Life the a purchase

Here's a common purchase circulation for a one-time purchase or a subscription.

Show the user what they have the right to buy.Launch the purchase flow for the user to accept the purchase.Verify the acquisition on your server.Give contents to the user, and acknowledge distribution of the content.Optionally, note the item as consumed so that the user have the right to buy the itemagain.

Subscriptions instantly renew till they space canceled. A subscription cango through the following states:

Active: User is in good standing and also has access to the subscription.Cancelled: User has cancelled however still has access until expiration.In grace period: User competent a payment issue, however still hasaccess if Google is retrying the payment method.On hold: User knowledgeable a payment issue, and also no longer has actually accesswhile Google is retrying the payment method.Paused: User paused your access, and also does no have accessibility untilthey resume.Expired: User has actually cancelled and lost accessibility to the subscription.The user is considered churned in ~ expiration.

Purchase tokens and Order IDs

Google Play tracks products and also transactions using purchase tokensand stimulate IDs.

A purchase token is a string that represents a buyer's entitlement come aproduct on Google Play. It suggests that a Google user is entitledto a specific product that is stood for by a SKU. You can use thepurchase token with the Google pat chrischona2015.org API.An Order ID is a string the represents a financial transaction onGoogle Play. This cable is had in a receipt that is emailed tothe buyer. You have the right to use the order ID to manage refunds in theused in sales and payout reports.

Order IDs are created every time a jae won transaction occurs. Purchasetokens are created only as soon as a user completes a acquisition flow.

For subscriptions, one initial purchase creates a purchase token and anOrder ID. Because that each continuous billing period, the acquisition token staysthe same, and also a new Order i would is issued. Upgrades, downgrades, replacements,and re-sign-ups every create brand-new purchase tokens and also Order IDs.

For subscriptions, note the following:

Order numbers for subscription renewals save anadditional integer the represents a certain renewal instance. Forexample, one initial subscription order ID might beGPA.1234-5678-9012-34567 with subsequent Order IDs beingGPA.1234-5678-9012-34567..0 (first renewal),GPA.1234-5678-9012-34567..1 (second renewal), and so on.Note: If the user doesn't fan money when they purchase an in-app product,such as throughout a cost-free trial the a subscription, the order ID is issued for$0. Because that example, as soon as a user cancels a subscription, the subscriptionremains valid until the end of the billing period. If the user decides tore-signup, some credit stays in their account. In this case, a brand-new purchasetoken is created, an stimulate ID is produced for $0, and also the subscription renewsafter the credit runs out.

Error Handling

The Google pat Billing Library return errors in the form ofBillingResult.A BillingResult contains aBillingResponseCode,which categorizes possible billing-related errors the your application can encounter.For example, if you obtain a SERVICE_DISCONNECTEDerror code, your app should reinitialize the connection with Google Play.Additionally, a BillingResult has adebug message,which is advantageous during advance to diagnose errors.

Connect come Google Play

The very first step to integrate with Google Play's billing system is to add thelibrary to your app and initialize a connection.

Add the Google beat Billing Library dependency

Note: If you've adhered to the getting readyguide, then you've already added the vital dependencies and also can relocate onto the following section.

Add the Google pat Billing Library suspended to your app'sbuild.gradle record as shown:


Groovy

dependencies def billing_version = "4.0.0" implementation "com.chrischona2015.org.billingclient:billing:$billing_version"

Kotlin

dependencies val billing_version = "4.0.0" implementation("com.chrischona2015.org.billingclient:billing:$billing_version")
If you're making use of Kotlin, the play Billing Library KTX module containsKotlin extensions and also coroutines support that enable you to writeidiomatic Kotlin once using the Google pat Billing Library. Come includethese expansions in your project, add the adhering to dependency come yourapp's build.gradle paper as shown:


Groovy

dependencies def billing_version = "4.0.0" implementation "com.chrischona2015.org.billingclient:billing-ktx:$billing_version"

Kotlin

dependencies val billing_version = "4.0.0" implementation("com.chrischona2015.org.billingclient:billing-ktx:$billing_version")

Initialize a BillingClient

Once you've added a suspended on the Google play Billing Library, you need toinitialize a BillingClientinstance. BillingClient is the main user interface for communication in between theGoogle play Billing Library and the remainder of your app. BillingClientprovides convenience methods, both synchronous and also asynchronous, formany common billing operations. It's strong recommended the you have actually oneactive BillingClientconnection open at one time to prevent multiple PurchasesUpdatedListener callbacksfor a solitary event.

To produce a BillingClient, usenewBuilder().You can pass any kind of context come newBuilder(), and BillingClient uses it toget an application context. That method you don't should worry about memoryleaks. To receive updates top top purchases, girlfriend must likewise callsetListener(), passing a reference to aPurchasesUpdatedListener.This listener receives update for every purchases in her app.


Kotlin

private val purchasesUpdatedListener = PurchasesUpdatedListener billingResult, purchase -> // come be imposed in a later section. Private var billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) .enablePendingPurchases() .build()

Java

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener()
Override publicly void onPurchasesUpdated(BillingResult billingResult, perform purchases) // come be imposed in a later section. ;private BillingClient billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) .enablePendingPurchases() .build();

Establish a connection to Google Play

After girlfriend have produced a BillingClient, you require to develop a connectionto Google Play.

To affix to Google Play, callstartConnection().The connection process is asynchronous, and also you need to implement aBillingClientStateListenerto get a callback when the setup the the client is complete and also it’sready come make further requests.

You must likewise implement retry reasonable to handle shed connections toGoogle Play. Come implement retry logic, override theonBillingServiceDisconnected()callback method, and also make certain that the BillingClient calls thestartConnection()method come reconnect come Google Play prior to making further requests.

The following example demonstrates just how to begin a connection and test thatit's prepared to use:


Kotlin

billingClient.startConnection(object : BillingClientStateListener override fun onBillingSetupFinished(billingResult: BillingResult) if (billingResult.responseCode == BillingResponseCode.OK) // The BillingClient is ready. You can query to buy here. override fun onBillingServiceDisconnected() // try to restart the connection on the next request to // Google pat by calling the startConnection() method. )

Java

billingClient.startConnection(new BillingClientStateListener()
Override publicly void onBillingSetupFinished(BillingResult billingResult) if (billingResult.getResponseCode() == BillingResponseCode.OK) // The BillingClient is ready. You have the right to query purchase here.
Override publicly void onBillingServiceDisconnected() // try to restart the link on the next request come // Google beat by phone call the startConnection() method. );
Note: It's strongly recommended the you implement your own connectionretry logic and also override theonBillingServiceDisconnected()method. Make sure you keep the BillingClient connection whenexecuting any type of methods.

Show products easily accessible to buy

After girlfriend have developed a link to Google Play, friend areready to query because that your easily accessible products and display lock to her users.To ask Google Play because that in-app product details, callquerySkuDetailsAsync().Querying for SKU details is crucial step before displaying your productsto her users, together it returns localized product information. Forsubscriptions, ensure her product displayfollows all Play policies.

When call querySkuDetailsAsync(), happen an circumstances ofSkuDetailsParamsthat states a list of product identifier strings developed in Google beat Consolealong v a SkuType. The SkuType can be either SkuType.INAPP forone-time commodities or SkuType.SUBS because that subscriptions.

To handle the result of the asynchronous operation, friend must additionally specify alistener which implements theSkuDetailsResponseListenerinterface. You can then overrideonSkuDetailsResponse(),which educates the listener once the questions finishes, as displayed in the followingexample:


Kotlin

suspend fun querySkuDetails() val skuList = ArrayList() skuList.add("premium_upgrade") skuList.add("gas") val params = SkuDetailsParams.newBuilder() params.setSkusList(skuList).setType(SkuType.INAPP) // leverage querySkuDetails Kotlin extension duty val skuDetailsResult = withContext(Dispatchers.IO) billingClient.querySkuDetails(params.build()) // process the result.

Java

List skuList = brand-new ArrayList ();skuList.add("premium_upgrade");skuList.add("gas");SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();params.setSkusList(skuList).setType(SkuType.INAPP);billingClient.querySkuDetailsAsync(params.build(), brand-new SkuDetailsResponseListener()
Override publicly void onSkuDetailsResponse(BillingResult billingResult, perform skuDetailsList) // procedure the result. );
The Google pat Billing Library stores the query outcomes in a list ofSkuDetails objects.You have the right to then call a variety of techniques on each SkuDetails thing in thelist come view relevant information around an in-app product, such asits price or description. To view the obtainable product detail information,see the list of methods in theSkuDetails class.

Before offering an object for sale, examine that the user does no alreadyown the item. If the user has actually a consumable the is quiet in your itemlibrary, they need to consume the item prior to they have the right to buy the again.

Before supplying a subscription, verify that the user is not currently subscribed.

Note: some chrischona2015.org devices might have one older version of the Google PlayStore app that doesn't support certain products types, such assubscriptions. Before your app enters the billing flow, you deserve to callisFeatureSupported()to recognize whether the maker supports the assets you desire to sell.For a perform of product types that deserve to be supported, seeBillingClient.FeatureType.

Launch the acquisition flow

To start a purchase request from your app, speak to thelaunchBillingFlow()method from your app's main thread. This an approach takes a recommendation to aBillingFlowParamsobject that consists of the relevantSkuDetails objectobtained native callingquerySkuDetailsAsync().To create a BillingFlowParams object, use theBillingFlowParams.Builder class.


Kotlin

// An task reference from which the billing circulation will be launched.val task : activity = ...;// Retrieve a worth for "skuDetails" by phone call querySkuDetailsAsync().val flowParams = BillingFlowParams.newBuilder() .setSkuDetails(skuDetails) .build()val responseCode = billingClient.launchBillingFlow(activity, flowParams).responseCode

Java

// An task reference indigenous which the billing circulation will it is in launched.Activity activity = ...;// Retrieve a value for "skuDetails" by phone call querySkuDetailsAsync().BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setSkuDetails(skuDetails) .build();int responseCode = billingClient.launchBillingFlow(activity, billingFlowParams).getResponseCode();// manage the result.
The launchBillingFlow() method returns one of several solution codeslisted inBillingClient.BillingResponseCode.Be certain to examine this an outcome to ensure there to be no errors launching thepurchase flow. A BillingResponseCode the OK indicates a effective launch.

On a successful call to launchBillingFlow(), the system displays theGoogle Play purchase screen. Number 1 reflects a purchase screen for asubscription:

*
Figure 1. The Google play purchase display shows a subscription that is easily accessible for purchase.

Google pat calls onPurchasesUpdated() to deliver the result ofthe purchase operation to a listener that implements thePurchasesUpdatedListener interface. The listener is mentioned using thesetListener() method when you initialized her client.

You must implement onPurchasesUpdated() to handle feasible response codes.The following example shows how to override onPurchasesUpdated():


Kotlin

override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List?) if (billingResult.responseCode == BillingResponseCode.OK && to buy != null) because that (purchase in purchases) handlePurchase(purchase) rather if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) // handle an error led to by a user cancelling the purchase flow. else // Handle any kind of other error codes.

Java


Overridevoid onPurchasesUpdated(BillingResult billingResult, list purchases) if (billingResult.getResponseCode() == BillingResponseCode.OK && to buy != null) for (Purchase acquisition : purchases) handlePurchase(purchase); else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) // take care of an error resulted in by a user cancelling the purchase flow. else // Handle any kind of other error codes.
A successful acquisition generates a Google Play purchase success screensimilar to figure 2.

*
Figure 2. Google Play"s acquisition success screen.

A successful purchase also generates a acquisition token, i m sorry is a uniqueidentifier the represents the user and also the product ID for thein-app product castle purchased. Your apps deserve to store the purchase tokenlocally, though us recommend passing the token to her secure backend serverwhere you deserve to then verify the purchase and protect versus fraud. Thisprocess is further explained in the complying with section.

The user is additionally emailed a receipt that the transaction include an OrderID or a distinctive ID of the transaction. Customers receive an e-mail with a uniqueOrder ID for each one-time product purchase, and likewise for the initialsubscription purchase and also subsequent recurring automatically renewals. Youcan usage the stimulate ID to regulate refunds in the Google beat Console.

Processing purchases

Once a user completes a purchase, your app then demands to procedure thatpurchase. In many cases, your application is notified of purchases through yourPurchasesUpdatedListener.but over there are situations where your app is made aware of callingBillingClient.queryPurchasesAsync()as explained in Fetching purchases.

Your application should procedure a acquisition in the adhering to way:

Verify the purchase.Give content to the user, and also acknowledge delivery of the content.Optionally, mark the item as consumed so the the user can buythe items again.

To verify a purchase, an initial check that thepurchase stateis PURCHASED.If the acquisition is PENDING, then you should procedure the purchase as describedin managing pending transactions. Because that purchases received fromonPurchasesUpdated()or queryPurchasesAsync,you should additional verify the acquisition to ensure legitimacy prior to yourapp sponsor entitlement. Come learn exactly how to appropriately verify a purchase, seeVerify purchases prior to granting entitlements.

Once you've proved the purchase, your application is ready to grantentitlement come the user. After giving entitlement, her appmust then identify the purchase. This acknowledgement communicates toGoogle Play that you have granted entitlement because that the purchase.

Note: If you perform not recognize a acquisition within three days, the userautomatically obtain a refund, and also Google beat revokes the purchase.Note: Acknowledgement is not forced when making use of a version of theGoogle play Billing Library before 2.0.

The procedure to approve entitlement and acknowledge the purchase depends onwhether the purchase is a non-consumable, a consumable, or a subscription.

For consumables, theconsumeAsync()method fulfills the acknowledgement requirement and indicates the your apphas granted entitlement to the user. This an approach also permits your application to makethe one-time product available for acquisition again.

To indicate that a one-time product has actually been consumed, speak to consumeAsync()and encompass the acquisition token the Google Play should make available forrepurchase. Friend must likewise pass things that implements theConsumeResponseListenerinterface. This thing handles the an outcome of the usage operation.You deserve to override theonConsumeResponse()method, i beg your pardon the Google pat Billing Library calls once the operationis complete.

The following example illustrates spend a product utilizing the associatedpurchase token:


Kotlin

suspend fun handlePurchase(purchase: Purchase) // acquisition retrieved from BillingClient#queryPurchasesAsync or your PurchasesUpdatedListener. Val purchase : acquisition = ...; // Verify the purchase. // certain entitlement was not already granted because that this purchaseToken. // provide entitlement to the user. Val consumeParams = ConsumeParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build() val consumeResult = withContext(Dispatchers.IO) client.consumePurchase(consumeParams)

Java

void handlePurchase(Purchase purchase) // purchase retrieved native BillingClient#queryPurchasesAsync or your PurchasesUpdatedListener. Purchase purchase = ...; // Verify the purchase. // ensure entitlement to be not currently granted for this purchaseToken. // approve entitlement come the user. ConsumeParams consumeParams = ConsumeParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); ConsumeResponseListener listener = new ConsumeResponseListener()
Override public void onConsumeResponse(BillingResult billingResult, wire purchaseToken) if (billingResult.getResponseCode() == BillingResponseCode.OK) // take care of the success that the consume operation. ; billingClient.consumeAsync(consumeParams, listener);
Note: because consumption requests deserve to occasionally fail, you have to checkyour secure backend server to ensure the each purchase token hasn't beenused therefore your application doesn’t approve entitlement multiple times because that the samepurchase. Alternatively, your app can wait until you obtain a successfulconsumption an answer from Google Play prior to granting entitlement. Ifyou choose to withhold purchases from the user till Google pat sendsa successful usage response, you need to be an extremely careful no to losetrack that the purchase after the usage request.To identify non-consumable purchases, usage eitherBillingClient.acknowledgePurchase()from the Billing Library orProduct.Purchases.Acknowledgefrom the Google play chrischona2015.org API. Prior to acknowledging a purchase, yourapp should inspect whether that was currently acknowledged by utilizing theisAcknowledged()method in the Google pat Billing Library or theacknowledgementStatefield in the Google chrischona2015.org API.

The following example shows just how to acknowledge a acquisition usingthe Google beat Billing Library:


Kotlin

val client: BillingClient = ...val acknowledgePurchaseResponseListener: AcknowledgePurchaseResponseListener = ...suspend funny handlePurchase() if (purchase.purchaseState === PurchaseState.PURCHASED) if (!purchase.isAcknowledged) val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.purchaseToken) val ackPurchaseResult = withContext(Dispatchers.IO) client.acknowledgePurchase(acknowledgePurchaseParams.build())

Java

BillingClient client = ...AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ...void handlePurchase(Purchase purchase) if (purchase.getPurchaseState() == PurchaseState.PURCHASED) if (!purchase.isAcknowledged()) AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
Subscriptions room handled an in similar way to non-consumables. You canacknowledge a subscription Acknowledgement utilizing eitherBillingClient.acknowledgePurchase()from the Google play Billing Library orPurchases.Subscriptions.Acknowledgefrom the Google beat chrischona2015.org API. Every initial subscription purchase needto it is in acknowledged. Subscription renewals execute not should be acknowledged.For much more information on as soon as subscriptions have to be acknowledged, see theSell subscriptions topic.

Fetching purchases

Listening to purchase updates utilizing aPurchasesUpdatedListeneris not sufficient to for sure your application processes every purchases. It's possiblethat your application might not be conscious of all the to buy a user has made. Hereare some scenarios whereby your application could shed track or be unaware the purchases:

Network worries during the purchase: A user renders a successfulpurchase and receives check from Google, yet their device losesnetwork connectivity before their machine receives notification ofthe purchase through the PurchasesUpdatedListener.Multiple devices: A user buys an object on one an equipment and thenexpects to see the item once they move devices.Handling purchase made exterior your app: some purchases, suchas promotion redemptions, can be made exterior of your app.

To manage these situations, be certain that your application callsBillingClient.queryPurchasesAsync()in your onResume() and onCreate() methods to ensure the all purchasesare efficiently processed as defined in processing purchases.

Handling purchase made exterior your app

Some purchases, such as promo redemptions, deserve to happen external of her app.When a user renders a purchase exterior of her app, they expect your app to showan in-app message, or usage some sort of an alert mechanism to let the userknow that the application correctly received and processed the purchase. Someacceptable instrument are:

Show an in-app popup.Deliver the article to one in-app post box, and plainly stating the thereis a new message in the in-app blog post box.Use an OS notification message.

Keep in mind the it is possible for your application to it is in in any state once your apprecognizes the purchase. It is even possible for your application to not also beinstalled as soon as the acquisition was made. Users mean to get their purchasewhen they resume the app, regardless of the state in i m sorry the app is.

You need to detect purchases regardless of the state in i m sorry the application is once thepurchase was made. However, there are some exceptions whereby it may be acceptableto not instantly notify the user that the item to be received. Because that example:

During the action part of a game, where reflecting a message might distract theuser. In this case, girlfriend must educate the user after the action component is over.During cutscenes, where reflecting a message may distract the user. In this case,you must educate the user after the cutscene is over.During the initial tutorial and also user setup parts of the game. Us recommend younotify brand-new users the the reward instantly after they open up the video game or duringinitial user set up. However, that is acceptable to wait until the key gamesequence is available to notify the user.

Always save the user in mind as soon as deciding when and how to notify your individuals ofpurchases made exterior of her app. Any time a user doesn’t automatically receivea notification, they may obtain confused, and may prevent using your app, contact usersupport, or complain around it on society media.

Handling pending transactions

Note: Pending transactions are compelled in Google beat Billing Library versions2.0 and also higher.Note: extr forms of payment space not obtainable for subscriptionspurchases.

Google Play support pending transactions, or transactions the requireone or more additional steps in between when a user initiates a purchase andwhen the payment an approach for the purchase is processed. Your app should notgrant entitlement come these species of purchases until Google informs youthat the user's payment technique was successfully charged.

For example, a user can produce a PENDING purchase of an in-app article bychoosing cash as their form of payment. The user deserve to then select a physicalstore wherein they will complete the transaction and receive a code v bothnotification and also email. As soon as the user arrives at the physics store, theycan redeem the code with the cashier and pay v cash. Google climate notifiesboth you and also the user the cash has actually been received. Your app can climate grantentitlement to the user.

Your application must support pending transactions through callingenablePendingPurchases()as component of initializing her app.

When your app receives a brand-new purchase, either through yourPurchasesUpdatedListeneror together a an outcome of callingqueryPurchasesAsync(),use the getPurchaseState()method to identify whether the purchase state is purchased or PENDING.Note that you should approve entitlement only once the state is PURCHASED. Ifyour application is running once the user completes the purchase, yourPurchasesUpdatedListeneris dubbed again, and the PurchaseState is now PURCHASED. In ~ this point,your application can procedure the purchase using the standard method forprocessing one-time purchases. Your application should additionally callqueryPurchasesAsync() in her app's onResume() and also onCreate() approaches tohandle purchases that have transitioned come the purchased state if yourapp was no running.

Note: You should acknowledge a purchase only once the state is PURCHASED.You cannot acknowledge while a purchase is PENDING. The 3 dayacknowledgement home window begins only as soon as the purchase state transitions from'PENDING' come 'PURCHASED'.

See more: What Is A Third Of A Half - What'S Half Of One Third Of A Cup

Your application can additionally useReal-time chrischona2015.org Notificationswith pending purchases by hearne forOneTimeProductNotifications. When the purchase transitions native PENDINGto PURCHASED, your app receives aONE_TIME_PRODUCT_PURCHASED notification. If the purchase is cancelled,your app receives a ONE_TIME_PRODUCT_CANCELED notification. This canhappen if your customer go not finish payment in the required timeframe.When receiving this notifications, you deserve to use the Google beat chrischona2015.orgAPI, which consists of a PENDING state forPurchases.products.

Note: Pending transactions have the right to be tested making use of license testers. In additionto two test credit transaction cards, license testers have access to 2 testinstruments for delayed forms of payment wherein the payment automaticallycompletes or cancels after a couple of minutes. While trial and error yourapplication, you must verify the your applications does not grantentitlement or identify the purchase immediately after purchasingwith either of these 2 instruments. Once purchasing making use of the testinstrument that instantly completes, you have to verify the yourapplication sponsor entitlement and also acknowledges the acquisition aftercompletion.