Skip to content

Most visited

Recently visited


Implementing In-app Billing

In-app Billing on Google Play provides a straightforward, simple interface for sending In-app Billing requests and managing In-app Billing transactions using Google Play. The information below covers the basics of how to make calls from your application to the In-app Billing service using the In-app Billing API.

Note: This guide provides general instructions to help you implement the In-app Billing API in your app. The Play Billing Library provides a wrapper around the In-app Billing API and is designed to help you when integrating the API. To see a complete implementation using the library, visit the Play Billing Library training class. The training class provides a complete sample In-app Billing app, which demonstrates how to start a purchase flow, handle purchase result, list your products, consume an item, and much more.

Before you start, read the In-app Billing Overview to familiarize yourself with concepts that make it easier for you to implement In-app Billing.

Complete these steps to implement In-app Billing in your application:

  1. Add the In-app Billing library to your project.
  2. Update your AndroidManifest.xml file.
  3. Create a ServiceConnection and bind it to the IInAppBillingService.
  4. Send In-app Billing requests from your application to IInAppBillingService.
  5. Handle In-app Billing responses from Google Play.

Adding the AIDL file to your project

The IInAppBillingService.aidl is an Android Interface Definition Language (AIDL) file that defines the interface to the In-app Billing service. You can use this interface to make billing requests by invoking interprocess communication (IPC) method calls.

You can find the IInAppBillingService.aidl file in the Trivial Drive sample app. To add the In-app Billing library to your project, follow these instructions:

  1. In Android Studio, import the IInAppBillingService.aidl file to your project as described in the following steps:
    1. Create a directory named aidl under src/main.
    2. Add a new package in this directory.
    3. Import the IInAppBillingService.aidl file into this package.
  2. Build your application. You should see a generated file named in the gen/ directory of your project.
  3. Add the helper classes from the util/ directory of the Trivial Drive sample to your project. Remember to change the package name declarations in those files accordingly so that your project compiles.
  4. Updating your app's manifest

    In-app billing relies on the Google Play application, which handles all of the communication between your application and the Google Play server. To use the Google Play application, your application must request the proper permission. You can do this by adding the permission to your AndroidManifest.xml file. If your application does not declare the In-app Billing permission, but attempts to send billing requests, Google Play refuses the requests and responds with an error.

    To give your app the necessary permission, add this line in the AndroidManifest.xml file:

    <uses-permission android:name="" />

    Creating a ServiceConnection

    Your application must have a ServiceConnection to facilitate messaging between your application and Google Play. At a minimum, your application must do the following:

    • Bind to IInAppBillingService.
    • Send billing requests (as IPC method calls) to the Google Play application.
    • Handle the synchronous response messages that are returned with each billing request.

    Binding to IInAppBillingService

    To establish a connection with the In-app Billing service on Google Play, implement a ServiceConnection to bind your activity to IInAppBillingService. Override the onServiceDisconnected and onServiceConnected methods to get a reference to the IInAppBillingService instance after a connection is established.

    IInAppBillingService mService;
    ServiceConnection mServiceConn = new ServiceConnection() {
       public void onServiceDisconnected(ComponentName name) {
           mService = null;
       public void onServiceConnected(ComponentName name,
          IBinder service) {
           mService = IInAppBillingService.Stub.asInterface(service);

    In your activity’s onCreate method, perform the binding by calling the bindService method. Pass the method an Intent that references the In-app Billing service and an instance of the ServiceConnection that you created, and explicitly set the Intent's target package name to—the package name of Google Play app.

    Caution: To protect the security of billing transactions, always explicitly set the intent's target package name to, using setPackage(). Setting the package name explicitly ensures that only the Google Play app can handle billing requests from your app, preventing other apps from intercepting those requests.

    The following code sample demonstrates how to set the intent's target package to protect the security of transactions:

    public void onCreate(Bundle savedInstanceState) {
      Intent serviceIntent =
          new Intent("");
      bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);

    Caution: To ensure that your app is secure, always use an explicit intent when starting a Service and do not declare intent filters for your services. Using an implicit intent to start a service is a security hazard because you cannot be certain of the service that will respond to the intent, and the user cannot see which service starts. Beginning with Android 5.0 (API level 21), the system throws an exception if you call bindService() with an implicit intent.

    You can now use the mService reference to communicate with the Google Play service.

    Important: Remember to unbind from the In-app Billing service when you are done with your Activity. If you don’t unbind, the open service connection could cause your device’s performance to degrade.

    This example shows how to perform the unbind operation on a service connection to In-app Billing called mServiceConn by overriding the activity’s onDestroy method:

    public void onDestroy() {
        if (mService != null) {

    For a complete implementation of a service connection that binds to the IInAppBillingService, see the Selling In-app Products training class and associated sample.

    Making In-app Billing requests

    After your application is connected to Google Play, you can initiate purchase requests for in-app products. Google Play provides a checkout interface for users to enter their payment method, so your application doesn't need to handle payment transactions directly. When an item is purchased, Google Play recognizes that the user has ownership of that item and prevents the user from purchasing another item with the same product ID until it is consumed. You can control how the item is consumed in your application and notify Google Play to make the item available for purchase again. You can also query Google Play to quickly retrieve the list of purchases that the user made. This is useful, for example, when you want to restore the user's purchases when your user launches your app.

    Querying for items available for purchase

    In your application, you can query the item details from Google Play using the In-app Billing API. To pass a request to the In-app Billing service, create a Bundle that contains a String ArrayList of product IDs with key "ITEM_ID_LIST", where each string is a product ID for an purchasable item. Here is an example:

    ArrayList<String> skuList = new ArrayList<String> ();
    Bundle querySkus = new Bundle();
    querySkus.putStringArrayList("ITEM_ID_LIST", skuList);

    To retrieve this information from Google Play, call the getSkuDetails method on the In-app Billing API and pass the In-app Billing API version, the package name of your calling app, the purchase type (“inapp”), and the Bundle that you created, into the method:

    Bundle skuDetails = mService.getSkuDetails(3,
       getPackageName(), "inapp", querySkus);

    If the request is successful, the returned Bundle has a response code of BILLING_RESPONSE_RESULT_OK (0).

    Warning: Don't call the getSkuDetails method on the main thread. Calling this method triggers a network request that could block your main thread. Instead, create a separate thread and call the getSkuDetails method from inside of that thread.

    To view all of the possible response codes from Google Play, see In-app Billing Reference.

    The query results are stored in a String ArrayList with key DETAILS_LIST. The purchase information is stored within the String in JSON format. To view the types of product detail information that are returned, see In-app Billing Reference.

    In this example shows how to retrieve the prices for your in-app items from the skuDetails Bundle that is returned from the previous code snippet:

    public static final int BILLING_RESPONSE_RESULT_OK = 0;
    int response = skuDetails.getInt("RESPONSE_CODE");
    if (response == BILLING_RESPONSE_RESULT_OK) {
       ArrayList<String> responseList
          = skuDetails.getStringArrayList("DETAILS_LIST");
       for (String thisResponse : responseList) {
          JSONObject object = new JSONObject(thisResponse);
          String sku = object.getString("productId");
          String price = object.getString("price");
          if (sku.equals("premium_upgrade")) mPremiumUpgradePrice = price;
          else if (sku.equals("gas")) mGasPrice = price;

    Purchasing an item

    To start a purchase request from your app, call the getBuyIntent method on the In-app Billing service. Pass the In-app Billing API version, the package name of your calling app, the product ID for the item to purchase, the purchase type (“inapp” or "subs"), and a developerPayload String into the method. The developerPayload String is used to specify any additional arguments that you want Google Play to send back along with the purchase information. Here is an example:

    Bundle buyIntentBundle = mService.getBuyIntent(3, getPackageName(),
       sku, "inapp", "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");

    If the request is successful, the returned Bundle has a response code of BILLING_RESPONSE_RESULT_OK (0) and a PendingIntent that you can use to start the purchase flow. To view all of the possible response codes from Google Play, see In-app Billing Reference.

    Caution: Don't use the developerPayload field for security validation purposes. This field isn't always available when completing tasks related to In-app Billing. For more information about security best practices, see the In-app Billing Security Best Practices guide.

    The next step is to extract a PendingIntent from the response Bundle with key BUY_INTENT, as shown here:

    PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");

    To complete the purchase transaction, call the startIntentSenderForResult method and use the PendingIntent that you created. This example uses an arbitrary value of 1001 for the request code:

    public static final int REQUEST_CODE = 1001;
       REQUEST_CODE, new Intent(), Integer.valueOf(0), Integer.valueOf(0),

    Google Play sends a response to your PendingIntent to the onActivityResult method of your application. The onActivityResult method has a result code of Activity.RESULT_OK (1) or Activity.RESULT_CANCELED (0). To view the types of order information that are returned in the response Intent, see In-app Billing Reference.

    The purchase data for the order is a String in JSON format that is mapped to the INAPP_PURCHASE_DATA key in the response Intent. Here is an example:


    Note: Google Play generates a token for the purchase. This token is an opaque character sequence that may be up to 1,000 characters long. Pass this entire token to other methods, such as when you consume the purchase, as described in Consume a Purchase. Don't abbreviate or truncate this token; you must save and return the entire token.

    Continuing from the previous example, you receive the response code, purchase data, and signature from the response Intent:

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       if (requestCode == REQUEST_CODE) {
          int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
          String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
          String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
          if (resultCode == RESULT_OK) {
             try {
                JSONObject jo = new JSONObject(purchaseData);
                String sku = jo.getString("productId");
                logDebug("You have bought the " + sku + ". Excellent choice,
              catch (JSONException e) {
                 logError("Failed to parse purchase data.");

    Security Recommendation: When you receive the purchase response from Google Play, ensure that you check the returned data signature and the orderId. Verify that the orderId exists and is a unique value that you have not previously processed. For added security, you should perform purchase validation on your own secure server.

    Querying for purchased items

    To retrieve information about purchases that are made by a user from your app, call the getPurchases method on the In-app Billing service. Pass the In-app Billing API version, the package name of your calling app, and the purchase type (“inapp” or "subs") into the method. Here is an example:

    Bundle ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);

    The Google Play service returns only the purchases made by the user account that is currently logged in to the device. If the request is successful, the returned Bundle has a response code of 0. The response Bundle also contains a list of the product IDs, a list of the order details for each purchase, and the signatures for each purchase.

    To improve performance, the In-app Billing service returns only up to 700 products that are owned by the user when getPurchase is first called. If the user owns a large number of products, Google Play includes a String token that is mapped to the key INAPP_CONTINUATION_TOKEN in the response Bundle to indicate that more products can be retrieved. Your application can then make a subsequent getPurchases call and pass in this token as an argument. Google Play continues to return a continuation token in the response Bundle until all of the products that are owned by the user are sent to your app.

    For more information about the data that is returned by getPurchases, see In-app Billing Reference. The following example shows how you can retrieve this data from the response:

    int response = ownedItems.getInt("RESPONSE_CODE");
    if (response == BILLING_RESPONSE_RESULT_OK) {
       ArrayList<String> ownedSkus =
       ArrayList<String>  purchaseDataList =
       ArrayList<String>  signatureList =
       String continuationToken =
       for (int i = 0; i < purchaseDataList.size(); ++i) {
          String purchaseData = purchaseDataList.get(i);
          String signature = signatureList.get(i);
          String sku = ownedSkus.get(i);
          // do something with this purchase information
          // e.g. display the updated list of products owned by user
       // if continuationToken != null, call getPurchases again
       // and pass in the token to retrieve more items

    Consuming a purchase

    You can use the In-app Billing API to track the ownership of purchased in-app products in Google Play. Once an in-app product is purchased, it is considered to be owned and cannot be purchased from Google Play. You must send a consumption request for the in-app product before Google Play makes it available for purchase again.

    Important: Managed in-app products are consumable, but subscriptions are not.

    The way that you use the consumption mechanism in your app is up to you. Typically, you implement consumption for in-app products with temporary benefits that users may want to purchase multiple times (for example, in-game currency or equipment). You typically don't want to implement consumption for in-app products that are purchased once and provide a permanent effect (for example, a premium upgrade).

    To record a purchase consumption, send the consumePurchase method to the In-app Billing service and pass in the purchaseToken String value that identifies the purchase to be removed. The purchaseToken is part of the data that is returned in the INAPP_PURCHASE_DATA String by the Google Play service following a successful purchase request. This example records the consumption of a product that is identified with the purchaseToken in the token variable:

    int response = mService.consumePurchase(3, getPackageName(), token);

    Warning: Don't call the consumePurchase method on the main thread. Calling this method triggers a network request that could block your main thread. Instead, create a separate thread and call the consumePurchase method from inside of that thread.

    It's your responsibility to control and track how the in-app product is provisioned to the user. For example, if the user purchased in-game currency, you should update the player's inventory with the amount of currency purchased.

    Security Recommendation: Send a consumption request before provisioning the benefit of the consumable in-app purchase to the user. Ensure that you receive a successful consumption response from Google Play before you provision the item.

    Implementing subscriptions

    Launching a purchase flow for a subscription is similar to launching the purchase flow for a product, with the exception that the product type must be set to "subs". The purchase result is delivered to your Activity's onActivityResult method, exactly as in the case of in-app products. Here is an example:

    Bundle bundle = mService.getBuyIntent(3, "com.example.myapp",
       MY_SKU, "subs", developerPayload);
    PendingIntent pendingIntent = bundle.getParcelable(RESPONSE_BUY_INTENT);
       // Start purchase flow (this brings up the Google Play UI).
       // Result will be delivered through onActivityResult().
       startIntentSenderForResult(pendingIntent, RC_BUY, new Intent(),
           Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0));

    To query for active subscriptions, use the getPurchases method, again with the product type parameter set to "subs":

    Bundle activeSubs = mService.getPurchases(3, "com.example.myapp",
                       "subs", continueToken);

    The call returns a Bundle with all of the active subscriptions that are owned by the user. When a subscription expires without renewal, it no longer appears in the returned Bundle.

    Securing your application

    To help ensure the integrity of the transaction information that is sent to your application, Google Play signs the JSON string that contains the response data for a purchase order. Google Play uses the private key that is associated with your application in the Play Console to create this signature. The Play Console generates an RSA key pair for each application.

    Note: To find the public key portion of this key pair, open your application's details in the Play Console, click Services & APIs, and review the field titled Your License Key for This Application.

    The Base64-encoded RSA public key that is generated by Google Play is in binary encoded, X.509 subjectPublicKeyInfo DER SEQUENCE format. It is the same public key that is used with Google Play licensing.

    When your application receives this signed response, you can use the public key portion of your RSA key pair to verify the signature. By performing signature verification, you can detect any responses that have been tampered with or that have been spoofed. You can perform this signature verification step in your application; however, if your application connects to a secure remote server, Google recommends that you perform the signature verification on that server.

    For more information, see Security Best Practices.

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields


Follow Google Developers on WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience. (April 2018 — Developer Survey)