Merge "docs: Removing IAB v2 API docs" into mnc-docs

This commit is contained in:
Andrew Solovay
2015-10-07 17:52:48 +00:00
committed by Android (Google) Code Review
8 changed files with 7 additions and 2580 deletions

View File

@@ -17,17 +17,7 @@
<span class="en">Reference</span></a></li>
</ul>
</li>
<li class="nav-section"><div class="nav-section-header"><a href="<?cs var:toroot?>google/play/billing/v2/api.html">
<span class="en">Version 2 API</span></a></div>
<ul>
<li><a href="<?cs var:toroot?>google/play/billing/v2/billing_integrate.html">
<span class="en">Implementing the API</span></a></li>
<li><a href="<?cs var:toroot?>google/play/billing/v2/billing_subscriptions.html">
<span class="en">Subscriptions</span></a></li>
<li><a href="<?cs var:toroot?>google/play/billing/v2/billing_reference.html">
<span class="en">Reference</span></a></li>
</ul>
</li>
<li><a href="<?cs var:toroot?>google/play/billing/billing_subscriptions.html">
<span class="en">Subscriptions</span></a>
</li>

View File

@@ -160,7 +160,7 @@ code in your application before you publish it. For more information, see
and Design</a>.</p>
<h2 id="migration">Migration Considerations</h2>
<p>The In-app Billing Version 2 API is deprecated and will be discontinued in January 2015.
<p>The In-app Billing Version 2 API was discontinued in January 2015.
If you have an existing In-app Billing implementation that uses API Version 2 or
earlier, you must migrate to <a href="{@docRoot}google/play/billing/api.html">In-app Billing Version
3</a>.</p>
@@ -173,8 +173,7 @@ work with Version 3 as before.</li>
treated as managed products if you make a purchase request for these items using
the Version 3 API. You do not need to create a new product entry in Developer
Console for these items, and you can use the same product IDs to purchase these
items. They will still continue to be treated as unmanaged items if you make a
purchase request for them using the Version 2 or earlier API.
items.
</ul>

View File

@@ -199,15 +199,8 @@ which can then use it to validate or cancel the subscription remotely using the
href="{@docRoot}google/play/developer-api.html">Google Play Developer API</a>.</p>
<p>If a recurring payment fails (for example, because the customer’s credit
card has become invalid), the subscription does not renew. How your app is
notified depends on the In-app Billing API version that you are using:</p>
<ul>
<li>With In-app Billing Version 3, the failed or expired subscription is no longer
returned when you call {@code getPurchases}.</li>
<li>With In-app Billing Version 2, Google Play notifies your app at the end of
the active cycle that the purchase state of the subscription is now "Expired".
</li>
</ul>
card has become invalid), the subscription does not renew. The {@code
getPurchases()} method does not return failed or expired subscriptions.</p>
<p class="note"><strong>Recommendation</strong>: Include business logic in your
app to notify your backend servers of subscription purchases, tokens, and any

View File

@@ -24,8 +24,8 @@ and features, and more. You can use In-app Billing to sell products as</p>
period.</li>
<li><strong>IAB Sandbox</strong>&mdash;The In-app Billing Sandbox now supports
testing subscription purchases.</li>
<li><strong>IAB v2 shutdown</strong>&mdash;In-app Billing v2 API is deprecated
and will be shut down in January 2015. If your app is still using In-app Billing
<li><strong>As of January 2015, the In-App Billing v2 API is shut down.
If your app is still using In-app Billing
v2, please migrate to the v3 API as soon as possible.</li>
<li><strong>Seasonal subscriptions</strong>&mdash;You can now set up a
recurring <a href="billing_subscriptions.html#user-billing">seasonal

View File

@@ -1,525 +0,0 @@
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> &mdash; 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> &mdash; 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> &mdash; 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>

File diff suppressed because it is too large Load Diff

View File

@@ -1,437 +0,0 @@
page.title=In-app Billing Reference <span style="font-size:16px;">(IAB Version 2)</span>
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-codes">Server Response Codes</a></li>
<li><a href="#billing-interface">API Reference</a></li>
<li><a href="#billing-intents">Broadcast Intents</a></li>
<li><a href="#http-api">REST API for Subscriptions</a></li>
</ol>
<h2>Related Samples</h2>
<ol>
<li><a href="{@docRoot}google/play/billing/v2/billing_integrate.html#billing-download">Sample
Application (V2)</a></li>
</ol>
</div>
</div>
<p>This documentation provides technical reference information for using the In-app Billing Version 2 API. </p>
<h2 id="billing-codes">Server Response Codes</h2>
<p>The following table lists all of the server response codes that are sent from Google Play to
your application. Google Play sends these response codes asynchronously as
<code>response_code</code> extras in the <code>com.android.vending.billing.RESPONSE_CODE</code>
broadcast intent. Your application must handle all of these response codes.</p>
<p class="table-caption" id="response-codes-table"><strong>Table 6.</strong> Summary of response
codes returned by Google Play.</p>
<table>
<tr>
<th>Response Code</th>
<th>Value</th>
<th>Description</th>
</tr>
<tr>
<td><code>RESULT_OK</code></td>
<td>0</td>
<td>Indicates that the request was sent to the server successfully. When this code is returned in
response to a <code>CHECK_BILLING_SUPPORTED</code> request, indicates that billing is
supported.</td>
</tr>
<tr>
<td><code>RESULT_USER_CANCELED</code></td>
<td>1</td>
<td>Indicates that the user pressed the back button on the checkout page instead of buying the
item.</td>
</tr>
<tr>
<td><code>RESULT_SERVICE_UNAVAILABLE</code></td>
<td>2</td>
<td>Indicates that the network connection is down.</td>
</tr>
<tr>
<td><code>RESULT_BILLING_UNAVAILABLE</code></td>
<td>3</td>
<td>Indicates that In-app Billing is not available because the <code>API_VERSION</code> that you
specified is not recognized by the Google Play application or the user is ineligible for in-app
billing (for example, the user resides in a country that prohibits in-app purchases).</td>
</tr>
<tr>
<td><code>RESULT_ITEM_UNAVAILABLE</code></td>
<td>4</td>
<td>Indicates that Google Play cannot find the requested item in the application's product
list. This can happen if the product ID is misspelled in your <code>REQUEST_PURCHASE</code>
request or if an item is unpublished in the application's product list.</td>
</tr>
<tr>
<td><code>RESULT_DEVELOPER_ERROR</code></td>
<td>5</td>
<td>Indicates that an application is trying to make an In-app Billing request but the application
has not declared the com.android.vending.BILLING permission in its manifest. Can also indicate
that an application is not properly signed, or that you sent a malformed request, such as a
request with missing Bundle keys or a request that uses an unrecognized request type.</td>
</tr>
<tr>
<td><code>RESULT_ERROR</code></td>
<td>6</td>
<td>Indicates an unexpected server error. For example, this error is triggered if you try to
purchase an item from yourself, which is not allowed.</td>
</tr>
</table>
</p>
<h3 id="billing-interface">In-app billing Version 2 API reference</h3>
<p>The following section describes the interface for Google Play's In-app Billing service. The
interface is defined in the <code>IMarketBillingService.aidl</code> file, which is included with the
In-app Billing <a
href="{@docRoot}google/play/billing/v2/billing_integrate.html#billing-download">sample
application</a>.</p>
<p>The interface consists of a single request method <code>sendBillingRequest()</code>. This method
takes a single {@link android.os.Bundle} parameter. The Bundle parameter includes several key-value
pairs, which are summarized in table 7.</p>
<p class="table-caption"><strong>Table 7.</strong> Description of Bundle keys passed in a
<code>sendBillingRequest()</code> request.</p>
<table>
<tr>
<th>Key</th>
<th>Type</th>
<th>Possible Values</th>
<th>Required?</th>
<th>Description</th>
</tr>
<tr>
<td><code>BILLING_REQUEST</code></td>
<td><code>String</code></td>
<td><code>CHECK_BILLING_SUPPORTED</code>, <code>REQUEST_PURCHASE</code>,
<code>GET_PURCHASE_INFORMATION</code>, <code>CONFIRM_NOTIFICATIONS</code>, or
<code>RESTORE_TRANSACTIONS</code></td>
<td>Yes</td>
<td>The type of billing request you are making with the <code>sendBillingRequest()</code> request.
The possible values are discussed more below this table.</td>
</tr>
<tr>
<td><code>API_VERSION</code></td>
<td><code>int</code></td>
<td> <ul>
<li><code>"2"</code> [<a href="#version_2">details</a>]</li>
<li><code>"1"</code> [<a href="#version_1">details</a>]</li>
</ul></td>
<td>Yes</td>
<td>The version of Google Play's In-app Billing service you want to use.</td>
</tr>
<tr>
<td><code>PACKAGE_NAME</code></td>
<td><code>String</code></td>
<td>A valid package name.</td>
<td>Yes</td>
<td>The name of the application that is making the request.</td>
</tr>
<tr>
<td><code>ITEM_ID</code></td>
<td><code>String</code></td>
<td>Any valid product identifier.</td>
<td>Required for <code>REQUEST_PURCHASE</code> requests.</td>
<td>The product ID of the item you are making a billing request for. Every in-app item that you
sell using Google Play's In-app Billing service must have a unique product ID, which you
specify on the Google Play Developer Console.</td>
</tr>
<tr>
<td><code>NONCE</code></td>
<td><code>long</code></td>
<td>Any valid <code>long</code> value.</td>
<td>Required for <code>GET_PURCHASE_INFORMATION</code> and <code>RESTORE_TRANSACTIONS</code>
requests.</td>
<td>A number used once. Your application must generate and send a nonce with each
<code>GET_PURCHASE_INFORMATION</code> and <code>RESTORE_TRANSACTIONS</code> request. The nonce is
returned with the <code>PURCHASE_STATE_CHANGED</code> broadcast intent, so you can use this value
to verify the integrity of transaction responses form Google Play.</td>
</tr>
<tr>
<td><code>NOTIFY_IDS</code></td>
<td>Array of <code>long</code> values</td>
<td>Any valid array of <code>long</code> values</td>
<td>Required for <code>GET_PURCHASE_INFORMATION</code> and <code>CONFIRM_NOTIFICATIONS</code>
requests.</td>
<td>An array of notification identifiers. A notification ID is sent to your application in an
<code>IN_APP_NOTIFY</code> broadcast intent every time a purchase changes state. You use the
notification to retrieve the details of the purchase state change.</td>
</tr>
<tr>
<td><code>DEVELOPER_PAYLOAD</code></td>
<td><code>String</code></td>
<td>Any valid <code>String</code> less than 256 characters long.</td>
<td>No</td>
<td>A developer-specified string that can be specified when you make a
<code>REQUEST_PURCHASE</code> request. This field is returned in the JSON string that contains
transaction information for an order. You can use this key to send supplemental information with
an order. For example, you can use this key 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 key
to send data or content.</td>
</tr>
</table>
<p>The <code>BILLING_REQUEST</code> key can have the following values:</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 state change can
occur when a purchase request 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. That is, this message confirms that you sent a <code>GET_PURCHASE_INFORMATION</code>
request for a given notification and that you received the purchase information for the
notification.</p>
</li>
<li><code>RESTORE_TRANSACTIONS</code>
<p>This request retrieves a user's transaction status for managed purchases (see <a
href="{@docRoot}google/play/billing/billing_admin.html#billing-purchase-type">Choosing a
Purchase Type</a> for more information). You should send this message 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>
<p>Every In-app Billing request generates a synchronous response. The response is a {@link
android.os.Bundle} and can include one or more of the following 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}, 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 certain types of requests. Table 8 shows which keys are
returned for each request type.</p>
<p class="table-caption"><strong>Table 8.</strong> Description of Bundle keys that are returned with
each In-app Billing request type.</p>
<table>
<tr>
<th>Request Type</th>
<th>Keys Returned</th>
<th>Possible Response Codes</th>
</tr>
<tr>
<td><code>CHECK_BILLING_SUPPORTED</code></td>
<td><code>RESPONSE_CODE</code></td>
<td><code>RESULT_OK</code>, <code>RESULT_BILLING_UNAVAILABLE</code>, <code>RESULT_ERROR</code>,
<code>RESULT_DEVELOPER_ERROR</code></td>
</tr>
<tr>
<td><code>REQUEST_PURCHASE</code></td>
<td><code>RESPONSE_CODE</code>, <code>PURCHASE_INTENT</code>, <code>REQUEST_ID</code></td>
<td><code>RESULT_OK</code>, <code>RESULT_ERROR</code>, <code>RESULT_DEVELOPER_ERROR</code></td>
</tr>
<tr>
<td><code>GET_PURCHASE_INFORMATION</code></td>
<td><code>RESPONSE_CODE</code>, <code>REQUEST_ID</code></td>
<td><code>RESULT_OK</code>, <code>RESULT_ERROR</code>, <code>RESULT_DEVELOPER_ERROR</code></td>
</tr>
<tr>
<td><code>CONFIRM_NOTIFICATIONS</code></td>
<td><code>RESPONSE_CODE</code>, <code>REQUEST_ID</code></td>
<td><code>RESULT_OK</code>, <code>RESULT_ERROR</code>, <code>RESULT_DEVELOPER_ERROR</code></td>
</tr>
<tr>
<td><code>RESTORE_TRANSACTIONS</code></td>
<td><code>RESPONSE_CODE</code>, <code>REQUEST_ID</code></td>
<td><code>RESULT_OK</code>, <code>RESULT_ERROR</code>, <code>RESULT_DEVELOPER_ERROR</code></td>
</tr>
</table>
<h3 id="billing-intents">In-app billing broadcast intents</h3>
<p>The following section describes the In-app Billing broadcast intents that are sent by the Google
Play application. These broadcast intents inform your application about In-app Billing actions
that have occurred. Your application must implement a {@link android.content.BroadcastReceiver} to
receive these broadcast intents, such as the <code>BillingReceiver</code> that's shown in the in-app
billing <a href="{@docRoot}google/play/billing/v2/billing_integrate.html#billing-download">sample
application</a>.</p>
<h4>com.android.vending.billing.RESPONSE_CODE</h4>
<p>This broadcast intent contains a Google Play 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
intent 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 <a
href="#billing-codes">Google Play Response Codes for In-app Billing</a>. The sample application
assigns this broadcast intent to a constant named <code>ACTION_RESPONSE_CODE</code>.</p>
<h5>Extras</h5>
<ul type="none">
<li><code>request_id</code>&mdash;a <code>long</code> representing a request ID. A request ID
identifies a specific billing request and is returned by Google Play at the time a request is
made.</li>
<li><code>response_code</code>&mdash;an <code>int</code> representing the Google Play server
response code.</li>
</ul>
<h4>com.android.vending.billing.IN_APP_NOTIFY</h4>
<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 the
message details. The sample application assigns this broadcast intent to a constant named
<code>ACTION_NOTIFY</code>.</p>
<h5>Extras</h5>
<ul type="none">
<li><code>notification_id</code>&mdash;a <code>String</code> representing the notification ID for
a given purchase state change. Google Play notifies you when there is a purchase state change
and the notification includes a unique notification ID. To get the details of the purchase state
change, you send the notification ID with the <code>GET_PURCHASE_INFORMATION</code> request.</li>
</ul>
<h4>com.android.vending.billing.PURCHASE_STATE_CHANGED</h4>
<p>This broadcast intent 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
sample application assigns this broadcast intent to a constant named
<code>ACTION_PURCHASE_STATE_CHANGED</code>.</p>
<h5>Extras</h5>
<ul type="none">
<li><code>inapp_signed_data</code>&mdash;a <code>String</code> representing the signed JSON
string.</li>
<li><code>inapp_signature</code>&mdash;a <code>String</code> representing the signature.</li>
</ul>
<p class="note"><strong>Note:</strong> Your application should map the broadcast intents and extras
to constants that are unique to your application. See the <code>Consts.java</code> file in the
sample application to see how this is done.</p>
<p>The fields in the JSON string are described in the following table (see table 9):</p>
<p class="table-caption"><strong>Table 9.</strong> Description of JSON fields that are returned with
a <code>PURCHASE_STATE_CHANGED</code> intent.</p>
<table>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
<tr>
<td>nonce</td>
<td>A number used once. Your application generates the nonce and sends it with the
<code>GET_PURCHASE_INFORMATION</code> request. Google Play sends the nonce back as part of the
JSON string so you can verify the integrity of the message.</td>
</tr>
<tr>
<td>notificationId</td>
<td>A unique identifier that is sent with an <code>IN_APP_NOTIFY</code> broadcast intent. Each
<code>notificationId</code> corresponds to a specify message that is waiting to be retrieved on
the Google Play server. Your application sends back the <code>notificationId</code> with the
<code>GET_PURCHASE_INFORMATION</code> message so Google Play can determine which messages you
are retrieving.</td>
</tr>
<tr>
<td>orderId</td>
<td>A unique order identifier for the transaction. This corresponds to the Google payments order
ID.</td>
</tr>
<tr>
<td>packageName</td>
<td>The application package from which the purchase originated.</td>
</tr>
<tr>
<td>productId</td>
<td>The item's product identifier. Every item has a product ID, which you must specify in the
application's product list on the Google Play Developer Console.</td>
</tr>
<tr>
<td>purchaseTime</td>
<td>The time the product was purchased, in milliseconds since the epoch (Jan 1, 1970).</td>
</tr>
<tr>
<td>purchaseState</td>
<td>The purchase state of the order. Possible values are 0 (purchased), 1 (canceled), 2
(refunded), or 3 (expired, for subscription purchases only).</td>
</tr>
<tr>
<td>purchaseToken</td>
<td>A token that uniquely identifies a subscription purchase for a given item and user pair.
You can use the token to specify the subscription when querying for subscription validity.
<p><br><em>Supported only in In-app Billing API Version 2 and higher.</em></p></td>
</tr>
<tr>
<td>developerPayload</td>
<td>A developer-specified string that contains supplemental information about an order. You can
specify a value for this field when you make a <code>REQUEST_PURCHASE</code> request.</td>
</tr>
</table>
<!--<h2 id="other-intents">Other Intents</h2>
<p>The following Intents related to In-app Billing may be useful in your
implemention. </p> -->
<h3 id="http-api">REST API for subscriptions</h3>
<p>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. See <a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Purchase Status API</a> for more information.</p>

View File

@@ -1,448 +0,0 @@
page.title=Implementing Subscriptions <span style="font-size:16px;">(IAB Version 2)</span>
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="#sample">Sample Application</a></li>
<li><a href="#model">Application Model</a></li>
<li><a href="#token">Purchase Token</a></li>
<li><a href="#version">Checking the In-app Billing API Version</a></li>
<li><a href="#purchase">Purchasing a Subscription</a></li>
<li><a href="#restore">Restoring Transactions</a></li>
<li><a href="#validity">Checking Subscription Validity</a></li>
<li><a href="#viewstatus">Letting Users Cancel or View Status</a></li>
<li><a href="#purchase-state-changes">Recurring Billing and Changes in Purchase State</a></li>
<li><a href="#modifying">Modifying Your App for Subscriptions</a></li>
</ol>
</div>
</div>
<p>This document is focused on highlighting implementation details that are
specific to subscriptions with the Version 2 API. To understand how
subscriptions work, see <a href="{@docRoot}google/play/billing/billing_subscriptions.html">In-app Billing Subscriptions</a>.</p>
<h2 id="sample">Sample Application</h2>
<p>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 <a
href="{@docRoot}google/play/billing/v2/billing_integrate.html#billing-download">
Downloading the Sample Application</a>.</p>
<h2 id="model">Application Model</h2>
<p>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.</p>
<p>Your app also uses the standard In-app Billing components &mdash; 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 <a
href="{@docRoot}google/play/billing/v2/api.html">In-app Billing
Overview</a> and related documents.</p>
<p>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.
</p>
<h2 id="token">Purchase Token</h2>
<p>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) and then sends it to the purchasing app on the device through the
In-app Billing API. </p>
<p>At the conclusion of a <code>PURCHASE_REQUEST</code> message flow, your app
can retrieve the purchase token and other transaction details by initiating a
<code>GET_PURCHASE_INFORMATION</code> 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 <code>purchaseToken</code>
field. </p>
<p>An example of a JSON order object that includes a subscription purchase token
is shown below. </p>
<pre class="no-pretty-print" style="color:black">{ "nonce" : 1836535032137741465,
"orders" :
[{ "notificationId" : "android.test.purchased",
"orderId" : "GPA.1234-5678-9012-34567"
"packageName" : "com.example.dungeons",
"productId" : "android.test.purchased",
"developerPayload" : "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ",
"purchaseTime" : 1290114783411,
"purchaseState" : 0,
"purchaseToken" : "rojeslcdyyiapnqcynkjyyjh" }]
}
</pre>
<p>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 <a
href="{@docRoot}google/play/billing/billing_best_practices.html">Security and
Design</a> document for best practices for maintaining the security of your
data.</p>
<h2 id="version">Checking the In-app Billing API Version</h2>
<p>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.</p>
<p>To do this, create a CHECK_BILLING_SUPPORTED request Bundle that includes the
required key-value pairs, together with</p>
<ul>
<li>The <code>API_VERSION</code> key, assigning a value of 2.</li>
<li>The <code>BILLING_REQUEST_ITEM_TYPE</code> key, assigning a value of “subs”</li>
</ul>
<p>Send the request using <code>sendBillingRequest(Bundle)</code> and receive
the response Bundle. You can extract the response from the
<code>BILLING_RESPONSE_RESPONSE_CODE</code> key of the response. RESULT_OK
indicates that subscriptions are supported.</p>
<p>The sample app declares constants for the accepted
<code>BILLING_REQUEST_ITEM_TYPE</code> values (from Consts.java):</p>
<pre class="pretty-print"> // 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";
</pre>
<p>It sets up a convenience method for building the request bundle (from BillingService.java):</p>
<pre class="pretty-print"> protected Bundle makeRequestBundle(String method) {
Bundle request = new Bundle();
request.putString(Consts.BILLING_REQUEST_METHOD, method);
request.putInt(Consts.BILLING_REQUEST_<code>API_VERSION</code>, 2);
request.putString(Consts.BILLING_REQUEST_PACKAGE_NAME, getPackageName());
return request;
}
</pre>
<p>Here’s an example of how to test support for In-App Billing v2 and subscriptions
(from BillingService.java):</p>
<pre class="pretty-print"> /**
* 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;
}
&#64;Override
protected long run() throws RemoteException {
Bundle request = makeRequestBundle("CHECK_BILLING_SUPPORTED");
if (mProductType != null) {
request.putString(Consts.<code>BILLING_REQUEST_ITEM_TYPE</code>, mProductType);
}
Bundle response = mService.sendBillingRequest(request);
int responseCode = response.getInt(Consts.<code>BILLING_RESPONSE_RESPONSE_CODE</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;
}
}
</pre>
<h2 id="purchase">Requesting a Subscription Purchase</h2>
<p>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 &mdash; by sending a REQUEST_PURCHASE request. You can then launch
Google Play to display the checkout user interface and handle the financial
transaction..
<p>The REQUEST_PURCHASE includes a Bundle containing the item details, as
described in the <a
href="{@docRoot}google/play/billing/v2/api.html">In-app Billing
Overview</a>. For a subscription, the Bundle must also specify:</p>
<ul>
<li>The <code>ITEM_ID</code> key, with a value that specifies a valid, published
subscription product.</li>
<li>The <code>ITEM_TYPE</code> key, with a value of “subs”
(<code>ITEM_TYPE_SUBSCRIPTION</code> in the sample app). If the request does not
specify the subscription's <code>ITEM_TYPE</code>, Google Play attempts to
handle the request as a standard in-app purchase (one-time purchase).</li>
</ul>
<p>Google Play synchronously returns a response bundle that includes
<code>RESPONSE_CODE</code>, <code>PURCHASE_INTENT</code>, and
<code>REQUEST_ID</code>. Your app uses the <code>PURCHASE_INTENT</code> to
launch the checkout UI and the message flow proceeds exactly as described in <a
href="{@docRoot}google/play/billing/v2/api.html#billing-message-
sequence">Messaging sequence</a>.</p>
<p>Here’s how the sample app initiates a purchase for a subscription, where
<code>mProductType</code> is <code>ITEM_TYPE_SUBSCRIPTION</code> (from
BillingService.java).</p>
<pre class="pretty-print"> /**
* Wrapper class that requests a purchase.
*/
class RequestPurchase extends BillingRequest {
public final String mProductId;
public final String mDeveloperPayload;
public final String mProductType;
. . .
&#64;Override
protected long run() throws RemoteException {
Bundle request = makeRequestBundle("REQUEST_PURCHASE");
request.putString(Consts.BILLING_REQUEST_ITEM_ID, mProductId);
request.putString(Consts.<code>BILLING_REQUEST_ITEM_TYPE</code>, 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);
}
&#64;Override
protected void responseCodeReceived(ResponseCode responseCode) {
ResponseHandler.responseCodeReceived(BillingService.this, this, responseCode);
}
}
</pre>
<h2 id="restoring">Restoring Transactions</h2>
<p>Subscriptions always use the <em>managed by user account</em> 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.</p>
<p>The process for restoring subscriptions transactions is the same as described
in <a
href="{@docRoot}google/play/billing/v2/api.html#billing-message-
sequence">Messaging sequence</a>. Your app sends a
<code>RESTORE_TRANSACTIONS</code> request to Google Play. Google Play sends two
broadcast intents as asynchronous responses &mdash; a <code>RESPONSE_CODE</code>
intent and a <code>PURCHASE_STATE_CHANGED</code> intent.</p>
<p>The <code>PURCHASE_STATE_CHANGED</code> intent contains a notification ID
that your app can use to retrieve the purchase details, including the purchase
token, by sending a standard <code>GET_PURCHASE_INFORMATION</code> request. The
<code>Bundle</code> returned in the call includes an JSON array of order objects
corresponding to subscription (and in-app product) purchases that you can
restore locally.</p>
<p>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 <a
href="{@docRoot}google/play/billing/billing_best_practices.html">Security and
Design</a> document for best practices for maintaining the security of your
data.</p>
<h2 id="validity">Checking Subscription Validity</h2>
<p>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.</p>
<p>With In-app Billing, you validate a subscription by keeping track of its
purchase state and then checking the state whenever needed. Google Play
provides two ways to let you know when the purchase
state of a subscription changes:</p>
<ul>
<li><em>In-app Billing Notifications</em>. Google Play pushes a notification
to your app to indicate a change in the purchase state of a subscription. Your app can
store the most recent purchase state for a given purchase token and then check
that state at run time, as needed.</li>
<li><em>Google Play Android Developer API</em>. You can use this HTTP-based
API to poll Google Play for the current purchase state of a subscription. You
can store the purchased state for each <code>purchaseToken</code> on your
backend servers. For more information, see <a href="#play-dev-api">Google Play
Android Developer API</a>, below.</li>
</ul>
<p>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:</p>
<ul>
<li>When the user successfully purchases a new subscription, your app notifies a
backend server, which stores the purchase token, user name, and other
information in a secure location.</li>
<li>Since your app cannot know the expiration date, your server can poll Google
Play to get the expiration and store it with the purchase token and other
data.</li>
<li>Because your server now knows the expiration date, it does not need to poll
Google Play again until after the expiration date, at which time it can confirm
that the subscription was not cancelled.</li>
<li>On the client side, your app can continue to update the server whenever the
purchase state changes, storing the state locally.</li>
</ul>
<p>If you are using both notifications and the Google Play Android Developer API to validate subscriptions, we recommend the following:</p>
<ul>
<li>If your app wants to check validity but you can’t reach your server (or
you don’t have a server), use the latest purchase state received by
notification.</li>
<li>If you have a server and it’s reachable, always give preference to the
purchase state obtained from your server over the state received in
notifications.</li>
</ul>
<p>If necessary, you can also use a <code>RESTORE_TRANSACTIONS</code> request to retrieve a record of all managed and in-app products purchased by the user, which you can then store locally. However, using <code>RESTORE_TRANSACTIONS</code> on a regular basis is not recommended because of performance impacts.</p>
<p>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.</p>
<p class="table-caption"><strong>Table 1.</strong> Summary of purchaseState
values for subscription purchases, as received with a
<code>PURCHASE_STATE_CHANGED</code> intent.</p>
<table>
<tr>
<th>State</th><th>purchaseState Value</th><th>Comments</th>
</tr>
<tr>
<td>Purchased successfully</td><td><code>0</code></td><td>Sent at original purchase only (not at recurring billing cycles).</td></tr>
<td>Cancelled</td><td><code>1</code></td><td>Sent at original purchase only if the purchase has failed for some reason. </td></tr>
<td>Refunded</td><td><code>2</code></td><td>The purchase was refunded.</code></td></tr>
<td>Subscription expired</td><td><code>3</code></td><td>Sent at the end of a billing cycle to indicate that the subscription expired without renewal because of non-payment or user-cancellation. Your app does not need to grant continued access to the subscription content.
</td></tr>
</table>
<h2 id="viewstatus">Letting the User Cancel or View Subscriptions</h2>
<p>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.</p>
<p>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.</p>
<p>To do this, create an intent with the <a
href="{@docRoot}reference/android/content/Intent.html#ACTION_VIEW">ACTION_VIEW</a>
action and include the <code>market://</code> URI (rather than the <code>http://</code>
URI) of your app's details page. Here’s an example:</p>
<pre style="pretty-print">Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("market://details?id=com.example.app"));
startActivity(intent);</pre>
<p>For more information, see
<a href="{@docRoot}distribute/tools/promote/linking.html">Linking to Your Products</a>.</p>
<h2 id="purchase-state-changes">Recurring Billing, Cancellation, and Changes In Purchase State</h2>
<p>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 <em>until the subscription expires because of
non-payment or user cancellation</em>. </p>
<p>Over the life of a subscription, your app does not need to initiate any
recurring billing events &mdash; those are all handled by Google Play and they
are transparent to your application if billing is successful.</p>
<p>When the user cancels a subscription during an active billing cycle, Google
Play <em>does not</em> notify your app immediately of the change in purchase
state. Instead, it waits until the end of the active billing cycle and then
notifies your app that the purchase state has changed to "Expired". </p>
<p>Similarly, if payment for the next billing cycle fails, Google Play waits
until the end of the active billing cycle and then notifies your app at that time that the
purchase state has changed to "Expired".</p>
<p>Your app can handle user cancellation and non-payment in the same way, since both cause
a change to the same "Expired" purchase state. Once the purchase state has become "Expired",
your app does not need to grant further access to the subscription content.</p>
<h2 id="modifying">Modifying Your App for Subscriptions</h2>
<p>For subscriptions, you make the same types of modifications to your app as
are described in <a
href="{@docRoot}google/play/billing/v2/billing_integrate.html#billing-implement">
Modifying your Application Code</a>.</p>
<p>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.</p>