526 lines
31 KiB
Plaintext
526 lines
31 KiB
Plaintext
page.title=In-app Billing Version 2
|
|
excludeFromSuggestions=true
|
|
@jd:body
|
|
|
|
<p class="caution" style=
|
|
"background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">
|
|
The <strong>In-app Billing Version 2 API</strong> has been deprecated in
|
|
favor of the Version 3 API. If your app is using In-app Billing, please
|
|
<strong>make sure that it is using the Version 3 API</strong>. If your app is
|
|
still using the Version 2 API, you must <strong>migrate to the Version 3 API
|
|
as soon as possible</strong>.<br>
|
|
<br>
|
|
We plan to turn off the In-app Billing Version 2 service on <strong>January
|
|
27, 2015</strong>, after which time users will <strong>no longer be able to
|
|
purchase in-app items and subscriptions through the Version 2 API</strong>.
|
|
We strongly encourage and recommend you migrate your apps to use Version 3
|
|
API by November 2014, to provide ample time for users to update their apps to
|
|
the new version.<br>
|
|
<br>
|
|
For more information, please see the <a href=
|
|
"http://support.google.com/googleplay/android-developer/answer/6090268">Help Center
|
|
article</a>. For common questions about transitioning your implementation to
|
|
In-app Billing Version 3, please see <a href=
|
|
"{@docRoot}google/play/billing/billing_overview.html#migration">Migration
|
|
Considerations</a>.
|
|
</p>
|
|
<div id="qv-wrapper" style="margin-top:0;">
|
|
<div id="qv">
|
|
|
|
<h2>In this document</h2>
|
|
<ol>
|
|
<li><a href="#billing-types">Product and Purchase Types</a></li>
|
|
<li><a href="#billing-arch">Service Architecture</a></li>
|
|
<li><a href="#billing-msgs">Service Messages</a></li>
|
|
<ol>
|
|
<li><a href="#billing-request">Request messages</a></li>
|
|
<li><a href="#billing-response">Broadcast intents</a></li>
|
|
<li><a href="#billing-message-sequence">Messaging sequence</a></li>
|
|
<li><a href="#billing-action-notify">Handling IN_APP_NOTIFY messages</a></li>
|
|
</ol>
|
|
<li><a href="#billing-security">Security Controls</a></li>
|
|
<li><a href="#billing-limitations">Requirements and Limitations</a></li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
|
|
<p>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. </p>
|
|
|
|
<p>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. </p>
|
|
|
|
<h2 id="billing-types">Product Types</h2>
|
|
|
|
<p>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 <a
|
|
href="{@docRoot}google/play/billing/billing_admin.html">Administering In-app Billing</a>.</p>
|
|
|
|
<ul>
|
|
<li><em>Managed per user account</em> — Items that can be purchased only
|
|
once per user account on Google Play. When a user purchases an item that uses
|
|
the "managed per user account" product type, Google Play permanently stores the
|
|
transaction information for each item on a per-user basis. This enables you to
|
|
later query Google Play to restore the state of the items a specific user has
|
|
purchased. If a user attempts to purchase a managed item that has already been
|
|
purchased, Google Play prevents the user from purchasing the item again and
|
|
displays an "Item already purchased" error.
|
|
|
|
<p>The "managed" product type is useful if you are selling
|
|
items such as game levels or application features. These items are not transient
|
|
and usually need to be restored whenever a user reinstalls your application,
|
|
wipes the data on their device, or installs your application on a new
|
|
device.</p>
|
|
|
|
<li><em>Unmanaged</em> — Items that do not have their transaction
|
|
information stored on Google Play. This means that you cannot later query Google
|
|
Play to retrieve transaction information for those items. For "unmanaged"
|
|
purchases, you are responsible for managing the transaction information. Also,
|
|
Google Play does not attempt to prevent the user from purchasing an item
|
|
multiple times if it uses the "unmanaged" product type. It's up to you to
|
|
control how many times an unmanaged item can be purchased.</p>
|
|
|
|
<p>The "unmanaged" product type is useful if you are selling consumable items,
|
|
such as fuel or magic spells. These items are consumed within your application
|
|
and are usually purchased multiple times.</p></li>
|
|
|
|
<li><em>Subscriptions</em> — Items that are sold with a
|
|
developer-specified, recurring billing interval. When a user purchases a
|
|
subscription, Google Play and its payment processor automatically bill the
|
|
user's account at the specified interval and price, charging the amount to the
|
|
original payment method. Once the user purchases a subscription, Google Play
|
|
continues billing the account indefinitely, without requiring approval or action
|
|
from the user. The user can cancel the subscription at any time.
|
|
|
|
<p>Subscriptions can only be sold using the "managed per user account" purchase
|
|
type. As with in-app products, once the user has purchased an in-app product
|
|
there is no refund window. Users desiring refunds must contact the developer
|
|
directly. For more information about subscriptions and how to sell them in your
|
|
apps, see the <a href="{@docRoot}google/play/billing/v2/billing_subscriptions.html">Subscriptions</a>
|
|
document.</p></li>
|
|
</ul>
|
|
|
|
<h2 id="billing-arch">Service Architecture</h2>
|
|
|
|
<p>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.</p>
|
|
|
|
<div class="figure" style="width:440px">
|
|
<img src="/images/billing_arch.png" alt="" height="582" />
|
|
<p class="img-caption">
|
|
<strong>Figure 1.</strong> Your application sends and receives billing messages through the
|
|
Google Play application, which handles all communication with the Google Play server.</p>
|
|
</div>
|
|
|
|
<p>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.</p>
|
|
|
|
<p>A typical in-app billing implementation relies on three components:</p>
|
|
<ul>
|
|
<li>A {@link android.app.Service Service} (named <code>BillingService</code> in the sample application),
|
|
which processes purchase messages from the application and sends billing requests to the Google
|
|
Play in-app billing service.</li>
|
|
<li>A {@link android.content.BroadcastReceiver BroadcastReceiver} (named <code>BillingReceiver</code> in the sample
|
|
application), which receives all asynchronous billing responses from the Google Play
|
|
application.</li>
|
|
<li>A security component (named <code>Security</code> 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 <a href="#billing-security">Security controls</a> later in this
|
|
document.</li>
|
|
</ul>
|
|
|
|
<p>You may also want to incorporate two other components to support in-app billing:</p>
|
|
<ul>
|
|
<li>A response {@link android.os.Handler Handler} (named <code>ResponseHandler</code> in the sample
|
|
application), which provides application-specific processing of purchase notifications, errors,
|
|
and other status messages.</li>
|
|
<li>An observer (named <code>PurchaseObserver</code> 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.</li>
|
|
</ul>
|
|
|
|
<p>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.</p>
|
|
|
|
<h2 id="billing-msgs">In-app Billing Messages</h2>
|
|
|
|
<p>When the user initiates a purchase, your application sends billing messages to Google Play's
|
|
in-app billing service (named <code>MarketBillingService</code>) 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.</p>
|
|
|
|
<h3 id="billing-request">In-app billing requests</h3>
|
|
|
|
<p>Your application sends in-app billing requests by invoking a single IPC method
|
|
(<code>sendBillingRequest()</code>), which is exposed by the <code>MarketBillingService</code>
|
|
interface. This interface is defined in an <a
|
|
href="{@docRoot}guide/components/aidl.html">Android Interface Definition Language</a> file
|
|
(<code>IMarketBillingService.aidl</code>). You can <a
|
|
href="{@docRoot}google/play/billing/v2/billing_integrate.html#billing-download">download</a> this AIDL
|
|
file with the in-app billing sample application.</p>
|
|
|
|
<p>The <code>sendBillingRequest()</code> 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 <a
|
|
href="{@docRoot}google/play/billing/v2/billing_reference.html#billing-interface">In-app Billing
|
|
Service Interface</a>.
|
|
|
|
<p>One of the most important keys that every request Bundle must have is the
|
|
<code>BILLING_REQUEST</code> 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:</p>
|
|
|
|
<ul>
|
|
<li><code>CHECK_BILLING_SUPPORTED</code>
|
|
<p>This request verifies that the Google Play 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.</p>
|
|
</li>
|
|
<li><code>REQUEST_PURCHASE</code>
|
|
<p>This request sends a purchase message to the Google Play 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. Google Play then handles the financial transaction by displaying
|
|
the checkout user interface.</p>
|
|
</li>
|
|
<li><code>GET_PURCHASE_INFORMATION</code>
|
|
<p>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. Google Play notifies your
|
|
application when a purchase changes state, so you only need to send this request when there is
|
|
transaction information to retrieve.</p>
|
|
</li>
|
|
<li><code>CONFIRM_NOTIFICATIONS</code>
|
|
<p>This request acknowledges that your application received the details of a purchase state
|
|
change. Google Play sends purchase state change notifications to your application until you
|
|
confirm that you received them.</p>
|
|
</li>
|
|
<li><code>RESTORE_TRANSACTIONS</code>
|
|
<p>This request retrieves a user's transaction status for <a
|
|
href="{@docRoot}google/play/billing/billing_admin.html#billing-purchase-type">managed
|
|
purchases</a> and <a
|
|
href="{@docRoot}google/play/billing/billing_admin.html#billing-purchase-type">subscriptions</a>.
|
|
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.</p>
|
|
</li>
|
|
</ul>
|
|
|
|
<h3 id="billing-response">In-app Billing Responses</h3>
|
|
|
|
<p>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:</p>
|
|
|
|
<ul>
|
|
<li><code>RESPONSE_CODE</code>
|
|
<p>This key provides status information and error information about a request.</p>
|
|
</li>
|
|
<li><code>PURCHASE_INTENT</code>
|
|
<p>This key provides a {@link android.app.PendingIntent PendingIntent}, which you use to launch the checkout
|
|
activity.</p>
|
|
</li>
|
|
<li><code>REQUEST_ID</code>
|
|
<p>This key provides you with a request identifier, which you can use to match asynchronous
|
|
responses with requests.</p>
|
|
</li>
|
|
</ul>
|
|
<p>Some of these keys are not relevant to every request. For more information, see <a
|
|
href="#billing-message-sequence">Messaging sequence</a> later in this document.</p>
|
|
|
|
<p>The asynchronous response messages are sent in the form of individual broadcast intents and
|
|
include the following:</p>
|
|
|
|
<ul>
|
|
<li><code>com.android.vending.billing.RESPONSE_CODE</code>
|
|
<p>This response contains a Google Play 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 Google Play or it can indicate that some error occurred during a billing
|
|
request. This response is <em>not</em> 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 <a
|
|
href="{@docRoot}google/play/billing/v2/billing_reference.html#billing-codes">Server Response Codes
|
|
for In-app Billing</a>.</p>
|
|
</li>
|
|
<li><code>com.android.vending.billing.IN_APP_NOTIFY</code>
|
|
<p>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
|
|
<code>IN_APP_NOTIFY</code> broadcast intent, you send a <code>GET_PURCHASE_INFORMATION</code>
|
|
request with the notification IDs to retrieve message details.</p>
|
|
</li>
|
|
<li><code>com.android.vending.billing.PURCHASE_STATE_CHANGED</code>
|
|
<p>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.</p>
|
|
</li>
|
|
</ul>
|
|
|
|
<p>The JSON string that is returned with the <code>PURCHASE_STATE_CHANGED</code> 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:</p>
|
|
<pre class="no-pretty-print" style="color:black">{ "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" }]
|
|
}
|
|
</pre>
|
|
|
|
<p>For more information about the fields in this JSON string, see <a
|
|
href="{@docRoot}google/play/billing/v2/billing_reference.html#billing-intents">In-app Billing
|
|
Broadcast Intents</a>.</p>
|
|
|
|
<h3 id="billing-message-sequence">Messaging sequence</h3>
|
|
|
|
<p>The messaging sequence for a typical purchase request is shown in figure 2. Request types for
|
|
each <code>sendBillingRequest()</code> method are shown in <strong>bold</strong>, broadcast intents
|
|
are shown in <em>italic</em>. For clarity, figure 2 does not show the <code>RESPONSE_CODE</code>
|
|
broadcast intents that are sent for every request.</p>
|
|
|
|
<p>The basic message sequence for an in-app purchase request is as follows:</p>
|
|
|
|
<ol>
|
|
<li>Your application sends a purchase request (<code>REQUEST_PURCHASE</code> type), specifying a
|
|
product ID and other parameters.</li>
|
|
<li>The Google Play application sends your application a Bundle with the following keys:
|
|
<code>RESPONSE_CODE</code>, <code>PURCHASE_INTENT</code>, and <code>REQUEST_ID</code>. The
|
|
<code>PURCHASE_INTENT</code> key provides a {@link android.app.PendingIntent PendingIntent}, which your
|
|
application uses to start the checkout UI for the given product ID.</li>
|
|
<li>Your application launches the pending intent, which launches the checkout UI.
|
|
<p class="note"><strong>Note:</strong> You must launch the pending intent from an activity
|
|
context and not an application context.</p>
|
|
</li>
|
|
<li>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
|
|
<code>IN_APP_NOTIFY</code> broadcast intent). The notification message includes a notification ID,
|
|
which references the transaction.</li>
|
|
<li>Your application requests the transaction information by sending a
|
|
<code>GET_PURCHASE_STATE_CHANGED</code> request, specifying the notification ID for the
|
|
transaction.</li>
|
|
<li>The Google Play application sends a Bundle with a <code>RESPONSE_CODE</code> key and a
|
|
<code>REQUEST_ID</code> key.
|
|
<li>Google Play sends the transaction information to your application in a
|
|
<code>PURCHASE_STATE_CHANGED</code> broadcast intent.</li>
|
|
<li>Your application confirms that you received the transaction information for the given
|
|
notification ID by sending a confirmation message (<code>CONFIRM_NOTIFICATIONS</code> type),
|
|
specifying the notification ID for which you received transaction information.</li>
|
|
<li>The Google Play application sends your application a Bundle with a
|
|
<code>RESPONSE_CODE</code> key and a <code>REQUEST_ID</code> key.</li>
|
|
</ol>
|
|
|
|
<img src="/images/billing_request_purchase.png" height="231" id="figure2" />
|
|
<p class="img-caption">
|
|
<strong>Figure 2.</strong> Message sequence for a purchase request.
|
|
</p>
|
|
|
|
<p>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 <code>IN_APP_NOTIFY</code> messages for the transactions you have not
|
|
confirmed. As a best practice, you should not send a <code>CONFIRM_NOTIFICATIONS</code> 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 <code>IN_APP_NOTIFY</code> 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 <code>IN_APP_NOTIFY</code> messages that contain multiple orders.</p>
|
|
|
|
<p>The messaging sequence for a restore transaction request is shown in figure 3. Request types for
|
|
each <code>sendBillingRequest()</code> method are shown in <strong>bold</strong>, broadcast intents
|
|
are shown in <em>italic</em>. For clarity, figure 3 does not show the <code>RESPONSE_CODE</code>
|
|
broadcast intents that are sent for every request.</p>
|
|
|
|
<div class="figure" style="width:490px">
|
|
<img src="/images/billing_restore_transactions.png" alt="" height="168" />
|
|
<p class="img-caption">
|
|
<strong>Figure 3.</strong> Message sequence for a restore transactions request.
|
|
</p>
|
|
</div>
|
|
|
|
<p>The request triggers three responses. The first is a {@link android.os.Bundle Bundle} with a
|
|
<code>RESPONSE_CODE</code> key and a <code>REQUEST_ID</code> key. Next, the Google Play
|
|
application sends a <code>RESPONSE_CODE</code> broadcast intent, which provides status information
|
|
or error information about the request. As always, the <code>RESPONSE_CODE</code> message references
|
|
a specific request ID, so you can determine which request a <code>RESPONSE_CODE</code> message
|
|
pertains to.</p>
|
|
|
|
<p>The <code>RESTORE_TRANSACTIONS</code> request type also triggers a
|
|
<code>PURCHASE_STATE_CHANGED</code> 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 <code>CONFIRM_NOTIFICATIONS</code> message. </p>
|
|
|
|
<p class="note"><strong>Note:</strong> You should use the <code>RESTORE_TRANSACTIONS</code> 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.</p>
|
|
|
|
<p>The messaging sequence for checking whether in-app billing is supported is shown in figure 4. The
|
|
request type for the <code>sendBillingRequest()</code> method is shown in <strong>bold</strong>.</p>
|
|
|
|
<div class="figure" style="width:454px">
|
|
<img src="/images/billing_check_supported.png" alt="" height="168" />
|
|
<p class="img-caption">
|
|
<strong>Figure 4.</strong> Message sequence for checking whether in-app billing is supported.
|
|
</p>
|
|
</div>
|
|
|
|
<p>The synchronous response for a <code>CHECK_BILLING_SUPPORTED</code> request provides a Bundle
|
|
with a server response code. A <code>RESULT_OK</code> response code indicates that in-app billing
|
|
is supported; a <code>RESULT_BILLING_UNAVAILABLE</code> 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 <code>SERVER_ERROR</code> can also be returned, indicating that there was a problem with
|
|
the Google Play server.</p>
|
|
|
|
<h3 id="billing-action-notify">Handling IN_APP_NOTIFY messages</h3>
|
|
|
|
<p>Usually, your application receives an <code>IN_APP_NOTIFY</code> broadcast intent from Google
|
|
Play in response to a <code>REQUEST_PURCHASE</code> message (see figure 2). The
|
|
<code>IN_APP_NOTIFY</code> 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
|
|
<code>GET_PURCHASE_INFORMATION</code> request. Google Play responds with a
|
|
<code>PURCHASE_STATE_CHANGED</code> broadcast intent, which contains the details of the purchase
|
|
state change. Your application then sends a <code>CONFIRM_NOTIFICATIONS</code> message, informing
|
|
Google Play that you have received the purchase state change information.</p>
|
|
|
|
<p>In some special cases, you may receive multiple <code>IN_APP_NOTIFY</code> messages even though
|
|
you have confirmed receipt of the purchase information, or you may receive
|
|
<code>IN_APP_NOTIFY</code> messages for a purchase change even though you never initiated the
|
|
purchase. Your application must handle both of these special cases.</p>
|
|
|
|
<h4>Handling multiple IN_APP_NOTIFY messages</h4>
|
|
|
|
<p>When Google Play receives a <code>CONFIRM_NOTIFICATIONS</code> message for a given
|
|
<code>PURCHASE_STATE_CHANGED</code> message, it usually stops sending <code>IN_APP_NOTIFY</code>
|
|
intents for that <code>PURCHASE_STATE_CHANGED</code> message. Sometimes, however, Google
|
|
Play may send repeated <code>IN_APP_NOTIFY</code> intents for a
|
|
<code>PURCHASE_STATE_CHANGED</code> message even though your application has sent a
|
|
<code>CONFIRM_NOTIFICATIONS</code> message. This can occur if a device loses network connectivity
|
|
while you are sending the <code>CONFIRM_NOTIFICATIONS</code> message. In this case, Google Play
|
|
might not receive your <code>CONFIRM_NOTIFICATIONS</code> message and it could send multiple
|
|
<code>IN_APP_NOTIFY</code> messages until it receives acknowledgement that you received the
|
|
transaction message. Therefore, your application must be able to recognize that the subsequent
|
|
<code>IN_APP_NOTIFY</code> messages are for a previously processed transaction. You can do this by
|
|
checking the <code>orderID</code> that's contained in the JSON string because every transaction has
|
|
a unique <code>orderId</code>.</p>
|
|
|
|
<h4>Handling refunds and other unsolicited IN_APP_NOTIFY messages</h4>
|
|
|
|
<p>There are two cases where your application may receive <code>IN_APP_NOTIFY</code> broadcast
|
|
intents even though your application has not sent a <code>REQUEST_PURCHASE</code> message. Figure 5
|
|
shows the messaging sequence for both of these cases. Request types for each
|
|
<code>sendBillingRequest()</code> method are shown in <strong>bold</strong>, broadcast intents are
|
|
shown in <em>italic</em>. For clarity, figure 5 does not show the <code>RESPONSE_CODE</code>
|
|
broadcast intents that are sent for every request.</p>
|
|
|
|
<div class="figure" style="width:481px">
|
|
<img src="/images/billing_refund.png" alt="" height="189" />
|
|
<p class="img-caption">
|
|
<strong>Figure 5.</strong> Message sequence for refunds and other unsolicited
|
|
IN_APP_NOTIFY messages.</p>
|
|
</div>
|
|
|
|
<p>In the first case, your application may receive an <code>IN_APP_NOTIFY</code> 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 <code>IN_APP_NOTIFY</code>
|
|
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 <code>REQUEST_PURCHASE</code> message, so that ultimately your application
|
|
receives a <code>PURCHASE_STATE_CHANGED</code> 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."</p>
|
|
|
|
<p>In the second case, your application can receive an <code>IN_APP_NOTIFY</code> broadcast intent
|
|
when Google Play receives a refund notification from Google. In this case, Google
|
|
Play sends an <code>IN_APP_NOTIFY</code> message to your application. Your application can handle
|
|
this message the same way it handles responses from an application-initiated
|
|
<code>REQUEST_PURCHASE</code> message so that ultimately your application receives a
|
|
<code>PURCHASE_STATE_CHANGED</code> message that includes information about the item that has been
|
|
refunded. The refund information is included in the JSON string that accompanies the
|
|
<code>PURCHASE_STATE_CHANGED</code> broadcast intent. Also, the <code>purchaseState</code> field in
|
|
the JSON string is set to 2.</p>
|
|
|
|
<p class="caution"><strong>Important:</strong> You cannot use the API to
|
|
issue refunds or cancel in-app billing transactions. You must do this manually through your
|
|
Google payments merchant account. However, you can use the API to retrieve order
|
|
information.</p>
|
|
|
|
<h2 id="billing-security">Security Controls</h2>
|
|
|
|
<p>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 <code>PURCHASE_STATE_CHANGED</code>
|
|
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 <strong>Settings</strong>, in the License Key field.</p>
|
|
|
|
<p>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.</p>
|
|
|
|
<p>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 <code>GET_PURCHASE_INFORMATION</code> request and a <code>RESTORE_TRANSACTIONS</code>
|
|
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.</p>
|
|
|
|
<p>For more information about best practices for security and design, see <a
|
|
href="{@docRoot}google/play/billing/billing_best_practices.html">Security and Design</a>.</p>
|
|
|
|
<h2 id="billing-limitations">In-app Billing Requirements and Limitations</h2>
|
|
|
|
<p>Before you get started with in-app billing, be sure to review the following requirements and
|
|
limitations.</p>
|
|
|
|
<ul>
|
|
<li>In-app billing can be implemented only in applications that you publish through Google
|
|
Play.</li>
|
|
<li>You must have a Google payments Merchant account to use Google Play In-app Billing.</li>
|
|
<li>To support subscriptions, version 3.5 or higher of the Google Play app is required. </li>
|
|
<li>In-app Billing requires Android 1.6 (API level 4) or higher.</li>
|
|
<li>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.</li>
|
|
<li>Google Play does not provide any form of content delivery. You are responsible for
|
|
delivering the digital content that you sell in your applications.</li>
|
|
<li>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 Google Play server over
|
|
the network. </li>
|
|
</ul>
|