Overview of In-app Billing

This documentation provides an early look at the Android Market In-app Billing service. The documentation may change without notice.

The Android Market In-app Billing service is an Android Market feature that provides checkout processing for in-app purchases. To use the service, your application sends a billing request to the service for a specific in-app product. The service then handles all of the checkout details for the transaction, including requesting and validating the form of payment and processing the financial transaction. When the checkout process is complete, the service sends your application the purchase details, such as the order number, the order date and time, and the price paid. At no point does your application have to handle any financial transactions; that role is provided by the in-app billing service.

In-app Billing Architecture

In-app billing uses an asynchronous message loop to convey billing requests and billing responses between your application and the Android Market server. In practice, your application never directly communicates with the Android Market server (see figure 1). Instead, your application sends billing requests to the Android Market application over interprocess communication (IPC) and receives purchase responses from the Android Market application in the form of asynchronous broadcast intents. Your application does not manage any network connections between itself and the Android Market server or use any special APIs from the Android platform.

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.

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

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

  • A Service (named BillingService in the sample application), which processes purchase messages from the application and sends billing requests to the in-app billing service.
  • A BroadcastReceiver (named BillingReceiver in the sample application), which receives all asynchronous billing responses from the Android Market application.
  • A security component (named Security in the sample application), which performs security-related tasks, such as signature verification and nonce generation. For more information about in-app billing security, see Security controls later in this document.

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

  • A response Handler (named ResponseHandler in the sample application), which provides application-specific processing of purchase notifications, errors, and other status messages.
  • An observer (named PurchaseObserver in the sample application), which is responsible for sending callbacks to your application so you can update your user interface with purchase information and status.

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 Android Market 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 the in-app billing service (named MarketBillingService) using simple IPC method calls. The Android Market application responds to all billing requests synchronously, providing your application with status notifications and other information. The Android Market 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 Android Market 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 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 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. The in-app billing service supports the following five types of billing requests:

  • CHECK_BILLING_SUPPORTED

    This request verifies that the Android Market application supports in-app billing. You usually send this request when your application first starts up. This request is useful if you want to enable or disable certain UI features that are relevant only to in-app billing.

  • REQUEST_PURCHASE

    This request sends a purchase message to the Android Market application and is the foundation of in-app billing. You send this request when a user indicates that he or she wants to purchase an item in your application. Android Market then handles the financial transaction by displaying the checkout user interface.

  • GET_PURCHASE_INFORMATION

    This request retrieves the details of a purchase state change. A purchase changes state when a requested purchase is billed successfully or when a user cancels a transaction during checkout. It can also occur when a previous purchase is refunded. Android Market notifies your application when a purchase changes state, so you only need to send this request when there is transaction information to retrieve.

  • CONFIRM_NOTIFICATIONS

    This request acknowledges that your application received the details of a purchase state change. Android Market sends purchase state change notifications to your application until you confirm that you received them.

  • RESTORE_TRANSACTIONS

    This request retrieves a user's transaction status for managed purchases (see Choosing a Purchase Type for more information). You should send this request only when you need to retrieve a user's transaction status, which is usually only when your application is reinstalled or installed for the first time on a device.

In-app Billing Responses

The Android Market application responds to in-app billing requests with both synchronous and asynchronous responses. The synchronous response is a Bundle with the following three keys:

  • RESPONSE_CODE

    This key provides status information and error information about a request.

  • PURCHASE_INTENT

    This key provides a PendingIntent, which you use to launch the checkout activity.

  • REQUEST_ID

    This key provides you with a request identifier, which you can use to match asynchronous responses with requests.

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:

  • ACTION_RESPONSE_CODE

    This response contains an Android Market server response code, and is sent after you make an in-app billing request. A server response code can indicate that a billing request was successfully sent to Android Market or it can indicate that some error occurred during a billing request. This response is not used to report any purchase state changes (such as refund or purchase information). For more information about the response codes that are sent with this response, see Server Response Codes for In-app Billing.

  • ACTION_NOTIFY

    This response indicates that a purchase has changed state, which means a purchase succeeded, was canceled, or was refunded. This response contains one or more notification IDs. Each notification ID corresponds to a specific server-side message, and each messages contains information about one or more transactions. After your application receives an ACTION_NOTIFY broadcast intent, you send a GET_PURCHASE_INFORMATION request with the notification IDs to retrieve message details.

  • ACTION_PURCHASE_STATE_CHANGED

    This response contains detailed information about one or more transactions. The transaction information is contained in a JSON string. The JSON string is signed and the signature is sent to your application along with the JSON string (unencrypted). To help ensure the security of your in-app billing messages, your application can verify the signature of this JSON string.

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

The fields in the JSON string are described in the following table (see table 1):

Table 1. Description of JSON fields that are returned with an ACTION_PURCHASE_STATE_CHANGED intent.

Field Description
nonce A number used once. Your application generates the nonce and sends it with the GET_PURCHASE_INFORMATION request. Android Market sends the nonce back as part of the JSON string so you can verify the integrity of the message.
notificationId A unique identifier that is sent with an ACTION_NOTIFY broadcast intent. Each notificationId corresponds to a specify message that is waiting to be retrieved on the Android Market server. Your application sends back the notificationId with the GET_PURCHASE_INFORMATION message so Android Market can determine which messages you are retrieving.
orderId A unique order identifier for the transaction. This corresponds to the Google Checkout Order ID.
packageName The application package from which the purchase originated.
productId The item's product identifier. Every item has a product ID, which you must specify in the application's product list on the Android Market publisher site.
purchaseTime The time the product was purchased, in milliseconds since the epoch (Jan 1, 1970).
purchaseState The enum value for the purchase state, which indicates whether the purchase was successful, canceled, or refunded.
developerPayload A developer-specified string that is associated with an order. This field is returned in the JSON string that contains transaction information for an order. You can use this field to send information with an order. For example, you can use this field to send index keys with an order, which is useful if you are using a database to store purchase information. We recommend that you do not use this field to send data or content.

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, responses are shown in standard text. For clarity, Figure 2 does not show the ACTION_RESPONSE_CODE broadcast intents that are sent for every request. These responses provide status information or error information and are returned after each 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 Android Market application sends your application a Bundle with a RESPONSE_CODE, PURCHASE_INTENT, and REQUEST_ID. The PURCHASE_INTENT provides a PendingIntent, which your application uses to start the checkout flow for the given product ID.
  3. Your application launches the pending intent, which launches the checkout UI.
  4. When the checkout flow finishes (that is, the user successfully purchases the item or cancels the purchase), Android Market sends your application a notification message (an ACTION_NOTIFY intent). The notification message includes a notification ID, which references the completed 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 Android Market application sends a Bundle with a RESPONSE_CODE and a REQUEST_ID.
  7. Android Market sends the transaction information to your application in an ACTION_PURCHASE_STATE_CHANGED 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 Android Market applications sends your application a Bundle with a RESPONSE_CODE and a REQUEST_ID.

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

Figure 2. Message sequence for a typical purchase request. Request types for each sendBillingRequest() method are shown in bold (ACTION_RESPONSE_CODE broadcast intents have been omitted).

The messaging sequence for a restore transaction request is shown in Figure 3. The request type for the sendBillingRequest() method is shown in bold, the responses are shown in standard text.

Figure 3. Message sequence for a restore transactions request.

The request triggers three responses. The first is a Bundle with a RESPONSE_CODE and a REQUEST_ID. Next, the Android Market application sends an ACTION_RESPONSE_CODE broadcast intent, which provides status information or error information about the request. As always, the ACTION_RESPONSE_CODE message references a specific request ID, so you can determine which request an ACTION_RESPONSE_CODE message pertains to.

The RESTORE_TRANSACTIONS request type also triggers an ACTION_PURCHASE_STATE_CHANGED broadcast intent, which contains the same type of transaction information that is sent during a purchase request, although you do not need to respond to this intent with a CONFIRM_NOTIFICATIONS message.

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, the response is shown in regular text.

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

The synchronous response for a CHECK_BILLING_SUPPORTED request provides a server response code. A RESULT_OK response code indicates that in-app billing is supported; a RESULT_BILLING_UNAVAILABLE response code indicates that the Android Market application does not support in-app billing and may need to be updated. A SERVER_ERROR can also be returned, indicating that there was a problem with the Android Market server. The RESULT_BILLING_UNAVAILABLE response code can also indicate that the user is ineligible for in-app billing (for example, the user resides in a country that does not allow in-app billing).

Handling ACTION_NOTIFY messages

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

When Android Market receives a CONFIRM_NOTIFICATIONS message for a given message, it usually stops sending ACTION_NOTIFY intents for that message. However, there are some cases where Android Market may send repeated ACTION_NOTIFY intents for a 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, Android Market might not receive your CONFIRM_NOTIFICATIONS message and it could send multiple ACTION_NOTIFY messages until it receives acknowledgement that you received the message. Therefore, your application must be able to recognize that the subsequent ACTION_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.

Your application may also receive ACTION_NOTIFY intents even though your application has not sent a REQUEST_PURCHASE message. This can occur 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, Android Market sends an ACTION_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 change message that includes information about the item that's been purchased. This scenario applies only to items that have their purchase type set to "managed per user account."

Security Controls

To help ensure the integrity of the transaction information that is sent to your application, Android Market signs the JSON string that is contained in the ACTION_PURCHASE_STATE_CHANGED broadcast intent. Android Market uses the private key that is associated with your publisher account to create this signature. The publisher site generates an RSA key pair for each publisher account. You can find the public key portion of this key pair on your account's profile page. It is the same public key that is used with Android Market licensing.

When Android Market 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 Android Market. Your application must generate a nonce and send it with a GET_PURCHASE_INFORMATION request and a RESTORE_TRANSACTIONS request. When Android Market 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.

  • In-app billing can be implemented only in applications that you publish through Android Market.
  • You must have a Google Checkout merchant account to use the in-app billing service.
  • An application can use in-app billing only if the current Android Market application is installed on its host device and the device is running Android 1.6 (API level 4) or higher.
  • A device must be running version 2.3.0 (or higher) of the Android Market application to support in-app billing.
  • You can use in-app billing to sell only digital content. You cannot use in-app billing to sell physical goods, personal services, or anything that requires physical delivery.
  • Android Market does not provide any form of content delivery. You are responsible for delivering the digital content that you sell in your applications.
  • You cannot implement in-app billing on a device that never connects to the network. To complete in-app purchase requests, a device must be able to access the Android Market server over the network.
↑ Go to top