blob: 4e6e035afe568b6a29b098effaeff0b437cf76c6 [file] [log] [blame]
page.title=Purchasing In-app Billing Products
parent.title=Selling In-app Products
parent.link=index.html
trainingnavtop=true
previous.title=Establishing In-app Billing Products for Sale
previous.link=list-iab-products.html
next.title=Testing Your In-app Billing Application
next.link=test-iab-app.html
@jd:body
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you to</h2>
<ol>
<li><a href="#Purchase">Purchase an Item</a></li>
<li><a href="#QueryPurchases">Query Purchased Items</a></li>
<li><a href="#Consume">Consume a Purchase</a></li>
</ol>
<h2>You should also read</h2>
<ul>
<li><a href="{@docRoot}google/play/billing/billing_overview.html">In-app Billing
Overview</a></li>
</ul>
</div>
</div>
<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.</p>
<p>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.</p>
<p>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>
<h2 id="Purchase">Purchase an Item</h2>
<p>To start a purchase request from your app, call {@code launchPurchaseFlow(Activity, String, int, OnIabPurchaseFinishedListener, String)} on your {@code IabHelper} instance. You must make this call from the main thread of your {@code Activity}. Here’s an explaination of the {@code launchPurchaseFlow} method parameters:</p>
<ul>
<li>The first argument is the calling {@code Activity}.</li>
<li>The second argument is the product ID (also called its SKU) of the item to purchase. Make sure that you are providing the ID and not the product name. You must have previously defined and activated the item in the Developer Console, otherwise it won’t be recognized. </li>
<li>The third argument is a request code value. This value can be any positive integer. Google Play reurns this request code to the calling {@code Activity}’s {@code onActivityResult} along with the purchase response.</li>
<li>The fourth argument is a listener that is notified when the purchase operation has completed and handles the purchase response from Google Play.</li>
<li>The fifth argument contains a ‘developer payload’ string that you can use to send supplemental information about an order (it can be an empty string). Typically, this is used to pass in a string token that uniquely identifies this purchase request. If you specify a string value, Google Play returns this string along with the purchase response. Subsequently, when you make queries about this purchase, Google Play returns this string together with the purchase details. <p class="note"><strong>Security Recommendation:</strong> It’s good practice to pass in a string that helps your application to identify the user who made the purchase, so that you can later verify that this is a legitimate purchase by that user. For consumable items, you can use a randomly generated string, but for non-consumable items you should use a string that uniquely identifies the user.</p></li>
</ul>
<p>The following example shows how you can make a purchase request for a product with ID {@code SKU_GAS}, using an arbitrary value of 10001 for the request code, and an encoded developer payload string.</p>
<pre>
mHelper.launchPurchaseFlow(this, SKU_GAS, 10001,
mPurchaseFinishedListener, "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");
</pre>
<p>If the purchase order is successful, the response data from Google Play is stored in an {@code Purchase} object that is passed back to the listener.</p>
<p>The following example shows how you can handle the purchase response in the listener, depending on whether the purchase order was completed successfully, and whether the user purchased gas or a premium upgrade. In this example, gas is an in-app product that can be purchased multiple times, so you should consume the purchase to allow the user to buy it again. To learn how to consume purchases, see the <a href="{@docRoot}training/in-app-billing/purchase-iab-products.html#Consume">Consuming Products</a> section. The premium upgrade is a one-time purchase so you don’t need to consume it. It is good practice to update the UI immediately so that your users can see their newly purchased items.</p>
<pre>
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
= new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase)
{
if (result.isFailure()) {
Log.d(TAG, "Error purchasing: " + result);
return;
}
else if (purchase.getSku().equals(SKU_GAS)) {
// consume the gas and update the UI
}
else if (purchase.getSku().equals(SKU_PREMIUM)) {
// give user access to premium content and update the UI
}
}
};
</pre>
<p class="note"><strong>Security Recommendation:</strong> 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 in the {@code Purchase} object to make sure that you are getting the expected values. You should 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. As a further security precaution, you should perform the verification on your own secure server. </p>
<h2 id="QueryPurchases">Query Purchased Items</h2>
<p>Upon a successful purchase, the user’s purchase data is cached locally by Google Play’s In-app Billing service. It is good practice to frequently query the In-app Billing service for the user’s purchases, for example whenever the app starts up or resumes, so that the user’s current in-app product ownership information is always reflected in your app.</p>
<p>To retrieve the user’s purchases from your app, call {@code queryInventoryAsync(QueryInventoryFinishedListener)} on your {@code IabHelper} instance. The {@code QueryInventoryFinishedListener} argument specifies a listener that is notified when the query operation has completed and handles the query response. It is safe to make this call fom your main thread.</p>
<pre>
mHelper.queryInventoryAsync(mGotInventoryListener);
</pre>
<p>If the query is successful, the query results are stored in an {@code Inventory} object that is passed back to the listener. The In-app Billing service returns only the purchases made by the user account that is currently logged in to the device.</p>
<pre>
IabHelper.QueryInventoryFinishedListener mGotInventoryListener
= new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) {
if (result.isFailure()) {
// handle error here
}
else {
// does the user have the premium upgrade?
mIsPremium = inventory.hasPurchase(SKU_PREMIUM);
// update UI accordingly
}
}
};
</pre>
<h2 id="Consume">Consume a Purchase</h2>
<p>You can use the In-app Billing Version 3 API to track the ownership of purchased items in Google Play. Once an item is purchased, it is considered to be "owned" and cannot be purchased again from Google Play while in that state. You must send a consumption request for the item before Google Play makes it available for purchase again. All managed in-app products are consumable. How you use the consumption mechanism in your app is up to you. Typically, you would implement consumption for products with temporary benefits that users may want to purchase multiple times (for example, in-game currency or replenishable game tokens). You would typically not want to implement consumption for products that are purchased once and provide a permanent effect (for example, a premium upgrade).</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>To record a purchase consumption, call {@code consumeAsync(Purchase, OnConsumeFinishedListener)} on your {@code IabHelper} instance. The first argument that the method takes is the {@code Purchase} object representing the item to consume. The second argument is a {@code OnConsumeFinishedListener} that is notified when the consumption operation has completed and handles the consumption response from Google Play. It is safe to make this call fom your main thread.</p>
<p>In this example, you want to consume the gas item that the user has previously purchased in your app.</p>
<pre>
mHelper.consumeAsync(inventory.getPurchase(SKU_GAS),
mConsumeFinishedListener);
</pre>
<p>The following example shows how to implement the {@code OnConsumeFinishedListener}.</p>
<pre>
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase, IabResult result) {
if (result.isSuccess()) {
// provision the in-app purchase to the user
// (for example, credit 50 gold coins to player's character)
}
else {
// handle error
}
}
};
</pre>
<h3>Check for Consumable Items on Startup</h3>
<p>It’s important to check for consumable items when the user starts up your application. Typically, you would first query the In-app Billing service for the items purchased by the user (via {@code queryInventoryAsync}), then get the consumable {@code Purchase} objects from the Inventory. If your application detects that are any consumable items that are owned by the user, you should send a consumption request to Google Play immediately and provision the item to the user. See the {@code TrivialDrive} sample for an example of how to implement this checking at startup.</p>