Warning: AIDL is now deprecated and will be removed in a future release. To implement billing-related features, use the Google Play Billing Library.
You can use an Android Interface Definition Language (AIDL) interface to implement some features of Google Play's billing system.
Purchasing Products
A typical purchase flow with the Google Play Billing AIDL API is as follows:
- Your application sends an
isBillingSupported
request to Google Play to determine that the target version of the Google Play Billing AIDL API that you are using is supported. The request also verifies that Google Play supports billing in the user's country. - When your application starts or user logs in, it's good practice to check
with Google Play to determine what items are owned by the user. To query the
user's purchases, send a
getPurchases
request. If the request is successful, Google Play returns aBundle
containing a list of product IDs of the purchased items, a list of the individual purchase details, and a list of the signatures for the purchases. - Usually, you'll want to inform the user of the products that are
available for purchase. To query the details of the in-app products that you
defined in Google Play, your application can send a
getSkuDetails
request. You must specify a list of product IDs in the query request. If the request is successful, Google Play returns aBundle
containing product details including the product’s price, title, description, and the purchase type. - If an in-app product is not owned by the user, you can initiate a
purchase for it. To start a purchase request, your application sends a
getBuyIntent
request, specifying the product ID of the item to purchase, along with other parameters. You should record the product ID when you create a new in-app product in the Google Play Console.- Google Play returns a
Bundle
that contains aPendingIntent
which your application uses to start the checkout UI for the purchase. - Your application launches the pending intent by calling the
startIntentSenderForResult
method. - When the checkout flow finishes (that is, the user successfully
purchases the item or cancels the purchase), Google Play sends a response
Intent
to youronActivityResult
method. The result code of theonActivityResult
has a result code that indicates whether the purchase was successful or canceled. The responseIntent
contains information about the purchased item, including apurchaseToken
String that is generated by Google Play to uniquely identify this purchase transaction. TheIntent
also contains the signature of the purchase, signed with your private developer key.
- Google Play returns a
To learn more about the Google Play Billing AIDL API calls and server responses, see Google Play Billing AIDL API Reference.
Consuming In-app Products
You can use the consumption mechanism to track the user's ownership of managed products.
All managed products are managed in the Google Play Billing AIDL API. This means that the user's ownership of all managed product purchases is maintained by Google Play, and your application can query the user's purchase information when needed. When the user successfully purchases a managed product, that purchase is recorded in Google Play. Once a managed product is purchased, it is considered to be "owned". Managed products in the "owned" state cannot be purchased from Google Play. You must send a consumption request for the "owned" managed product before Google Play makes it available for purchase again. Consuming the managed product reverts it to the "unowned" state, and discards the previous purchase data.
To retrieve the list of products owned by the user, your application sends a
getPurchases
call to Google Play. Your application can make a consumption request by
sending a consumePurchase
call. In the request argument, you must specify the managed
product's unique purchaseToken
string that you obtained from Google Play when it was
purchased. Google Play returns a status code indicating if the consumption was recorded
successfully.
Non-consumable and Consumable Managed Products
It's up to you to decide if you want to handle your managed products as non-consumable or consumable items.
- Non-consumable products
- Typically, you would not implement consumption for managed products that can only be purchased once in your application and provide a permanent benefit. Once purchased, these products will be permanently associated to the user's Google account. An example of a non-consumable managed product is a premium upgrade or a level pack.
- Consumable products
-
In contrast, you can implement consumption for products that can be made
available for purchase multiple times. Typically, these products provide
certain temporary effects. For example, the user's in-game character might
gain life points or gain extra gold coins in their inventory. Dispensing
the benefits or effects of the purchased product in your application is called
provisioning the managed product. You are responsible for
controlling and tracking how managed products are provisioned to the users.
Important: Before provisioning the consumable managed product in your application, you must send a consumption request to Google Play and receive a successful response indicating that the consumption was recorded.
Managing consumable purchases in your application
Here is the basic flow for purchasing a consumable managed product:
- Call the
getBuyIntent
method to launch a purchase flow. - Inspect the returned
Bundle
from Google Play to determine whether the purchase completed successfully. - If the purchase was successful, consume the purchase by calling the
consumePurchase
method. - Inspect the response code from Google Play to determine whether the consumption completed successfully.
- If the consumption was successful, provision the product in your application.
Subsequently, when the user starts up or logs in to your application, you should check if the user owns any outstanding consumable in-app products; if so, make sure to consume and provision those items. Here's the recommended application startup flow if you implement consumable in-app products in your application:
- Send a
getPurchases
request to query the owned in-app products for the user. - If there are any consumable in-app products, consume the items by calling
consumePurchase
. This step is necessary because the application might have completed the purchase order for the consumable product, but stopped or got disconnected before the application had the chance to send a consumption request. - Inspect the response code from Google Play to determine whether the consumption completed successfully.
- If the consumption was successful, provision the product in your application.
Configure rewarded purchases
Warning: Rewarded products are no longer supported. For more information, see Create a rewarded product.
When working with rewarded products using the AIDL, you should cache the buy `Intent` before a user needs to collect the reward. You can call the buy intent on a background thread and save the successful response `Intent` until the user takes action to collect the reward.
List and load SKUs
Before offering a rewarded product to a user, get the product details by
calling getSkuDetails()
. A new JSON field, "rewardToken", is
populated for each rewarded product in the list of SKUs.
getBuyIntentExtraParams()
on a background thread. After
you receive a response of BILLING_RESPONSE_RESULT_OK
, enable the
rewarded product for the user and save the returned PendingIntent
object for use later.
The following code snippet demonstrates the process for loading the ad
associated with a rewarded product:
Kotlin
val rewardToken = skuDetailsJson.optString("rewardToken") val extraParams = Bundle().putString("rewardToken", rewardToken) // This call blocks the current thread, so do this in the background. val buyIntentBundle : Bundle = mService.getBuyIntentExtraParams(9, packageName, sku, "inapp", "", extraParams) val response = buyIntentBundle.getInt("RESPONSE_CODE") if (response == BILLING_RESPONSE_RESULT_OK) { // Enable rewarded product. // Save this object for use later. val pendingIntentToSave = bundle.getParcelable(RESPONSE_BUY_INTENT) } else { // Don't offer rewarded product. }
Java
String rewardToken = skuDetailsJson.optString("rewardToken"); Bundle extraParams = new Bundle(); extraParams.putString("rewardToken", rewardToken); // This call blocks the current thread, so do this in the background. Bundle buyIntentBundle = mService.getBuyIntentExtraParams(9, getPackageName(), sku, "inapp", "", extraParams); int response = buyIntentBundle.getInt("RESPONSE_CODE"); if (response == BILLING_RESPONSE_RESULT_OK) { // Enable rewarded product. // Save this object for use later. PendingIntent pendingIntentToSave = bundle.getParcelable(RESPONSE_BUY_INTENT); } else { // Don't offer rewarded product. }
Declare age-appropriate ads
To help facilitate compliance with legal obligations related to children and to underage users, including the Children's Online Privacy Protection Act (COPPA) and the General Data Protection Regulation (GDPR), your app should declare which ads should be treated as child-directed in the United States and which ads are directed at users who are under the applicable age of consent in their country. The AdMob Help Center explains when you should tag your ad requests for child-directed treatment and when you should tag them for under-the-age-of-consent treatment, as well as the effects of doing so.
To indicate that a rewarded request is targeted for children or for users
under the age of consent, include the childDirected
and
underAgeOfConsent
extra parameters, as shown in the following code
snippet:
Kotlin
val rewardToken = skuDetailsJson.optString("rewardToken") val extraParams = Bundle().putString("rewardToken", rewardToken) .putInt("childDirected", ChildDirected.CHILD_DIRECTED) .putInt("underAgeOfConsent", UnderAgeOfConsent.UNDER_AGE_OF_CONSENT) // This call blocks the current thread, so do this in the background. val buyIntentBundle : Bundle = mService.getBuyIntentExtraParams(9, packageName, sku, "inapp", "", extraParams)
Java
Bundle extraParams = new Bundle(); extraParams.putString("rewardToken", rewardToken); extraParams.putInt("childDirected", ChildDirected.CHILD_DIRECTED); extraParams.putInt("underAgeOfConsent", UnderAgeOfConsent.UNDER_AGE_OF_CONSENT); // This call blocks the current thread, so do this in the background. Bundle buyIntentBundle = mService.getBuyIntentExtraParams( 9, getPackageName(), sku, "inapp", "", extraParams);
Play ads before rewarding your user
After the user clicks the button to start watching the ad, your app is able to use the savedPendingIntent
object to start playing ads. To do so,
call startIntentSenderForResult()
:
Kotlin
startIntentSenderForResult( pendingIntentToSave, RC_BUY, Intent(), 0, 0, 0 )
Java
startIntentSenderForResult(pendingIntentToSave, RC_BUY, new Intent(), 0, 0, 0);
Then, process the billing workflow's results in
onActivityResult()
, as shown in the following code snippets. When
handling the ad-playing process, Google Play uses the same set of
server response
codes as it does for other billing flows.
Kotlin
fun onActivityResult(requestCode : Int, resultCode : Int, data : Intent) { if (requestCode == RC_BUY) { int responseCode = data.getIntExtra(RESPONSE_CODE) String purchaseData = data.getStringExtra(RESPONSE_INAPP_PURCHASE_DATA) String signature = data.getStringExtra(RESPONSE_INAPP_SIGNATURE) // Handle reward purchase. } }
Java
public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == RC_BUY) { int responseCode = data.getIntExtra(RESPONSE_CODE); String purchaseData = data.getStringExtra(RESPONSE_INAPP_PURCHASE_DATA); String signature = data.getStringExtra(RESPONSE_INAPP_SIGNATURE); // Handle reward purchase. } }
Local Caching
Because the Google Play client now caches billing information locally on the device, you can use the Google Play Billing AIDL API to query for this information more frequently. The following Google Play Billing AIDL API calls are serviced through cache lookups instead of requiring a network connection, which significantly speeds up the API's response time:
getBuyIntent
getPurchases
isBillingSupported