page.title=In-app Billing Version 2 excludeFromSuggestions=true @jd:body
In-app Billing Version 2 is superseded. Please migrate to Version 3 at your earliest convenience.

In this document

  1. Product and Purchase Types
  2. Service Architecture
  3. Service Messages
    1. Request messages
    2. Broadcast intents
    3. Messaging sequence
    4. Handling IN_APP_NOTIFY messages
  4. Security Controls
  5. Requirements and Limitations

In-app Billing version 2 is the legacy version of the Google Play In-app Billing. Like Version 3, it lets you interact with the Google Play purchase flow and payments system indirectly, by means of IPC communication with the Play Store app installed on the device.

Unlike Version 3, the Version 2 API is asynchronous and uses service messages sent as broadcast intents, so it is more complicated than Version 3.

Version 2 supports both unmanaged and managed products, as well as supports subscriptions, where Version 3 does not yet offer support for subscriptions. If you want to sell subscriptions in your app, you should implement In-app Billing Version 2, rather than Version 3.

If you do not need to sell subscriptions, you should implement In-app Billing Version 3 instead.

Product Types

In-app Billing Version supports three different product types to give you flexibility in how you monetize your app. In all cases, you define your products using the Google Play Developer Console, including product type, SKU, price, description, and so on. For more information, see Administering In-app Billing.

Service Architecture

Your app accesses the In-app Billing service using an API that is exposed by the Google Play app installed on the device. The Google Play app then uses an asynchronous message loop to convey billing requests and responses between your application and the Google Play server. In practice, your application never directly communicates with the Google Play server (see figure 1). Instead, your application sends billing requests to the Google Play application over interprocess communication (IPC) and receives purchase responses from the Google Play application 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.

Figure 1. Your application sends and receives billing messages through the Google Play application, which handles all communication with the Google Play server.

Some in-app billing implementations may also use a private remote server to deliver content or validate transactions, but a remote server is not required to implement in-app billing. A remote server can be useful if you are selling digital content that needs to be delivered to a user's device, such as media files or photos. You might also use a remote server to store users' transaction history or perform various in-app billing security tasks, such as signature verification. Although you can handle all security-related tasks in your application, performing those tasks on a remote server is recommended because it helps make your application less vulnerable to security attacks.

A typical in-app billing implementation relies on three components:

You may also want to incorporate two other components to support in-app billing:

In addition to these components, your application must provide a way to store information about users' purchases and some sort of user interface that lets users select items to purchase. You do not need to provide a checkout user interface. When a user initiates an in-app purchase, the Google Play application presents the checkout user interface to your user. When the user completes the checkout process, your application resumes.

In-app Billing Messages

When the user initiates a purchase, your application sends billing messages to Google Play's in-app billing service (named MarketBillingService) using simple IPC method calls. The Google Play application responds to all billing requests synchronously, providing your application with status notifications and other information. The Google Play application also responds to some billing requests asynchronously, providing your application with error messages and detailed transaction information. The following section describes the basic request-response messaging that takes place between your application and the Google Play application.

In-app billing requests

Your application sends in-app billing requests by invoking a single IPC method (sendBillingRequest()), which is exposed by the MarketBillingService interface. This interface is defined in an Android Interface Definition Language file (IMarketBillingService.aidl). You can download this AIDL file with the in-app billing sample application.

The sendBillingRequest() method has a single {@link android.os.Bundle Bundle} parameter. The Bundle that you deliver must include several key-value pairs that specify various parameters for the request, such as the type of billing request you are making, the item that is being purchased and its type, and the application that is making the request. For more information about the Bundle keys that are sent with a request, see In-app Billing Service Interface.

One of the most important keys that every request Bundle must have is the BILLING_REQUEST key. This key lets you specify the type of billing request you are making. Google Play's in-app billing service supports the following five types of billing requests:

In-app Billing Responses

The Google Play application responds to in-app billing requests with both synchronous and asynchronous responses. The synchronous response is a {@link android.os.Bundle Bundle} with the following three keys:

Some of these keys are not relevant to every request. For more information, see Messaging sequence later in this document.

The asynchronous response messages are sent in the form of individual broadcast intents and include the following:

The JSON string that is returned with the PURCHASE_STATE_CHANGED intent provides your application with the details of one or more billing transactions. An example of this JSON string for a subscription item 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" }]
}

For more information about the fields in this JSON string, see In-app Billing Broadcast Intents.

Messaging sequence

The messaging sequence for a typical purchase request is shown in figure 2. Request types for each sendBillingRequest() method are shown in bold, broadcast intents are shown in italic. For clarity, figure 2 does not show the RESPONSE_CODE broadcast intents that are sent for every request.

The basic message sequence for an in-app purchase request is as follows:

  1. Your application sends a purchase request (REQUEST_PURCHASE type), specifying a product ID and other parameters.
  2. The Google Play application sends your application a Bundle with the following keys: RESPONSE_CODE, PURCHASE_INTENT, and REQUEST_ID. The PURCHASE_INTENT key provides a {@link android.app.PendingIntent PendingIntent}, which your application uses to start the checkout UI for the given product ID.
  3. Your application launches the pending intent, which launches the checkout UI.

    Note: You must launch the pending intent from an activity context and not an application context.

  4. When the checkout flow finishes (that is, the user successfully purchases the item or cancels the purchase), Google Play sends your application a notification message (an IN_APP_NOTIFY broadcast intent). The notification message includes a notification ID, which references the transaction.
  5. Your application requests the transaction information by sending a GET_PURCHASE_STATE_CHANGED request, specifying the notification ID for the transaction.
  6. The Google Play application sends a Bundle with a RESPONSE_CODE key and a REQUEST_ID key.
  7. Google Play sends the transaction information to your application in a PURCHASE_STATE_CHANGED broadcast intent.
  8. Your application confirms that you received the transaction information for the given notification ID by sending a confirmation message (CONFIRM_NOTIFICATIONS type), specifying the notification ID for which you received transaction information.
  9. The Google Play application sends your application a Bundle with a RESPONSE_CODE key and a REQUEST_ID key.

Figure 2. Message sequence for a purchase request.

Keep in mind, you must send a confirmation when you receive transaction information from Google Play (step 8 in figure 2). If you don't send a confirmation message, Google Play will continue sending IN_APP_NOTIFY messages for the transactions you have not confirmed. As a best practice, you should not send a CONFIRM_NOTIFICATIONS request for a purchased item until you have delivered the item to the user. This way, if your application crashes or something else prevents your application from delivering the product, your application will still receive an IN_APP_NOTIFY broadcast intent from Google Play indicating that you need to deliver the product. Also, as a best practice, your application must be able to handle IN_APP_NOTIFY messages that contain multiple orders.

The messaging sequence for a restore transaction request is shown in figure 3. Request types for each sendBillingRequest() method are shown in bold, broadcast intents are shown in italic. For clarity, figure 3 does not show the RESPONSE_CODE broadcast intents that are sent for every request.

Figure 3. Message sequence for a restore transactions request.

The request triggers three responses. The first is a {@link android.os.Bundle Bundle} with a RESPONSE_CODE key and a REQUEST_ID key. Next, the Google Play application sends a RESPONSE_CODE broadcast intent, which provides status information or error information about the request. As always, the RESPONSE_CODE message references a specific request ID, so you can determine which request a RESPONSE_CODE message pertains to.

The RESTORE_TRANSACTIONS request type also triggers a PURCHASE_STATE_CHANGED broadcast intent, which contains the same type of transaction information that is sent during a purchase request. Unlike with a purchase request, however, the transactions are given without any associated notification IDs, so you do not need to respond to this intent with a CONFIRM_NOTIFICATIONS message.

Note: You should use the RESTORE_TRANSACTIONS request type only when your application is installed for the first time on a device or when your application has been removed from a device and reinstalled.

The messaging sequence for checking whether in-app billing is supported is shown in figure 4. The request type for the sendBillingRequest() method is shown in bold.

Figure 4. Message sequence for checking whether in-app billing is supported.

The synchronous response for a CHECK_BILLING_SUPPORTED request provides a Bundle with a server response code. A RESULT_OK response code indicates that in-app billing is supported; a RESULT_BILLING_UNAVAILABLE response code indicates that in-app billing is unavailable because the API version you specified is unrecognized or the user is not eligible to make in-app purchases (for example, the user resides in a country that does not allow in-app billing). A SERVER_ERROR can also be returned, indicating that there was a problem with the Google Play server.

Handling IN_APP_NOTIFY messages

Usually, your application receives an IN_APP_NOTIFY broadcast intent from Google Play in response to a REQUEST_PURCHASE message (see figure 2). The IN_APP_NOTIFY broadcast intent informs your application that the state of a requested purchase has changed. To retrieve the details of that purchase, your application sends a GET_PURCHASE_INFORMATION request. Google Play responds with a PURCHASE_STATE_CHANGED broadcast intent, which contains the details of the purchase state change. Your application then sends a CONFIRM_NOTIFICATIONS message, informing Google Play that you have received the purchase state change information.

In some special cases, you may receive multiple IN_APP_NOTIFY messages even though you have confirmed receipt of the purchase information, or you may receive IN_APP_NOTIFY messages for a purchase change even though you never initiated the purchase. Your application must handle both of these special cases.

Handling multiple IN_APP_NOTIFY messages

When Google Play receives a CONFIRM_NOTIFICATIONS message for a given PURCHASE_STATE_CHANGED message, it usually stops sending IN_APP_NOTIFY intents for that PURCHASE_STATE_CHANGED message. Sometimes, however, Google Play may send repeated IN_APP_NOTIFY intents for a PURCHASE_STATE_CHANGED message even though your application has sent a CONFIRM_NOTIFICATIONS message. This can occur if a device loses network connectivity while you are sending the CONFIRM_NOTIFICATIONS message. In this case, Google Play might not receive your CONFIRM_NOTIFICATIONS message and it could send multiple IN_APP_NOTIFY messages until it receives acknowledgement that you received the transaction message. Therefore, your application must be able to recognize that the subsequent IN_APP_NOTIFY messages are for a previously processed transaction. You can do this by checking the orderID that's contained in the JSON string because every transaction has a unique orderId.

Handling refunds and other unsolicited IN_APP_NOTIFY messages

There are two cases where your application may receive IN_APP_NOTIFY broadcast intents even though your application has not sent a REQUEST_PURCHASE message. Figure 5 shows the messaging sequence for both of these cases. Request types for each sendBillingRequest() method are shown in bold, broadcast intents are shown in italic. For clarity, figure 5 does not show the RESPONSE_CODE broadcast intents that are sent for every request.

Figure 5. Message sequence for refunds and other unsolicited IN_APP_NOTIFY messages.

In the first case, your application may receive an IN_APP_NOTIFY broadcast intent when a user has your application installed on two (or more) devices and the user makes an in-app purchase from one of the devices. In this case, Google Play sends an IN_APP_NOTIFY message to the second device, informing the application that there is a purchase state change. Your application can handle this message the same way it handles the response from an application-initiated REQUEST_PURCHASE message, so that ultimately your application receives a PURCHASE_STATE_CHANGED broadcast intent message that includes information about the item that has been purchased. This applies only to items that have their product type set to "managed per user account."

In the second case, your application can receive an IN_APP_NOTIFY broadcast intent when Google Play receives a refund notification from Google Wallet. In this case, Google Play sends an IN_APP_NOTIFY message to your application. Your application can handle this message the same way it handles responses from an application-initiated REQUEST_PURCHASE message so that ultimately your application receives a PURCHASE_STATE_CHANGED message that includes information about the item that has been refunded. The refund information is included in the JSON string that accompanies the PURCHASE_STATE_CHANGED broadcast intent. Also, the purchaseState field in the JSON string is set to 2.

Important: You cannot use the Google Wallet API to issue refunds or cancel in-app billing transactions. You must do this manually through your Google Wallet merchant account. However, you can use the Google Wallet API to retrieve order information.

Security Controls

To help ensure the integrity of the transaction information that is sent to your application, Google Play signs the JSON string that is contained in the PURCHASE_STATE_CHANGED broadcast intent. Google Play uses the private key that is associated with the app to create this signature. The Developer Console generates an RSA key pair for each app. You can find the public key portion of this key pair in the app's publishing details in the Developer Console, under Settings, in the License Key field.

When Google Play signs a billing response, it includes the signed JSON string (unencrypted) and the signature. 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 help detect 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 then we recommend that you perform the signature verification on that server.

In-app billing also uses nonces (a random number used once) to help verify the integrity of the purchase information that's returned from Google Play. Your application must generate a nonce and send it with a GET_PURCHASE_INFORMATION request and a RESTORE_TRANSACTIONS request. When Google Play receives the request, it adds the nonce to the JSON string that contains the transaction information. The JSON string is then signed and returned to your application. When your application receives the JSON string, you need to verify the nonce as well as the signature of the JSON string.

For more information about best practices for security and design, see Security and Design.

In-app Billing Requirements and Limitations

Before you get started with in-app billing, be sure to review the following requirements and limitations.