page.title=Subscriptions parent.title=In-app Billing parent.link=index.html @jd:body
Subscriptions let you sell content, services, or features in your app with automated, recurring billing. Adding support for subscriptions is straightforward and you can easily adapt an existing In-app Billing implementation to sell subscriptions.
If you have already implemented In-app Billing for one-time purchase products, you will find that you can add support for subscriptions with minimal impact on your code. If you are new to In-app Billing, you can implement subscriptions using the standard communication model, data structures, and user interactions as for other in-app products.subscriptions. Because the implementation of subscriptions follows the same path as for other in-app products, details are provided outside of this document, starting with the In-app Billing Overview.
This document is focused on highlighting implementation details that are specific to subscriptions, along with some strategies for the associated billing and business models.
A subscription is a new product type offered in In-app Billing that lets you sell content, services, or features to users from inside your app with recurring monthly or annual billing. You can sell subscriptions to almost any type of digital content, from any type of app or game.
As with other in-app products, you configure and publish subscriptions using the Developer Console and then sell them from inside apps installed on an Android-powered devices. In the Developer console, you create subscription products and add them to a product list, setting a price for each, choosing a billing interval of monthly or annually, and then publishing. In your apps, it’s straightforward to add support for subscription purchases. The implementation extends the standard In-app Billing API to support a new product type but uses the same communication model, data structures, and user interactions as for other in-app products.
When users purchase subscriptions in your apps, Google Play handles all checkout details so your apps never have to directly process any financial transactions. Google Play processes all payments for subscriptions through Google Wallet, just as it does for standard in-app products and app purchases. This ensures a consistent and familiar purchase flow for your users.
After users have purchase subscriptions, they can view the subscriptions and cancel them, if necessary, from the My Apps screen in the Play Store app or from the app's product details page in the Play Store app.
Once users have purchased a subscription through In-app Billing, you can easily give them extended access to additional content on your web site (or other service) through the use of a server-side API provided for In-app Billing. The server-side API lets you validate the status of a subscription when users sign into your other services. For more information about the API, see Google Play Android Developer API, below.
You can also build on your existing external subscriber base from inside your Android apps. If you sell subscriptions on a web site, for example, you can add your own business logic to your Android app to determine whether the user has already purchased a subscription elsewhere, then allow access to your content if so or offer a subscription purchase from Google Play if not.
With the flexibility of In-app Billing, you can even implement your own solution for sharing subscriptions across as many different apps or products as you want. For example, you could sell a subscription that gives a subscriber access to an entire collection of apps, games, or other content for a monthly or annual fee. To implement this solution, you could add your own business logic to your app to determine whether the user has already purchased a given subscription and if so, allow access to your content.
In general the same basic policies and terms apply to subscriptions as to standard in-app products, however there are some differences. For complete information about the current policies and terms, please read the policies document.
To sell a subscription in an app, you use the tools in the Developer Console to set up a product list for the app and then create and configure a new subscription. In the subscription, you set the price and billing interval and define a subscription ID, title, and description. When you are ready, you can then publish the subscription in the app product list.
In the product list, you can add subscriptions, in-app products, or both. You can add multiple subscriptions that give access to different content or services, or you can add multiple subscriptions that give access to the same content but for different intervals or different prices, such as for a promotion. For example, a news outlet might decide to offer both monthly and annual subscriptions to the same content, with annual having a discount. You can also offer in-app purchase equivalents for subscription products, to ensure that your content is available to users of older devices that do not support subscriptions.
After you add a subscription or in-app product to the product list, you must publish the product before Google Play can make it available for purchase. Note that you must also publish the app itself before Google Play will make the products available for purchase inside the app.
Important: At this time, the capability to unpublish a subscription is not available. Support for unpublishing a subscription is coming to the Developer Console in the weeks ahead, so this is a temporary limitation. In the short term, instead of unpublishing, you can remove the subscription product from the product list offered in your app to prevent users from seeing or purchasing it.
When you create a subscription in the Developer Console, you can set a price for it in any available currencies. Each subscription must have a non-zero price. You can price multiple subscriptions for the same content differently — for example you could offer a discount on an annual subscription relative to the monthly equivalent.
Important: At this time, once you publish a subscription product, you cannot change its price in any currency. Support for changing the price of published subscriptions is coming to the Developer Console in the weeks ahead. In the short term, you can work around this limitation by publishing a new subscription product ID at a new price, then offer it in your app instead of the original product. Users who have already purchased will continue to be charged at the original price, but new users will be charged at the new price.
You can sell subscription products with automated recurring billing at either of two intervals:
Billing continues indefinitely at the interval and price specified for the subscription. At each subscription renewal, Google Play charges the user account automatically, then notifies the user of the charges afterward by email. Billing cycles will always match subscription cycles, based on the purchase date.
Over the life of a subscription, the form of payment billed remains the same — Google Play always bills the same form of payment (such as credit card, Direct Carrier Billing) that was originally used to purchase the subscription.
When the subscription payment is approved by Google Wallet, Google Play provides a purchase token back to the purchasing app through the In-app Billing API. For details, see Purchase token, below. Your apps can store the token locally or pass it to your backend servers, which can then use it to validate or cancel the subscription remotely using the Google Play Android Developer API.
In the case of billing errors, such as could happen if the customer’s credit card becomes invalid, Google Play notifies your app of the change in purchase state.
As a best practice, we recommend that your app includes business logic to notify your backend servers of subscription purchases, tokens, and any billing errors that may occur. Your backend servers can use the server-side API to query and update your records and follow up with customers directly, if needed.
Users can view the status of all of their subscriptions and cancel them if necessary from the My Apps screen in the Play Store app. Currently, the In-app Billing API does not provide support for canceling subscriptions direct from inside the purchasing app, although your app can broadcast an Intent to launch the Play Store app directly to the My Apps screen.
When the user cancels a subscription, Google Play does not offer a refund for the current billing cycle. Instead, it allows the user to have access to the cancelled subscription until the end of the current billing cycle, at which time it terminates the subscription. For example, if a user purchases a monthly subscription and cancels it on the 15th day of the cycle, Google Play will consider the subscription valid until the end of the 30th day (or other day, depending on the month).
In some cases, the user may contact you directly to request cancellation of a subscription. In this and similar cases, you can use the server-side API to query and directly cancel the user’s subscription from your servers.
Important: In all cases, you must continue to offer the content that your subscribers have purchased through their subscriptions, for as long any users are able to access it. That is, you must not remove any subscriber’s content while any user still has an active subscription to it, even if that subscription will terminate at the end of the current billing cycle. Removing content that a subscriber is entitled to access will result in penalties. Please see the policies document for more information.
When the user uninstalls an app that includes purchased subscriptions, the Play Store app will notify the user that there are active subscriptions. If the user chooses to continue with the uninstalltion, the app is removed and the subscriptions remain active and recurring billing continues. The user can return to cancel the associated subscriptions at any time in the My Apps screen of the Play Store app. If the user chooses to cancel the uninstallation, the app and subscriptions remain as they were.
As with other in-app products, Google Play does not provide a refund window for subscription purchases. For example, users who purchase an app can ask for a refund from Google Play within a 15-minute window. With subscriptions, Google Play does not provide a refund window, so users will need to contact you directly to request a refund.
If you receive requests for refunds, you can use the server-side API to cancel the subscription or verify that it is already cancelled. However, keep in mind that Google Play considers cancelled subscriptions valid until the end of their current billing cycles, so even if you grant a refund and cancel the subscription, the user will still have access to the content.
Note: Partial refunds for canceled subscriptions are not available at this time.
In general, the terms of Google Play allow you to sell in-app subscriptions only through the standard payment processor, Google Wallet. For purchases of any subscription products, just as for other in-app products and apps, the transaction fee for subscriptions, just as for other in-app purchases, is the same as the transaction fee for application purchases (30%).
Apps published on Google Play that are selling subscriptions must use In-app Billing to handle the transaction and may not provide links to a purchase flow outside of the app and Google Play (such as to a web site).
For complete details about terms and policies, see the policies document.
In-app purchases of subscriptions are supported only on devices that meet these minimum requirements:
Google Play 3.5 and later versions include support for the In-app Billing v2 API or higher, which is needed to support handling of subscription products.
As noted in the previous section, support for subscriptions is available only on devices that meet the system requirements. Not all devices will receive or install Google Play 3.5, so not all users who install your apps will have access to the In-app Billing API and subscriptions.
If you are targeting older devices that run Android 2.1 or earlier, we recommend that you offer those users an alternative way buy the content that is available through subscriptions. For example, you could create standard in-app products (one-time purchases) that give access to similar content as your subscriptions, possibly for a longer interval such as a year.
Subscriptions are a standard In-app Billing product type. If you have already implemented In-app Billing for one-time purchase products, you will find that adding support for subscriptions is straightforward, with minimal impact on your code. If you are new to In-app Billing, you can implement subscriptions using the standard communication model, data structures, and user interactions as for other in-app products.subscriptions.
The full implementation details for In-app Billing are provided outside of this document, starting with the In-app Billing Overview. This document is focused on highlighting implementation details that are specific to subscriptions, along with some strategies for the associated billing and business models.
To help you get started with your In-app Billing implementation and subscriptions, an updated version of the In-app Billing sample app is available. You can download the sample app from the Android SDK repository using the Android SDK Manager. For details, see Downloading the Sample Application.
With subscriptions, your app uses the standard In-app Billing application model, sending billing requests to the Play Store application over interprocess communication (IPC) and receiving purchase responses from the Play Store app in the form of asynchronous broadcast intents. Your application does not manage any network connections between itself and the Google Play server or use any special APIs from the Android platform.
Your app also uses the standard In-app Billing components — a billing Service for sending requests, a BroadcastReceiver for receiving the responses, and a security component for verifying that the response was sent by Google Play. Also recommended are a response Handler for processing notifications, errors, and status messages, and an observer for sending callbacks to your application as needed. All of these components and their interactions are described in full in the In-app Billing Overview and related documents.
To initiate different types of billing communication with Google Play, your app will use the standard set of in-app billing requests and receive the same responses. Inside the requests and responses are two new fields described below.
Central to the end-to-end architecture for subscriptions is the purchase token, a string value that uniquely identifies (and associates) a user ID and a subscription ID. Google Play generates the purchase token when the user completes the purchase of a subscription product (and payment is approved by Google Wallet) and then sends it to the purchasing app on the device through the In-app Billing API.
At the conclusion of a PURCHASE_REQUEST
message flow, your app
can retrieve the purchase token and other transaction details by initiating a
GET_PURCHASE_INFORMATION
request. The Bundle returned by the call
contains an JSON array of order objects. In the order corresponding to the
subscription purchase, the token is available in the purchaseToken
field.
An example of a JSON order object that includes a subscription purchase token is shown below.
{ "nonce" : 1836535032137741465, "orders" : [{ "notificationId" : "android.test.purchased", "orderId" : "transactionId.android.test.purchased", "packageName" : "com.example.dungeons", "productId" : "android.test.purchased", "developerPayload" : "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ", "purchaseTime" : 1290114783411, "purchaseState" : 0, "purchaseToken" : "rojeslcdyyiapnqcynkjyyjh" }] }
After receiving a purchase token, your apps can store the token locally or pass it to your backend servers, which can then use it to query the billing status or cancel the subscription remotely. If your app will store the token locally, please read the Security and Design document for best practices for maintaining the security of your data.
Subscriptions support is available only in versions of Google Play that support the In-app Billing v2 API (Google Play 3.5 and higher). For your app, an essential first step at launch is to check whether the version of Google Play installed on the device supports the In-app Billing v2 API and subscriptions.
To do this, create a CHECK_BILLING_SUPPORTED request Bundle that includes the required key-value pairs, together with
API_VERSION
key, assigning a value of 2.BILLING_REQUEST_ITEM_TYPE
key, assigning a value of “subs”Send the request using sendBillingRequest(Bundle)
and receive
the response Bundle. You can extract the response from the
BILLING_RESPONSE_RESPONSE_CODE
key of the response. RESULT_OK
indicates that subscriptions are supported.
The sample app declares constants for the accepted
BILLING_REQUEST_ITEM_TYPE
values (from Consts.java):
// These are the types supported in the IAB v2 public static final String ITEM_TYPE_INAPP = "inapp"; public static final String ITEM_TYPE_SUBSCRIPTION = "subs";
It sets up a convenience method for building the request bundle (from BillingService.java):
protected Bundle makeRequestBundle(String method) {
Bundle request = new Bundle();
request.putString(Consts.BILLING_REQUEST_METHOD, method);
request.putInt(Consts.BILLING_REQUEST_API_VERSION
, 2);
request.putString(Consts.BILLING_REQUEST_PACKAGE_NAME, getPackageName());
return request;
}
Here’s an example of how to test support for In-App Billing v2 and subscriptions (from BillingService.java):
/** * Wrapper class that checks if in-app billing is supported. */ class CheckBillingSupported extends BillingRequest { public String mProductType = null; public CheckBillingSupported() { // This object is never created as a side effect of starting this // service so we pass -1 as the startId to indicate that we should // not stop this service after executing this request. super(-1); } public CheckBillingSupported(String type) { super(-1); mProductType = type; } @Override protected long run() throws RemoteException { Bundle request = makeRequestBundle("CHECK_BILLING_SUPPORTED"); if (mProductType != null) { request.putString(Consts.BILLING_REQUEST_ITEM_TYPE
, mProductType); } Bundle response = mService.sendBillingRequest(request); int responseCode = response.getInt(Consts.BILLING_RESPONSE_RESPONSE_CODE
); if (Consts.DEBUG) { Log.i(TAG, "CheckBillingSupported response code: " + ResponseCode.valueOf(responseCode)); } boolean billingSupported = (responseCode == ResponseCode.RESULT_OK.ordinal()); ResponseHandler.checkBillingSupportedResponse(billingSupported, mProductType); return Consts.BILLING_RESPONSE_INVALID_REQUEST_ID; } }
Once you’ve checked the API version as described above and determined that subscriptions are supported, you can present subscription products to the user for purchase. When the user has selected a subscription product and initiated a purchase, your app handles the purchase just as it would for other in-app products — by sending a REQUEST_PURCHASE request. You can then launch Google Play to display the checkout user interface and handle the financial transaction..
The REQUEST_PURCHASE includes a Bundle containing the item details, as described in the In-app Billing Overview. For a subscription, the Bundle must also specify:
ITEM_ID
key, with a value that specifies a valid, published
subscription product.ITEM_TYPE
key, with a value of “subs”
(ITEM_TYPE_SUBSCRIPTION
in the sample app). If the request does not
specify the subscription's ITEM_TYPE
, Google Play attempts to
handle the request as a standard in-app purchase (one-time purchase).Google Play synchronously returns a response bundle that includes
RESPONSE_CODE
, PURCHASE_INTENT
, and
REQUEST_ID
. Your app uses the PURCHASE_INTENT
to
launch the checkout UI and the message flow proceeds exactly as described in Messaging sequence.
Here’s how the sample app initiates a purchase for a subscription, where
mProductType
is ITEM_TYPE_SUBSCRIPTION
(from
BillingService.java).
/**
* Wrapper class that requests a purchase.
*/
class RequestPurchase extends BillingRequest {
public final String mProductId;
public final String mDeveloperPayload;
public final String mProductType;
. . .
@Override
protected long run() throws RemoteException {
Bundle request = makeRequestBundle("REQUEST_PURCHASE");
request.putString(Consts.BILLING_REQUEST_ITEM_ID, mProductId);
request.putString(Consts.BILLING_REQUEST_ITEM_TYPE
, mProductType);
// Note that the developer payload is optional.
if (mDeveloperPayload != null) {
request.putString(Consts.BILLING_REQUEST_DEVELOPER_PAYLOAD, mDeveloperPayload);
}
Bundle response = mService.sendBillingRequest(request);
PendingIntent pendingIntent
= response.getParcelable(Consts.BILLING_RESPONSE_PURCHASE_INTENT);
if (pendingIntent == null) {
Log.e(TAG, "Error with requestPurchase");
return Consts.BILLING_RESPONSE_INVALID_REQUEST_ID;
}
Intent intent = new Intent();
ResponseHandler.buyPageIntentResponse(pendingIntent, intent);
return response.getLong(Consts.BILLING_RESPONSE_REQUEST_ID,
Consts.BILLING_RESPONSE_INVALID_REQUEST_ID);
}
@Override
protected void responseCodeReceived(ResponseCode responseCode) {
ResponseHandler.responseCodeReceived(BillingService.this, this, responseCode);
}
}
Subscriptions always use the managed by user account purchase type, so that you can restore a record of subscription transactions on the device when needed. When a user installs your app onto a new device, or when the user uninstalls/reinstalls the app on the original device, your app should restore the subscriptions that the user has purchased.
The process for restoring subscriptions transactions is the same as described
in Messaging sequence. Your app sends a
RESTORE_TRANSACTIONS
request to Google Play. Google Play sends two
broadcast intents as asynchronous responses — a RESPONSE_CODE
intent and a PURCHASE_STATE_CHANGED
intent.
The PURCHASE_STATE_CHANGED
intent contains a notification ID
that your app can use to retrieve the purchase details, including the purchase
token, by sending a standard GET_PURCHASE_INFORMATION
request. The
Bundle
returned in the call includes an JSON array of order objects
corresponding to subscription (and in-app product) purchases that you can
restore locally.
Your app can store the restored purchase state and other transaction details in the way that best meets your needs. Your app can use it later to check the subscription validity, although please read the Security and Design document for best practices for maintaining the security of your data.
Subscriptions are time-bound purchases that require successful billing recurrences over time to remain valid. Your app should check the validity of purchased subscriptions at launch or prior to granting access to subscriber content.
With In-app Billing, you validate a subscription by keeping track of its purchase state, such as purchased or cancelled, and then checking the state whenever needed. Google Play provides two ways to let you know when the purchase state of a subscription changes:
purchaseToken
on your
backend servers. For more information, see Google Play
Android Developer API, below.For most use-cases, especially those where backend servers are already keeping track of subscribed users, implementing a combination of both methods is the recommended approach. A typical implementation might work like this:
If you are using both notifications and the Google Play Android Developer API to validate subscriptions, we recommend the following:
If necessary, you can also use a RESTORE_TRANSACTIONS
request to retrieve a record of all managed and in-app products purchased by the user, which you can then store locally. However, using RESTORE_TRANSACTIONS
on a regular basis is not recommended because of performance impacts.
Regardless of the approach you choose, your app should check subscriptions and validity at launch, such as prior to accessing subscriber content, game levels, and so on.
State | purchaseState Value | Comments |
---|---|---|
Purchased successfully | 0 | Sent at original purchase only (not at recurring billing cycles). | Cancelled | 1 | Sent at original purchase only if the purchase has failed for some reason. | Refunded | 2 | The purchase was refunded. | Subscription expired | 3 | Sent if a subscription expires because of non-payment or user cancelation. |
In-app Billing does not currently provide an API to let users directly view or cancel subscriptions from within the purchasing app. Instead, users can launch the Play Store app on their devices and go to the My Apps screen to manage subscriptions. In My Apps, users can see a list of their subscriptions organized by application. Tapping one of the subscriptions loads the app's product page, from which users can see active subscriptions and billing status and cancel subscriptions as needed.
To make it easier for users to find and manage their subscriptions from inside your app, we recommend that you offer a "View My Subscriptions" or "Manage Subscriptions" option in your UI that directly loads your app's product page in the Play Store app.
To do this, create an intent with the ACTION_VIEW
action and include the market://
URI (rather than the http://
URI) of your app's details page. Here’s an example:
Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("market://details?id=com.example.app")); startActivity(intent);
For more information, see Linking to Your Products.
Google Play notifies your app when the user completes the purchase of a subscription, but the purchase state does not change over time, provided that recurring billing takes place successfully. Google Play does not notify your app of a purchase state change until the subscription expires because of non-payment or user cancellation.
Over the life of a subscription, your app does not need to initiate any recurring billing events — those are all handled by Google Play and they are transparent to your application if billing is successful.
For subscriptions, you make the same types of modifications to your app as are described in Modifying your Application Code.
Note that, in your UI that lets users view and select subscriptions for purchase, you should add logic to check for purchased subscriptions and validate them. Your UI should not present subscriptions if the user has already purchased them.
To create and manage subscriptions, you use the tools in the Developer Console, just as for other in-app products.
At the Developer Console, you can configure these attributes for each subscription product:
For details, please see Administering In-app Billing.
Google Play offers an HTTP-based API that you can use to remotely query the validity of a specific subscription at any time or cancel a subscription. The API is designed to be used from your backend servers as a way of securely managing subscriptions, as well as extending and integrating subscriptions with other services.
To use the API, you must first register a project at the Google APIs Console and receive a Client ID and shared secret that your app will present when calling the Google Play Android Developer API. All calls to the API are authenticated with OAuth 2.0.
Once your app is registered, you can access the API directly, using standard HTTP methods to retrieve and manipulate resources, or you can use the Google APIs Client Libraries, which are extended to support the API.
The Google Play Android Developer API is built on a RESTful design that uses HTTP and JSON, so any standard web stack can send requests and parse the responses. However, if you don’t want to send HTTP requests and parse responses manually, you can access the API using the client libraries, which provide better language integration, improved security, and support for making calls that require user authorization.
For more information about the API and how to access it through the Google APIs Client Libraries, see the documentation at:
https://developers. google.com/android-publisher/v1/
Applications using the Google Play Android Developer API are limited to an initial courtesy usage quota of 15000 requests per day (per application). This should provide enough access for normal subscription-validation needs, assuming that you follow the recommendation in this section.
If you need to request a higher limit for your application, please use the “Request more” link in the Google APIs Console. Also, please read the section below on design best practices for minimizing your use of the API.
Calls to the Google Play Android Developer API require authorization. Google uses the OAuth 2.0 protocol to allow authorized applications to access user data. To learn more, see Authorization in the Google Play Android Developer API documentation.
Access to the Google Play Android Developer API is regulated to help ensure a high-performance environment for all applications that use it. While you can request a higher daily quota for your application, we highly recommend that you minimize your access using the technique(s) below.
By following those general guidelines, your implementation will offer the best possible performance for users and minimize use of the Google Play Android Developer API.