Android Developers Blog
The latest Android and Google Play news for app and game developers.
🔍
Platform Android Studio Google Play Jetpack Kotlin Docs News

10 December 2012

In-App Billing Version 3


Link copied to clipboard
Posted by Bruno Oliveira of the Android Developer Relations Team

In-app Billing has come a long way since it was first announced on Google Play (then Android Market). One year and a half later, the vast majority of top-grossing apps on Google Play use In-app Billing and thousands of developers monetize apps through try-and-buy, virtual goods, as well as subscriptions.

In-app Billing is expanding again, making it even more powerful and flexible so you can continue to build successful applications. Version 3 introduces the following new features:
  • An improved design that makes applications simpler to write, debug and maintain. Integrations that previously required several hundred lines of code can now be implemented in as few as 50.
  • More robust architecture resulting in fewer lost transactions.
  • Local caching for faster API calls.
  • Long-anticipated functionality such as the ability to consume managed purchases and query for product information.

In-app Billing version 3 is available now and lets you sell both in-app items and (since February 2013) subscriptions, including subscriptions with free trials. It is supported by Android 2.2+ devices running the latest version of the Google Play Store (over 90% of active devices).

Instead of the four different application components required by the asynchronous structure of the previous release, the new version of the API allows developers to make synchronous requests and handle responses directly from within a single Activity, all of which are accomplished with just a few lines of code. The reduced implementation cost makes this a great opportunity for developers who are implementing new in-app billing solutions.

Easier to Implement


In contrast to the earlier model of asynchronous notification through a background service, the new API is now synchronous and reports the result of a purchase immediately to the application. This eliminates the necessity to integrate the handling of asynchronous purchase results into the application's lifecycle, which significantly simplifies the code that a developer must write in order to sell an in-app item.

To launch a purchase, simply obtain a buy Intent from the API and start it:

Bundle bundle = mService.getBuyIntent(3, "com.example.myapp",
    MY_SKU, ITEM_TYPE_INAPP, developerPayload);

PendingIntent pendingIntent = bundle.getParcelable(RESPONSE_BUY_INTENT);
if (bundle.getInt(RESPONSE_CODE) == BILLING_RESPONSE_RESULT_OK) {
    // 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));
}

Then, handle the purchase result that's delivered to your Activity's onActivityResult() method:

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 purchase here (for a permanent item like a premium upgrade,
        // this means dispensing the benefits of the upgrade; for a consumable
        // item like "X gold coins", typically the application would initiate
        // consumption of the purchase here)
    }
}

Also, differently from the previous version, all purchases are now managed by Google Play, which means the ownership of a given item can be queried at any time. To implement the same mechanics as unmanaged items, applications can consume the item immediately upon purchase and provision the benefits of the item upon successful consumption.

Local Caching


The API leverages a new feature of the Google Play store application which caches In-app Billing information locally on the device, making it readily available to applications. With this feature, many API calls will be serviced through cache lookups instead of a network connection to Google Play, which significantly speeds up the API's response time. For example, an application could query the owned items using this call:

Bundle bundle = mService.getPurchases(3, mContext.getPackageName(), ITEM_TYPE_INAPP);
if (bundle.getInt(RESPONSE_CODE) == BILLING_RESPONSE_RESULT_OK) {
    ArrayList mySkus, myPurchases, mySignatures;
    mySkus = bundle.getStringArrayList(RESPONSE_INAPP_ITEM_LIST);
    myPurchases = bundle.getStringArrayList(RESPONSE_INAPP_PURCHASE_DATA_LIST);
    mySignatures = bundle.getStringArrayList(RESPONSE_INAPP_PURCHASE_SIGNATURE_LIST);

    // handle items here
}

Querying for owned items was an expensive server call in previous versions of the API, so developers were discouraged from doing so frequently. However, since the new version implements local caching, applications can now make this query every time they start running, and as often as necessary thereafter.

Product Information


The API also introduces a long-anticipated feature: the ability to query in-app product information directly from Google Play. Developers can now programmatically obtain an item's title, description and price. No currency conversion or formatting is necessary: prices are reported in the user's currency and formatted according to their locale:

Bundle bundle = mService.getSkuDetails(3, "com.example.myapp", 
        ITEM_TYPE_INAPP, skus); // skus is a Bundle with the list of SKUs to query
if (bundle.getInt(RESPONSE_CODE) == BILLING_RESPONSE_RESULT_OK) {
    List detailsList = bundle.getStringArrayList(RESPONSE_SKU_DETAILS_LIST);
    for (String details : detailsList) {
        // details is a JSON string with 
        // SKU details (title, description, price, ...)
    }
}

This means that, for example, developers can update prices in Developer Console and then use this API call to show the updated prices in the application (such as for a special promotion or sale) with no need to update the application's code to change the prices displayed to the user.

Sample Application


In addition to the API, we are releasing a new sample application that illustrates how to implement In-app Billing. It also contains helper classes that implement commonly-written boilerplate code such as marshalling and unmarshalling data structures from JSON strings and Bundles, signature verification, as well as utilities that automatically manage background work in order to allow developers to call the API directly from the UI thread of their application. We highly recommend that developers who are new to In-app Billing leverage the code in this sample, as it further simplifies the process of implemention. The sample application is available for download through the Android SDK Manager.

App-Specific Keys


Along with the other changes introduced with In-app Billing Version 3, we have also improved the way Licensing and In-app Billing keys are managed. Keys are now set on a per-app basis, instead of a per-developer basis and are available on the “Services & APIs” page for each application on Google Play Developer Console preview. Your existing applications will continue to work with their current keys.

Get Started!


To implement In-app Billing in your application using the new API, start with the updated In-App Billing documentation and take the Selling In-App Products training class.