docs: IAB formatting fixes (no content changes)

Saw a problem with the files' TOCs that was causing formatting
problems. While I had the files open, I fixed other formatting
issues--mostly just whitespace (paragraphs that were on one line
instead of broken at 100 chars) and a couple of other typos or HTML
errors. No substantive changes to the documentation.

Change-Id: I5f89ae616489d19dd683fd24e11e3482cce99477
This commit is contained in:
Andrew Solovay
2015-10-01 14:04:25 -07:00
parent 85ac0dd2ab
commit 7e86ae85cc
2 changed files with 600 additions and 175 deletions

View File

@@ -11,53 +11,96 @@ page.tags="billing, inapp, iap"
<ol>
<li><a href="#producttypes">Product Types</a>
<ol>
<li><a href="#managed">Managed In-app Products</a><li>
<li><a href="#subs">Subscriptions</a><li>
<li><a href="#managed">Managed In-app Products</a></li>
<li><a href="#subs">Subscriptions</a></li>
</ol>
</li>
<li><a href="#purchase">Purchasing Items</a></li>
<li><a href="#consume">Consuming In-app Products</a>
<ol>
<li><a href="#consumetypes">Non-consumable and Consumable In-app Products</a><li>
<li><a href="#managingconsumables">Managing Consumable Purchases</a><li>
<li><a href="#consumetypes">Non-consumable and Consumable In-app Products</a></li>
<li><a href="#managingconsumables">Managing Consumable Purchases</a></li>
</ol>
</li>
<li><a href="#caching">Local Caching</a></li>
</ol>
<h2>Reference</h2>
<ol>
<li><a href="{@docRoot}google/play/billing/billing_reference.html">In-app Billing
Reference (V3)</a></li>
</ol>
<h2>See also</h2>
<ol>
<li><a href="{@docRoot}training/in-app-billing/index.html">Selling In-app Products</a></li>
</ol>
</ol>
</div>
</div>
<p>The In-app Billing Version 3 API makes it easier for you to integrate In-app Billing into your applications. The features in this version include improved synchronous purchase flow, APIs to let you easily track ownership of consumable goods, and local caching of in-app purchase data.</p>
<p>
The In-app Billing Version 3 API makes it easier for you to integrate In-app
Billing into your applications. The features in this version include improved
synchronous purchase flow, APIs to let you easily track ownership of
consumable goods, and local caching of in-app purchase data.
</p>
<h2 id="producttypes">Product Types</h2>
<p>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>. The Version 3 API supports managed in-app products and subscriptions.</p>
<p>
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>. The Version 3 API supports managed in-app products and
subscriptions.
</p>
<h3 id="managed">Managed In-app Products</h3>
<p>Managed in-app products are items that have their ownership information tracked and managed by Google Play. When a user purchases a managed in-app item, Google Play stores the purchase information for each item on a per-user basis. This enables you to later query Google Play at any time to restore the state of the items a specific user has purchased. This information is persistent on the Google Play servers even if the user uninstalls the application or if they change devices.</p>
<p>If you are using the Version 3 API, you can also consume managed items within your application. You would typically implement consumption for items that can be purchased multiple times (such as in-game currency, fuel, or magic spells). Once purchased, a managed item cannot be purchased again until you consume the item, by sending a consumption request to Google Play. To learn more about in-app product consumption, see <a href="#consume">Consuming Items</a></p>
<p>
Managed in-app products are items that have their ownership information
tracked and managed by Google Play. When a user purchases a managed in-app
item, Google Play stores the purchase information for each item on a per-user
basis. This enables you to later query Google Play at any time to restore the
state of the items a specific user has purchased. This information is
persistent on the Google Play servers even if the user uninstalls the
application or if they change devices.
</p>
<p>
If you are using the Version 3 API, you can also consume managed items within
your application. You would typically implement consumption for items that
can be purchased multiple times (such as in-game currency, fuel, or magic
spells). Once purchased, a managed item cannot be purchased again until you
consume the item, by sending a consumption request to Google Play. To learn
more about in-app product consumption, see <a href="#consume">Consuming
Items</a>.
</p>
<h3 id="subs">Subscriptions</h3>
<p>A subscription is a product type offered in In-app Billing that lets you sell
content, services, or features to users from inside your app with recurring
monthly or annual billing. You can sell subscriptions to almost any type of
digital content, from any type of app or game. To understand how
subscriptions work, see <a href="{@docRoot}google/play/billing/billing_subscriptions.html">In-app Billing Subscriptions</a>.</p>
<p>With the Version 3 API, you can use the same purchase flow for buying
subscriptions and retrieving subscription purchase information as with in-app
products. For a code example, see <a href="{@docRoot}google/play/billing/billing_integrate.html#Subs">Implementing Subscriptions</a>.</p>
<p class="caution"><strong>Important</strong>: Unlike in-app products,
subscriptions cannot be consumed.</p>
<p>
A subscription is a product type offered in In-app Billing that lets you sell
content, services, or features to users from inside your app with recurring
monthly or annual billing. You can sell subscriptions to almost any type of
digital content, from any type of app or game. To understand how
subscriptions work, see <a href=
"{@docRoot}google/play/billing/billing_subscriptions.html">In-app Billing
Subscriptions</a>.
</p>
<p>
With the Version 3 API, you can use the same purchase flow for buying
subscriptions and retrieving subscription purchase information as with in-app
products. For a code example, see <a href=
"{@docRoot}google/play/billing/billing_integrate.html#Subs">Implementing
Subscriptions</a>.
</p>
<p class="caution">
<strong>Important</strong>: Unlike in-app products, subscriptions cannot be
consumed.
</p>
<h2 id="purchase">Purchasing Items</h2>
@@ -68,71 +111,205 @@ subscriptions cannot be consumed.</p>
</p>
</div>
<p>A typical purchase flow with the Version 3 API is as follows:
<p>A typical purchase flow with the Version 3 API is as follows:</p>
<ol>
<li>Your application sends a {@code isBillingSupported} request to Google Play to determine that the target version of the In-app Billing API that you are using is supported. </li>
<li>When your application starts or user logs in, it's good practice to check with Google Play to determine what items are owned by the user. To query the user's in-app purchases, send a {@code getPurchases} request. If the request is successful, Google Play returns a {@code Bundle} containing a list of product IDs of the purchased items, a list of the individual purchase details, and a list of the signatures for the purchases.</li>
<li>Usually, you'll want to inform the user of the products that are available for purchase. To query the details of the in-app products that you defined in Google Play, your application can send a {@code getSkuDetails} request. You must specify a list of product IDs in the query request. If the request is successful, Google Play returns a {@code Bundle} containing product details including the products price, title, description, and the purchase type.
</li>
<li>If an in-app product is not owned by the user, you can initiate a purchase for it. To start a purchase request, your application sends a {@code getBuyIntent} request, specifying the product ID of the item to purchase, along with other parameters. You should record the product ID when you create a new in-app product in the Developer Console.
<ol type="a">
<li>Google Play returns a {@code Bundle} that contains a {@code PendingIntent} which your application uses to start the checkout UI for the purchase.</li>
<li>Your application launches the pending intent by calling the {@code startIntentSenderForResult} method.</li>
<li>When the checkout flow finishes (that is, the user successfully purchases the item or cancels the purchase), Google Play sends a response {@code Intent} to your {@code onActivityResult} method. The result code of the {@code onActivityResult} has a result code that indicates whether the purchase was successful or canceled. The response {@code Intent} contains information about the purchased item, including a {@code purchaseToken} String that is generated by Google Play to uniquely identify this purchase transaction. The {@code Intent} also contains the signature of the purchase, signed with your private developer key.</li>
</ol>
</li>
<li>Your application sends a {@code isBillingSupported} request to Google
Play to determine that the target version of the In-app Billing API that you
are using is supported.
</li>
<li>When your application starts or user logs in, it's good practice to check
with Google Play to determine what items are owned by the user. To query the
user's in-app purchases, send a {@code getPurchases} request. If the request
is successful, Google Play returns a {@code Bundle} containing a list of
product IDs of the purchased items, a list of the individual purchase
details, and a list of the signatures for the purchases.
</li>
<li>Usually, you'll want to inform the user of the products that are
available for purchase. To query the details of the in-app products that you
defined in Google Play, your application can send a {@code getSkuDetails}
request. You must specify a list of product IDs in the query request. If the
request is successful, Google Play returns a {@code Bundle} containing
product details including the products price, title, description, and the
purchase type.
</li>
<li>If an in-app product is not owned by the user, you can initiate a
purchase for it. To start a purchase request, your application sends a {@code
getBuyIntent} request, specifying the product ID of the item to purchase,
along with other parameters. You should record the product ID when you create
a new in-app product in the Developer Console.
<ol type="a">
<li>Google Play returns a {@code Bundle} that contains a {@code
PendingIntent} which your application uses to start the checkout UI for
the purchase.
</li>
<li>Your application launches the pending intent by calling the {@code
startIntentSenderForResult} method.
</li>
<li>When the checkout flow finishes (that is, the user successfully
purchases the item or cancels the purchase), Google Play sends a response
{@code Intent} to your {@code onActivityResult} method. The result code
of the {@code onActivityResult} has a result code that indicates whether
the purchase was successful or canceled. The response {@code Intent}
contains information about the purchased item, including a {@code
purchaseToken} String that is generated by Google Play to uniquely
identify this purchase transaction. The {@code Intent} also contains the
signature of the purchase, signed with your private developer key.
</li>
</ol>
</li>
</ol>
<p>
To learn more about the Version 3 API calls and server responses, see
<a href="{@docRoot}google/play/billing/billing_reference.html">In-app Billing
Reference</a>.
</p>
<p>To learn more about the Version 3 API calls and server responses, see <a href="{@docRoot}google/play/billing/billing_reference.html">In-app Billing Reference</a>.</p>
<h2 id="consume">Consuming In-app Products</h2>
<p>You can use the consumption mechanism to track the user's ownership of in-app
products.</p>
<p>In Version 3, all in-app products are managed. This means that the user's
ownership of all in-app item purchases is maintained by Google Play, and your
application can query the user's purchase information when needed. When the user
successfully purchases an in-app product, that purchase is recorded in Google
Play. Once an in-app product is purchased, it is considered to be "owned".
In-app products in the "owned" state cannot be purchased from Google Play. You
must send a consumption request for the "owned" in-app product before Google
Play makes it available for purchase again. Consuming the in-app product reverts
it to the "unowned" state, and discards the previous purchase data.</p>
<p>
You can use the consumption mechanism to track the user's ownership of in-app
products.
</p>
<p>
In Version 3, all in-app products are managed. This means that the user's
ownership of all in-app item purchases is maintained by Google Play, and your
application can query the user's purchase information when needed. When the
user successfully purchases an in-app product, that purchase is recorded in
Google Play. Once an in-app product is purchased, it is considered to be
"owned". In-app products in the "owned" state cannot be purchased from Google
Play. You must send a consumption request for the "owned" in-app product
before Google Play makes it available for purchase again. Consuming the
in-app product reverts it to the "unowned" state, and discards the previous
purchase data.
</p>
<div class="figure" style="width:420px">
<img src="{@docRoot}images/in-app-billing/v3/iab_v3_consumption_flow.png" id="figure2" height="300"/>
<img src="{@docRoot}images/in-app-billing/v3/iab_v3_consumption_flow.png"
id="figure2" height="300"/>
<p class="img-caption">
<strong>Figure 2.</strong> The basic sequence for a consumption request.
</p>
</div>
<p>To retrieve the list of product's owned by the user, your application sends a {@code getPurchases} call to Google Play. Your application can make a consumption request by sending a {@code consumePurchase} call. In the request argument, you must specify the in-app product's unique {@code purchaseToken} String that you obtained from Google Play when it was purchased. Google Play returns a status code indicating if the consumption was recorded successfully.</p>
<p>
To retrieve the list of product's owned by the user, your application sends a
{@code getPurchases} call to Google Play. Your application can make a
consumption request by sending a {@code consumePurchase} call. In the request
argument, you must specify the in-app product's unique {@code purchaseToken}
String that you obtained from Google Play when it was purchased. Google Play
returns a status code indicating if the consumption was recorded
successfully.
</p>
<h3 id="consumetypes">Non-consumable and Consumable In-app Products</h3>
<p>It's up to you to decide if you want to handle your in-app products as non-consumable or consumable items.</p>
<p>
It's up to you to decide if you want to handle your in-app products as
non-consumable or consumable items.
</p>
<dl>
<dt>Non-consumable Items</dt>
<dd>Typically, you would not implement consumption for in-app products that can only be purchased once in your application and provide a permanent benefit. Once purchased, these items will be permanently associated to the user's Google account. An example of a non-consumable in-app product is a premium upgrade or a level pack.</dd>
<dt>Consumable items</dt>
<dd>In contrast, you can implement consumption for items that can be made available for purchase multiple times. Typically, these items provide certain temporary effects. For example, the user's in-game character might gain life points or gain extra gold coins in their inventory. Dispensing the benefits or effects of the purchased item in your application is called <em>provisioning</em> the in-app product. You are responsible for controlling and tracking how in-app products are provisioned to the users.
<p class="note"><strong>Important:</strong> Before provisioning the consumable in-app product in your application, you must send a consumption request to Google Play and receive a successful response indicating that the consumption was recorded.</p>
</dd>
<dt>
Non-consumable Items
</dt>
<dd>
Typically, you would not implement consumption for in-app products that can
only be purchased once in your application and provide a permanent benefit.
Once purchased, these items will be permanently associated to the user's
Google account. An example of a non-consumable in-app product is a premium
upgrade or a level pack.
</dd>
<dt>
Consumable items
</dt>
<dd>
In contrast, you can implement consumption for items that can be made
available for purchase multiple times. Typically, these items provide
certain temporary effects. For example, the user's in-game character might
gain life points or gain extra gold coins in their inventory. Dispensing
the benefits or effects of the purchased item in your application is called
<em>provisioning</em> the in-app product. You are responsible for
controlling and tracking how in-app products are provisioned to the users.
<p class="note">
<strong>Important:</strong> Before provisioning the consumable in-app
product in your application, you must send a consumption request to
Google Play and receive a successful response indicating that the
consumption was recorded.
</p>
</dd>
</dl>
<h3 id="managingconsumables">Managing consumable purchases in your application</h3>
<p>Here is the basic flow for purchasing a consumable in-app product:</p>
<ol>
<li>Launch a purchase flow with a {@code getBuyIntent} call</li>
<li>Get a response {@code Bundle}from Google Play indicating if the purchase completed successfully.</li>
<li>If the purchase was successful, consume the purchase by making a {@code consumePurchase} call.</li>
<li>Get a response code from Google Play indicating if the consumption completed successfully.</li>
<li>If the consumption was successful, provision the product in your application.</li>
<li>Launch a purchase flow with a {@code getBuyIntent} call
</li>
<li>Get a response {@code Bundle}from Google Play indicating if the purchase
completed successfully.
</li>
<li>If the purchase was successful, consume the purchase by making a {@code
consumePurchase} call.
</li>
<li>Get a response code from Google Play indicating if the consumption
completed successfully.
</li>
<li>If the consumption was successful, provision the product in your
application.
</li>
</ol>
<p>Subsequently, when the user starts up or logs in to your application, you should check if the user owns any outstanding consumable in-app products; if so, make sure to consume and provision those items. Here's the recommended application startup flow if you implement consumable in-app products in your application:</p>
<p>
Subsequently, when the user starts up or logs in to your application, you
should check if the user owns any outstanding consumable in-app products; if
so, make sure to consume and provision those items. Here's the recommended
application startup flow if you implement consumable in-app products in your
application:
</p>
<ol>
<li>Send a {@code getPurchases} request to query the owned in-app products for the user.</li>
<li>If there are any consumable in-app products, consume the items by calling {@code consumePurchase}. This step is necessary because the application might have completed the purchase order for the consumable item, but stopped or got disconnected before the application had the chance to send a consumption request.</li>
<li>Get a response code from Google Play indicating if the consumption completed successfully.</li>
<li>If the consumption was successful, provision the product in your application.</li>
<li>Send a {@code getPurchases} request to query the owned in-app products
for the user.
</li>
<li>If there are any consumable in-app products, consume the items by calling
{@code consumePurchase}. This step is necessary because the application might
have completed the purchase order for the consumable item, but stopped or got
disconnected before the application had the chance to send a consumption
request.
</li>
<li>Get a response code from Google Play indicating if the consumption
completed successfully.
</li>
<li>If the consumption was successful, provision the product in your
application.
</li>
</ol>
<h2 id="caching">Local Caching</h2>
<p>Because the Google Play client now caches In-app Billing information locally on the device, you can use the Version 3 API to query for this information more frequently, for example through a {@code getPurchases} call. Unlike with previous versions of the API, many Version 3 API calls will be serviced through cache lookups instead of through a network connection to Google Play, which significantly speeds up the API's response time. </p>
<p>
Because the Google Play client now caches In-app Billing information locally
on the device, you can use the Version 3 API to query for this information
more frequently, for example through a {@code getPurchases} call. Unlike with
previous versions of the API, many Version 3 API calls will be serviced
through cache lookups instead of through a network connection to Google Play,
which significantly speeds up the API's response time.
</p>

View File

@@ -16,8 +16,8 @@ page.tags="inapp, billing, iap"
<li><a href="#QueryDetails">Querying Items Available for Purchase</a><li>
<li><a href="#Purchase">Purchasing an Item</a></li>
<li><a href="#QueryPurchases">Querying Purchased Items</a></li>
<li><a href="#Consume">Consuming a Purchase</a><li>
<li><a href="#Subs">Implementing Subscriptions</a><li>
<li><a href="#Consume">Consuming a Purchase</a></li>
<li><a href="#Subs">Implementing Subscriptions</a></li>
</ol>
</li>
<li><a href="#billing-security">Securing Your App</a>
@@ -38,15 +38,35 @@ page.tags="inapp, billing, iap"
</div>
</div>
<p>In-app Billing on Google Play provides a straightforward, simple interface for sending In-app Billing requests and managing In-app Billing transactions using Google Play. The information below covers the basics of how to make calls from your application to the In-app Billing service using the Version 3 API. </p>
<p>
In-app Billing on Google Play provides a straightforward, simple interface
for sending In-app Billing requests and managing In-app Billing transactions
using Google Play. The information below covers the basics of how to make
calls from your application to the In-app Billing service using the Version 3
API.
</p>
<p class="note"><strong>Note:</strong> To see a complete implementation and learn how to test your application, see the <a href="{@docRoot}training/in-app-billing/index.html">Selling In-app Products</a> training class. The training class provides a complete sample In-app Billing application, including convenience classes to handle key tasks related to setting up your connection, sending billing requests and processing responses from Google Play, and managing background threading so that you can make In-app Billing calls from your main activity.</p>
<p class="note">
<strong>Note:</strong> To see a complete implementation and learn how to test
your application, see the <a href=
"{@docRoot}training/in-app-billing/index.html">Selling In-app Products</a>
training class. The training class provides a complete sample In-app Billing
application, including convenience classes to handle key tasks related to
setting up your connection, sending billing requests and processing responses
from Google Play, and managing background threading so that you can make
In-app Billing calls from your main activity.
</p>
<p>Before you start, be sure that you read the <a href="{@docRoot}google/play/billing/billing_overview.html">In-app Billing Overview</a> to familiarize yourself with
concepts that will make it easier for you to implement In-app Billing.</p>
<p>
Before you start, be sure that you read the <a href=
"{@docRoot}google/play/billing/billing_overview.html">In-app Billing
Overview</a> to familiarize yourself with concepts that will make it easier
for you to implement In-app Billing.
</p>
<p>To implement In-app Billing in your application, you need to do the
following:</p>
<ol>
<li>Add the In-app Billing library to your project.</li>
<li>Update your {@code AndroidManifest.xml} file.</li>
@@ -73,48 +93,74 @@ method calls.</p>
<p>The {@code IInAppBillingService.aidl} file will be installed to {@code &lt;sdk&gt;/extras/google/play_billing/}.</p>
<p>To add the AIDL to your project:</p>
<ol>
<li>Copy the {@code IInAppBillingService.aidl} file to your Android project.
<ul>
<li>If you are using Eclipse:
<ol type="a">
<li>If you are starting from an existing Android project, open the project
in Eclipse. If you are creating a new Android project from scratch, click
<strong>File</strong> &gt; <strong>New</strong> &gt; <strong>Android Application
Project</strong>, then follow the instructions in the <strong>New Android
Application</strong> wizard to create a new project in your workspace.</li>
<li>In the {@code /src} directory, click <strong>File</strong> &gt;
<strong>New</strong> &gt; <strong>Package</strong>, then create a package named {@code com.android.vending.billing}.</li>
<li>Copy the {@code IInAppBillingService.aidl} file from {@code &lt;sdk&gt;/extras/google/play_billing/} and paste it into the {@code src/com.android.vending.billing/}
folder in your workspace.</li>
</ol>
</li>
<li>If you are developing in a non-Eclipse environment: Create the following
directory {@code /src/com/android/vending/billing} and copy the
{@code IInAppBillingService.aidl} file into this directory. Put the AIDL file
into your project and use the Ant tool to build your project so that the
<code>IInAppBillingService.java</code> file gets generated.</li>
</ul>
</li>
<li>Build your application. You should see a generated file named
{@code IInAppBillingService.java} in the {@code /gen} directory of your
project.</li>
</ol>
<ol>
<li>Copy the {@code IInAppBillingService.aidl} file to your Android project.
<ul>
<li>If you are using Eclipse:
<ol type="a">
<li>If you are starting from an existing Android project, open the
project in Eclipse. If you are creating a new Android project from
scratch, click <strong>File</strong> &gt; <strong>New</strong> &gt;
<strong>Android Application Project</strong>, then follow the
instructions in the <strong>New Android Application</strong> wizard
to create a new project in your workspace.
</li>
<li>In the {@code /src} directory, click <strong>File</strong> &gt;
<strong>New</strong> &gt; <strong>Package</strong>, then create a
package named {@code com.android.vending.billing}.
</li>
<li>Copy the {@code IInAppBillingService.aidl} file from {@code
&lt;sdk&gt;/extras/google/play_billing/} and paste it into the {@code
src/com.android.vending.billing/} folder in your workspace.
</li>
</ol>
</li>
<li>If you are developing in a non-Eclipse environment: Create the
following directory {@code /src/com/android/vending/billing} and copy the
{@code IInAppBillingService.aidl} file into this directory. Put the AIDL
file into your project and use the Ant tool to build your project so that
the <code>IInAppBillingService.java</code> file gets generated.
</li>
</ul>
</li>
<li>Build your application. You should see a generated file named {@code
IInAppBillingService.java} in the {@code /gen} directory of your project.
</li>
</ol>
<h2 id="billing-permission">Updating Your Application's Manifest</h2>
<p>In-app billing relies on the Google Play application, which handles all communication between your application and the Google Play server. To use the Google Play application, your application must request the proper permission. You can do this by adding the {@code com.android.vending.BILLING} permission to your AndroidManifest.xml file. If your application does not declare the In-app Billing permission, but attempts to send billing requests, Google Play will refuse the requests and respond with an error.</p>
<p>
In-app billing relies on the Google Play application, which handles all
communication between your application and the Google Play server. To use the
Google Play application, your application must request the proper permission.
You can do this by adding the {@code com.android.vending.BILLING} permission
to your AndroidManifest.xml file. If your application does not declare the
In-app Billing permission, but attempts to send billing requests, Google Play
will refuse the requests and respond with an error.
</p>
<p>
To give your app the necessary permission, add this line in your {@code
Android.xml} manifest file:
</p>
<p>To give your app the necessary permission, add this line in your {@code Android.xml} manifest file:</p>
<pre>
&lt;uses-permission android:name="com.android.vending.BILLING" /&gt;
</pre>
<h2 id="billing-service">Creating a ServiceConnection</h2>
<p>Your application must have a {@link android.content.ServiceConnection} to facilitate messaging between
your application and Google Play. At a minimum, your application must do the following:</p>
<p>
Your application must have a {@link android.content.ServiceConnection} to
facilitate messaging between your application and Google Play. At a minimum,
your application must do the following:
</p>
<ul>
<li>Bind to {@code IInAppBillingService}.
@@ -123,8 +169,18 @@ your application and Google Play. At a minimum, your application must do the fol
</ul>
<h3>Binding to IInAppBillingService</h3>
<p>To establish a connection with the In-app Billing service on Google Play, implement a {@link android.content.ServiceConnection} to bind your activity to {@code IInAppBillingService}. Override the {@link android.content.ServiceConnection#onServiceDisconnected onServiceDisconnected} and {@link
android.content.ServiceConnection#onServiceConnected onServiceConnected} methods to get a reference to the {@code IInAppBillingService} instance after a connection has been established.</p>
<p>
To establish a connection with the In-app Billing service on Google Play,
implement a {@link android.content.ServiceConnection} to bind your activity
to {@code IInAppBillingService}. Override the {@link
android.content.ServiceConnection#onServiceDisconnected
onServiceDisconnected} and {@link
android.content.ServiceConnection#onServiceConnected onServiceConnected}
methods to get a reference to the {@code IInAppBillingService} instance after
a connection has been established.
</p>
<pre>
IInAppBillingService mService;
@@ -142,9 +198,25 @@ ServiceConnection mServiceConn = new ServiceConnection() {
};
</pre>
<p>In your activitys {@link android.app.Activity#onCreate onCreate} method, perform the binding by calling the {@link android.content.Context#bindService bindService} method. Pass the method an {@link android.content.Intent} that references the In-app Billing service and an instance of the {@link android.content.ServiceConnection} that you created, and explicitly set the Intent's target package name to <code>com.android.vending</code> &mdash; the package name of Google Play app.</p>
<p>
In your activitys {@link android.app.Activity#onCreate onCreate} method,
perform the binding by calling the {@link android.content.Context#bindService
bindService} method. Pass the method an {@link android.content.Intent} that
references the In-app Billing service and an instance of the {@link
android.content.ServiceConnection} that you created, and explicitly set the
Intent's target package name to <code>com.android.vending</code> — the
package name of Google Play app.
</p>
<p class="caution"><strong>Caution:</strong> To protect the security of billing transactions, always make sure to explicitly set the intent's target package name to <code>com.android.vending</code>, using {@link android.content.Intent#setPackage(java.lang.String) setPackage()} as shown in the example below. Setting the package name explicitly ensures that <em>only</em> the Google Play app can handle billing requests from your app, preventing other apps from intercepting those requests.</p>
<p class="caution">
<strong>Caution:</strong> To protect the security of billing transactions,
always make sure to explicitly set the intent's target package name to
<code>com.android.vending</code>, using {@link
android.content.Intent#setPackage(java.lang.String) setPackage()} as shown in
the example below. Setting the package name explicitly ensures that
<em>only</em> the Google Play app can handle billing requests from your app,
preventing other apps from intercepting those requests.
</p>
<pre>&#64;Override
public void onCreate(Bundle savedInstanceState) {
@@ -154,8 +226,22 @@ public void onCreate(Bundle savedInstanceState) {
serviceIntent.setPackage("com.android.vending");
bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
</pre>
<p>You can now use the mService reference to communicate with the Google Play service.</p>
<p class="note"><strong>Important:</strong> Remember to unbind from the In-app Billing service when you are done with your {@link android.app.Activity}. If you dont unbind, the open service connection could cause your devices performance to degrade. This example shows how to perform the unbind operation on a service connection to In-app Billing called {@code mServiceConn} by overriding the activitys {@link android.app.Activity#onDestroy onDestroy} method.</p>
<p>
You can now use the mService reference to communicate with the Google Play
service.
</p>
<p class="note">
<strong>Important:</strong> Remember to unbind from the In-app Billing
service when you are done with your {@link android.app.Activity}. If you
dont unbind, the open service connection could cause your devices
performance to degrade. This example shows how to perform the unbind
operation on a service connection to In-app Billing called {@code
mServiceConn} by overriding the activitys {@link
android.app.Activity#onDestroy onDestroy} method.
</p>
<pre>
&#64;Override
public void onDestroy() {
@@ -166,16 +252,37 @@ public void onDestroy() {
}
</pre>
<p>For a complete implementation of a service connection that binds to the {@code IInAppBillingService},
see the <a href="{@docRoot}training/in-app-billing/preparing-iab-app.html">Selling In-app
Products</a> training class and associated sample.</p>
<p>
For a complete implementation of a service connection that binds to the
{@code IInAppBillingService}, see the <a href=
"{@docRoot}training/in-app-billing/preparing-iab-app.html">Selling In-app
Products</a> training class and associated sample.
</p>
<h2 id="billing-requests">Making In-app Billing Requests</h2>
<p>Once your application is connected to Google Play, you can initiate purchase requests for in-app products. Google Play provides a checkout interface for users to enter their payment method, so your application does not need to handle payment transactions directly. When an item is purchased, Google Play recognizes that the user has ownership of that item and prevents the user from purchasing another item with the same product ID until it is consumed. You can control how the item is consumed in your application, and notify Google Play to make the item available for purchase again. You can also query Google Play to quickly retrieve the list of purchases that were made by the user. This is useful, for example, when you want to restore the user's purchases when your user launches your app.
<p>
Once your application is connected to Google Play, you can initiate purchase
requests for in-app products. Google Play provides a checkout interface for
users to enter their payment method, so your application does not need to
handle payment transactions directly. When an item is purchased, Google Play
recognizes that the user has ownership of that item and prevents the user
from purchasing another item with the same product ID until it is consumed.
You can control how the item is consumed in your application, and notify
Google Play to make the item available for purchase again. You can also query
Google Play to quickly retrieve the list of purchases that were made by the
user. This is useful, for example, when you want to restore the user's
purchases when your user launches your app.
</p>
<h3 id="QueryDetails">Querying for Items Available for Purchase</h3>
<p>In your application, you can query the item details from Google Play using the In-app Billing Version 3 API. To pass a request to the In-app Billing service, first create a {@link android.os.Bundle} that contains a String {@link java.util.ArrayList} of product IDs with key "ITEM_ID_LIST", where each string is a product ID for an purchasable item.</p>
<p>
In your application, you can query the item details from Google Play using
the In-app Billing Version 3 API. To pass a request to the In-app Billing
service, first create a {@link android.os.Bundle} that contains a String
{@link java.util.ArrayList} of product IDs with key "ITEM_ID_LIST", where
each string is a product ID for an purchasable item.
</p>
<pre>
ArrayList&lt;String&gt; skuList = new ArrayList&lt;String&gt; ();
skuList.add("premiumUpgrade");
@@ -183,19 +290,51 @@ skuList.add("gas");
Bundle querySkus = new Bundle();
querySkus.putStringArrayList(“ITEM_ID_LIST”, skuList);
</pre>
<p>To retrieve this information from Google Play, call the {@code getSkuDetails} method on the In-app Billing Version 3 API, and pass the method the In-app Billing API version (“3”), the package name of your calling app, the purchase type (“inapp”), and the {@link android.os.Bundle} that you created.</p>
<p>
To retrieve this information from Google Play, call the {@code getSkuDetails}
method on the In-app Billing Version 3 API, and pass the method the In-app
Billing API version (“3”), the package name of your calling app, the purchase
type (“inapp”), and the {@link android.os.Bundle} that you created.
</p>
<pre>
Bundle skuDetails = mService.getSkuDetails(3,
getPackageName(), "inapp", querySkus);
</pre>
<p>If the request is successful, the returned {@link android.os.Bundle}has a response code of {@code BILLING_RESPONSE_RESULT_OK} (0).</p>
<p class="note"><strong>Warning:</strong> Do not call the {@code getSkuDetails} method on the main thread. Calling this method triggers a network request which could block your main thread. Instead, create a separate thread and call the {@code getSkuDetails} method from inside that thread.</p>
<p>To see all the possible response codes from Google Play, see <a href="{@docRoot}google/play/billing/billing_reference.html#billing-codes">In-app Billing Reference</a>.</p>
<p>
If the request is successful, the returned {@link android.os.Bundle}has a
response code of {@code BILLING_RESPONSE_RESULT_OK} (0).
</p>
<p>The query results are stored in a String ArrayList with key {@code DETAILS_LIST}. The purchase information is stored in the String in JSON format. To see the types of product detail information that are returned, see <a href="{@docRoot}google/play/billing/billing_reference.html#getSkuDetails">In-app Billing Reference</a>.</p>
<p class="note">
<strong>Warning:</strong> Do not call the {@code getSkuDetails} method on the
main thread. Calling this method triggers a network request which could block
your main thread. Instead, create a separate thread and call the {@code
getSkuDetails} method from inside that thread.
</p>
<p>
To see all the possible response codes from Google Play, see <a href=
"{@docRoot}google/play/billing/billing_reference.html#billing-codes">In-app
Billing Reference</a>.
</p>
<p>
The query results are stored in a String ArrayList with key {@code
DETAILS_LIST}. The purchase information is stored in the String in JSON
format. To see the types of product detail information that are returned, see
<a href=
"{@docRoot}google/play/billing/billing_reference.html#getSkuDetails">In-app
Billing Reference</a>.
</p>
<p>
In this example, you are retrieving the prices for your in-app items from the
skuDetails {@link android.os.Bundle} returned from the previous code snippet.
</p>
<p>In this example, you are retrieving the prices for your in-app items from the skuDetails {@link android.os.Bundle} returned from the previous code snippet.</p>
<pre>
int response = skuDetails.getInt("RESPONSE_CODE");
if (response == 0) {
@@ -213,28 +352,66 @@ if (response == 0) {
</pre>
<h3 id="Purchase">Purchasing an Item</h3>
<p>To start a purchase request from your app, call the {@code getBuyIntent} method on the In-app Billing service. Pass in to the method the In-app Billing API version (“3”), the package name of your calling app, the product ID for the item to purchase, the purchase type (“inapp” or "subs"), and a {@code developerPayload} String. The {@code developerPayload} String is used to specify any additional arguments that you want Google Play to send back along with the purchase information.</p>
<p>
To start a purchase request from your app, call the {@code getBuyIntent}
method on the In-app Billing service. Pass in to the method the In-app
Billing API version (“3”), the package name of your calling app, the product
ID for the item to purchase, the purchase type (“inapp” or "subs"), and a
{@code developerPayload} String. The {@code developerPayload} String is used
to specify any additional arguments that you want Google Play to send back
along with the purchase information.
</p>
<pre>
Bundle buyIntentBundle = mService.getBuyIntent(3, getPackageName(),
sku, "inapp", "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");
</pre>
<p>
If the request is successful, the returned {@link android.os.Bundle} has a response code of {@code BILLING_RESPONSE_RESULT_OK} (0) and a {@link android.app.PendingIntent} that you can use to start the purchase flow. To see all the possible response codes from Google Play, see <a href="{@docRoot}google/play/billing/billing_reference.html#billing-codes">In-app Billing Reference</a>. Next, extract a {@link android.app.PendingIntent} from the response {@link android.os.Bundle} with key {@code BUY_INTENT}.
If the request is successful, the returned {@link android.os.Bundle} has a
response code of {@code BILLING_RESPONSE_RESULT_OK} (0) and a {@link
android.app.PendingIntent} that you can use to start the purchase flow. To
see all the possible response codes from Google Play, see <a href=
"{@docRoot}google/play/billing/billing_reference.html#billing-codes">In-app
Billing Reference</a>. Next, extract a {@link android.app.PendingIntent} from
the response {@link android.os.Bundle} with key {@code BUY_INTENT}.
</p>
<pre>
PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
</pre>
<p>
To complete the purchase transaction, call the {@link android.app.Activity#startIntentSenderForResult startIntentSenderForResult} method and use the {@link android.app.PendingIntent} that you created. In this example, you are using an arbitrary value of 1001 for the request code.</p>
To complete the purchase transaction, call the {@link
android.app.Activity#startIntentSenderForResult startIntentSenderForResult}
method and use the {@link android.app.PendingIntent} that you created. In
this example, you are using an arbitrary value of 1001 for the request code.
</p>
<pre>
startIntentSenderForResult(pendingIntent.getIntentSender(),
1001, new Intent(), Integer.valueOf(0), Integer.valueOf(0),
Integer.valueOf(0));
</pre>
<p>Google Play sends a response to your {@link android.app.PendingIntent} to the {@link android.app.Activity#onActivityResult onActivityResult} method of your application. The {@link android.app.Activity#onActivityResult onActivityResult} method will have a result code of {@code Activity.RESULT_OK} (1) or {@code Activity.RESULT_CANCELED} (0). To see the types of order information that is returned in the response {@link android.content.Intent}, see <a href="{@docRoot}google/play/billing/billing_reference.html#getBuyIntent">In-app Billing Reference</a>.</p>
<p>The purchase data for the order is a String in JSON format that is mapped to the {@code INAPP_PURCHASE_DATA} key in the response {@link android.content.Intent}, for example:
<p>
Google Play sends a response to your {@link android.app.PendingIntent} to the
{@link android.app.Activity#onActivityResult onActivityResult} method of your
application. The {@link android.app.Activity#onActivityResult
onActivityResult} method will have a result code of {@code
Activity.RESULT_OK} (1) or {@code Activity.RESULT_CANCELED} (0). To see the
types of order information that is returned in the response {@link
android.content.Intent}, see <a href=
"{@docRoot}google/play/billing/billing_reference.html#getBuyIntent">In-app
Billing Reference</a>.
</p>
<p>
The purchase data for the order is a String in JSON format that is mapped to
the {@code INAPP_PURCHASE_DATA} key in the response {@link
android.content.Intent}, for example:
</p>
<pre>
'{
"orderId":"GPA.1234-5678-9012-34567",
@@ -246,17 +423,22 @@ startIntentSenderForResult(pendingIntent.getIntentSender(),
"purchaseToken":<em>"opaque-token-up-to-1000-characters"</em>
}'
</pre>
<p class="note">
<strong>Note:</strong> Google Play generates a token for the purchase. This
token is an opaque character sequence that may be up to 1,000 characters
long. Pass this entire token to other methods, such as when you consume the
purchase, as described in <a href=
"{@docRoot}training/in-app-billing/purchase-iab-products.html#Consume">Consume
a Purchase</a>. Do not abbreviate or truncate this token; you must save and
return the entire token.
</p>
<p class="note"><strong>Note:</strong> Google Play generates a token for the
purchase. This token is an opaque character sequence that may be up to 1,000
characters long. Pass this entire token to other methods, such as when you
consume the purchase, as described in
<a href="{@docRoot}training/in-app-billing/purchase-iab-products.html#Consume">Consume
a Purchase</a>. Do not abbreviate or truncate this token; you must save and
return the entire token.</p>
<p>
Continuing from the previous example, you get the response code, purchase
data, and signature from the response {@link android.content.Intent}.
</p>
<p>Continuing from the previous example, you get the response code, purchase data, and signature from the response {@link android.content.Intent}.</p>
<pre>
&#64;Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
@@ -280,16 +462,55 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
}
}
</pre>
<p class="note"><strong>Security Recommendation:</strong> When you send a purchase request, create a String token that uniquely identifies this purchase request and include this token in the {@code developerPayload}.You can use a randomly generated string as the token. When you receive the purchase response from Google Play, make sure to check the returned data signature, the {@code orderId}, and the {@code developerPayload} String. For added security, you should perform the checking on your own secure server. Make sure to verify that the {@code orderId} is a unique value that you have not previously processed, and the {@code developerPayload} String matches the token that you sent previously with the purchase request.</p>
<p class="note">
<strong>Security Recommendation:</strong> When you send a purchase request,
create a String token that uniquely identifies this purchase request and
include this token in the {@code developerPayload}.You can use a randomly
generated string as the token. When you receive the purchase response from
Google Play, make sure to check the returned data signature, the {@code
orderId}, and the {@code developerPayload} String. For added security, you
should perform the checking on your own secure server. Make sure to verify
that the {@code orderId} is a unique value that you have not previously
processed, and the {@code developerPayload} String matches the token that you
sent previously with the purchase request.
</p>
<h3 id="QueryPurchases">Querying for Purchased Items</h3>
<p>To retrieve information about purchases made by a user from your app, call the {@code getPurchases} method on the In-app Billing Version 3 service. Pass in to the method the In-app Billing API version (“3”), the package name of your calling app, and the purchase type (“inapp” or "subs").</p>
<p>
To retrieve information about purchases made by a user from your app, call
the {@code getPurchases} method on the In-app Billing Version 3 service. Pass
in to the method the In-app Billing API version (“3”), the package name of
your calling app, and the purchase type (“inapp” or "subs").
</p>
<pre>
Bundle ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);
</pre>
<p>The Google Play service returns only the purchases made by the user account that is currently logged in to the device. If the request is successful, the returned {@link android.os.Bundle} has a response code of 0. The response {@link android.os.Bundle} also contains a list of the product IDs, a list of the order details for each purchase, and the signatures for each purchase.</p>
<p>To improve performance, the In-app Billing service returns only up to 700 products that are owned by the user when {@code getPurchase} is first called. If the user owns a large number of products, Google Play includes a String token mapped to the key {@code INAPP_CONTINUATION_TOKEN} in the response {@link android.os.Bundle} to indicate that more products can be retrieved. Your application can then make a subsequent {@code getPurchases} call, and pass in this token as an argument. Google Play continues to return a continuation token in the response {@link android.os.Bundle} until all products that are owned by the user has been sent to your app.</p>
<p>For more information about the data returned by {@code getPurchases}, see <a href="{@docRoot}google/play/billing/billing_reference.html#getPurchases">In-app Billing Reference</a>. The following example shows how you can retrieve this data from the response.
<p>
The Google Play service returns only the purchases made by the user account
that is currently logged in to the device. If the request is successful, the
returned {@link android.os.Bundle} has a response code of 0. The response
{@link android.os.Bundle} also contains a list of the product IDs, a list of
the order details for each purchase, and the signatures for each purchase.
</p>
<p>
To improve performance, the In-app Billing service returns only up to 700
products that are owned by the user when {@code getPurchase} is first called.
If the user owns a large number of products, Google Play includes a String
token mapped to the key {@code INAPP_CONTINUATION_TOKEN} in the response
{@link android.os.Bundle} to indicate that more products can be retrieved.
Your application can then make a subsequent {@code getPurchases} call, and
pass in this token as an argument. Google Play continues to return a
continuation token in the response {@link android.os.Bundle} until all
products that are owned by the user has been sent to your app.
</p>
<p>For more information about the data returned by {@code getPurchases}, see <a href="{@docRoot}google/play/billing/billing_reference.html#getPurchases">In-app Billing Reference</a>. The following example shows how you can retrieve this data from the response.</p>
<pre>
int response = ownedItems.getInt("RESPONSE_CODE");
if (response == 0) {
@@ -302,7 +523,7 @@ if (response == 0) {
String continuationToken =
ownedItems.getString("INAPP_CONTINUATION_TOKEN");
for (int i = 0; i < purchaseDataList.size(); ++i) {
for (int i = 0; i &lt; purchaseDataList.size(); ++i) {
String purchaseData = purchaseDataList.get(i);
String signature = signatureList.get(i);
String sku = ownedSkus.get(i);
@@ -314,43 +535,76 @@ if (response == 0) {
// if continuationToken != null, call getPurchases again
// and pass in the token to retrieve more items
}
</pre>
<h3 id="Consume">Consuming a Purchase</h3>
<p>You can use the In-app Billing Version 3 API to track the ownership of
purchased in-app products in Google Play. Once an in-app product is purchased,
it is considered to be "owned" and cannot be purchased from Google Play. You
must send a consumption request for the in-app product before Google Play makes
it available for purchase again.</p>
<p class="caution"><strong>Important</strong>: Managed in-app products are
consumable, but subscriptions are not.</p>
<p>How you use the consumption mechanism in your app is up to you. Typically,
you would implement consumption for in-app products with temporary benefits that
users may want to purchase multiple times (for example, in-game currency or
equipment). You would typically not want to implement consumption for in-app
products that are purchased once and provide a permanent effect (for example,
a premium upgrade).</p>
<p>To record a purchase consumption, send the {@code consumePurchase} method to
the In-app Billing service and pass in the {@code purchaseToken} String value
that identifies the purchase to be removed. The {@code purchaseToken} is part
of the data returned in the {@code INAPP_PURCHASE_DATA} String by the Google
Play service following a successful purchase request. In this example, you are
recording the consumption of a product that is identified with the
{@code purchaseToken} in the {@code token} variable.</p>
<p>
You can use the In-app Billing Version 3 API to track the ownership of
purchased in-app products in Google Play. Once an in-app product is
purchased, it is considered to be "owned" and cannot be purchased from Google
Play. You must send a consumption request for the in-app product before
Google Play makes it available for purchase again.
</p>
<p class="caution">
<strong>Important</strong>: Managed in-app products are consumable, but
subscriptions are not.
</p>
<p>
How you use the consumption mechanism in your app is up to you. Typically,
you would implement consumption for in-app products with temporary benefits
that users may want to purchase multiple times (for example, in-game currency
or equipment). You would typically not want to implement consumption for
in-app products that are purchased once and provide a permanent effect (for
example, a premium upgrade).
</p>
<p>
To record a purchase consumption, send the {@code consumePurchase} method to
the In-app Billing service and pass in the {@code purchaseToken} String value
that identifies the purchase to be removed. The {@code purchaseToken} is part
of the data returned in the {@code INAPP_PURCHASE_DATA} String by the Google
Play service following a successful purchase request. In this example, you
are recording the consumption of a product that is identified with the {@code
purchaseToken} in the {@code token} variable.
</p>
<pre>
int response = mService.consumePurchase(3, getPackageName(), token);
</pre>
<p class="note"><strong>Warning:</strong> Do not call the {@code consumePurchase} method on the main thread. Calling this method triggers a network request which could block your main thread. Instead, create a separate thread and call the {@code consumePurchase} method from inside that thread.</p>
<p>It's your responsibility to control and track how the in-app product is provisioned to the user. For example, if the user purchased in-game currency, you should update the player's inventory with the amount of currency purchased.</p>
<p class="note"><strong>Security Recommendation:</strong> You must send a consumption request before provisioning the benefit of the consumable in-app purchase to the user. Make sure that you have received a successful consumption response from Google Play before you provision the item.</p>
<p class="note">
<strong>Warning:</strong> Do not call the {@code consumePurchase} method on
the main thread. Calling this method triggers a network request which could
block your main thread. Instead, create a separate thread and call the {@code
consumePurchase} method from inside that thread.
</p>
<p>
It's your responsibility to control and track how the in-app product is
provisioned to the user. For example, if the user purchased in-game currency,
you should update the player's inventory with the amount of currency
purchased.
</p>
<p class="note">
<strong>Security Recommendation:</strong> You must send a consumption request
before provisioning the benefit of the consumable in-app purchase to the
user. Make sure that you have received a successful consumption response from
Google Play before you provision the item.
</p>
<h3 id="Subs">Implementing Subscriptions</h3>
<p>Launching a purchase flow for a subscription is similar to launching the
purchase flow for a product, with the exception that the product type must be set
to "subs". The purchase result is delivered to your Activity's
{@link android.app.Activity#onActivityResult onActivityResult} method, exactly
as in the case of in-app products.</p>
<pre>
Bundle bundle = mService.getBuyIntent(3, "com.example.myapp",
MY_SKU, "subs", developerPayload);
@@ -363,12 +617,15 @@ if (bundle.getInt(RESPONSE_CODE) == BILLING_RESPONSE_RESULT_OK) {
Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0));
}
</pre>
<p>To query for active subscriptions, use the {@code getPurchases} method, again
with the product type parameter set to "subs".</p>
<pre>
Bundle activeSubs = mService.getPurchases(3, "com.example.myapp",
"subs", continueToken);
</pre>
<p>The call returns a {@code Bundle} with all the active subscriptions owned by
the user. Once a subscription expires without renewal, it will no longer appear
in the returned {@code Bundle}.</p>
@@ -383,7 +640,7 @@ Developer Console generates an RSA key pair for each application.<p>
<p class="note"><strong>Note:</strong>To find the public key portion of this key
pair, open your application's details in the Developer Console, then click on
<strong>Services & APIs</strong>, and look at the field titled
<strong>Services &amp; APIs</strong>, and look at the field titled
<strong>Your License Key for This Application</strong>.</p>
<p>The Base64-encoded RSA public key generated by Google Play is in binary
@@ -400,12 +657,3 @@ verification on that server.</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>