diff options
-rw-r--r-- | docs/html/guide/guide_toc.cs | 2 | ||||
-rwxr-xr-x | docs/html/guide/market/billing/billing_about.jd | 63 | ||||
-rwxr-xr-x | docs/html/guide/market/billing/billing_admin.jd | 65 | ||||
-rwxr-xr-x | docs/html/guide/market/billing/billing_best_practices.jd | 13 | ||||
-rwxr-xr-x | docs/html/guide/market/billing/billing_integrate.jd | 198 | ||||
-rwxr-xr-x | docs/html/guide/market/billing/billing_overview.jd | 149 | ||||
-rwxr-xr-x | docs/html/guide/market/billing/billing_reference.jd | 119 | ||||
-rwxr-xr-x | docs/html/guide/market/billing/billing_testing.jd | 80 | ||||
-rwxr-xr-x | docs/html/guide/market/billing/index.jd | 20 | ||||
-rwxr-xr-x | docs/html/images/billing_product_list_entry.png | bin | 0 -> 78147 bytes | |||
-rwxr-xr-x | docs/html/images/billing_refund.png | bin | 0 -> 30801 bytes | |||
-rwxr-xr-x | docs/html/images/billing_request_purchase.png | bin | 38395 -> 38108 bytes | |||
-rwxr-xr-x | docs/html/images/billing_restore_transactions.png | bin | 27521 -> 25999 bytes |
13 files changed, 411 insertions, 298 deletions
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index 24e4648..a898545 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -364,7 +364,7 @@ <li class="toggle-list"> <div><a href="<?cs var:toroot?>guide/market/billing/index.html"> <span class="en">In-app Billing</span></a> - <span class="new">new!</span> + <span class="new">updated</span> </div> <ul> <li><a href="<?cs var:toroot?>guide/market/billing/billing_about.html"> diff --git a/docs/html/guide/market/billing/billing_about.jd b/docs/html/guide/market/billing/billing_about.jd index dac9738..ed45c19 100755 --- a/docs/html/guide/market/billing/billing_about.jd +++ b/docs/html/guide/market/billing/billing_about.jd @@ -3,12 +3,6 @@ parent.title=In-app Billing parent.link=index.html @jd:body -<style type="text/css"> - #jd-content { - background:transparent url({@docRoot}assets/images/preliminary.png) repeat scroll 0 0; - } -</style> - <div id="qv-wrapper"> <div id="qv"> <h2>In this document</h2> @@ -31,15 +25,9 @@ parent.link=index.html </div> </div> -<div class="special" style="margin-right:345px"> - <p>This documentation provides an early look at the Android Market In-app Billing service. The documentation may change without notice.</p> -</div> - -<p>This documentation gives you an early look at the Android Market In-app Billing service. We are providing this documentation to help you get started designing your in-app billing implementation. </p> +<p>The in-app billing release has now entered the testing phase. During this phase we are providing <a href="{@docRoot}guide/market/billing/index.html">documentation</a> and a <a href="{@docRoot}guide/market/billing/billing_integrate.html#billing-download">sample application</a> that shows you how to implement in-app billing. You can use these resources to start designing and testing your in-app billing implementations.</p> -<p>In addition to this documentation, we are providing a <a href="{@docRoot}guide/market/billing/billing_integrate.html#billing-download">sample application</a> that shows you how to implement in-app billing. Although you can compile the sample application, load it on a device, and run it, you cannot use it to make purchases at this time. In-app billing relies on version 2.3.0 (and higher) of the Android Market application, which may not be available yet.</p> - -<p>In the coming weeks we plan to launch the testing phase of the in-app billing release. Following the testing phase we will launch in-app billing to the general public (see table 1 for a summary of upcoming launch milestones). +<p>Following the testing phase we will launch in-app billing to the general public (see table 1 for a summary launch milestones). <p class="table-caption"><strong>Table 1.</strong> Summary of launch milestones for in-app billing.</p> @@ -47,29 +35,56 @@ parent.link=index.html <tr> <th>Release Phase</th> -<th>Android Market Application</th> +<th>Status</th> <th>Description</th> </tr> <tr> <td>Early Development</td> - <td>Version 2.3.0 not available</td> - <td>Provides an early look at documentation and sample application.</td> + <td>Completed</td> + <td>Provided an early look at the documentation and the sample application.</td> </tr> <tr> <td>Test Development</td> - <td>Version 2.3.0 available to developers and users</td> - <td>In-app billing service allows static testing with reserved product IDs. You cannot publish applications that use in-app billing.</td> + <td>In process</td> + <td>You can perform static testing with reserved product IDs and end-to-end testing with real product IDs. You cannot publish applications that use in-app billing.</td> </tr> <tr> <td>Final Release</td> - <td>Version 2.3.0 available to developers and users</td> - <td>In-app billing service allows end-to-end testing of in-app billing. You can publish applications that use in-app billing.</td> + <td>Coming soon</td> + <td>You can perform static testing with reserved product IDs and end-to-end testing with real product IDs. You can publish applications that use in-app billing.</td> +</tr> + +</table> + +<p>During the testing phase we are releasing version 2.3.4 of the Android Market application and version 5.0.12 of the MyApps application. To support in-app billing, devices running Android 3.0 must have version 5.0.12 (or higher) of the MyApps application. Devices running all other versions of Android must have version 2.3.4 (or higher) of the Android Market application. Table 2 summarizes these requirements.</p> + +<p class="table-caption"><strong>Table 2.</strong> Summary of in-app billing requirements.</p> + +<table> + +<tr> +<th>If your device is running this...</th> +<th>In-app billing requires this</th> +</tr> +<tr> + <td>Android 1.6</td> + <td>Android Market 2.3.4 (or higher)</td> +</tr> +<tr> + <td>Android 2.x</td> + <td>Android Market 2.3.4 (or higher)</td> +</tr> +<tr> + <td>Android 3.0</td> + <td>MyApps 5.0.12 (or higher)</td> </tr> </table> -<p>During the testing phase we will release version 2.3.0 of the Android Market application. This will allow you to test your in-app billing implementation using the <a href="{@docRoot}guide/market/billing/billing_testing.html#billing-testing-static">reserved product IDs and test responses</a>. However, you will not be able to test end-to-end in-app purchases during the testing phase, and you will not be able to publish an application that uses in in-app billing. </p> +<p class="note"><strong>Note:</strong> To learn how to check the version of the Android Market application, see <a href="http://market.android.com/support/bin/answer.py?answer=190860">Updating Android Market</a>. To learn about other requirements for in-app billing, see <a href="{@docRoot}guide/market/billing/billing_overview.html#billing-limitations">Requirements and Limitations.</a></p> + +<p>You can test your in-app billing implementation two ways during the testing phase: you can use the <a href="{@docRoot}guide/market/billing/billing_testing.html#billing-testing-static">reserved product IDs</a> to test static responses or you can use <a href="{@docRoot}guide/market/billing/billing_testing.html#billing-testing-real">your own product IDs</a> to test end-to-end in-app purchases. To perform end-to-end testing you need to upload your application as a draft application and add products to the application's product list.</p> -<p>After the testing phase is complete, we will release in-app billing to the general public. This will enable you to perform end-to-end tests of your in-app billing implementation using your actual in-app products. You will also be able to publish applications that use in-app billing.</p> +<p>During the testing phase, you cannot publish applications that use in-app billing; you can only upload the applications as draft applications. After the testing phase is complete, we will launch in-app billing to the general public and you will be able to publish applications that use in-app billing.</p> -<p>This documentation may change in the coming weeks as we move from the preview phase to the testing phase of this beta release. Be sure to check this documentation frequently for updates.</p>
\ No newline at end of file +<p>This documentation may change as we move from the testing phase to the final release. Be sure to check this documentation frequently for updates.</p> diff --git a/docs/html/guide/market/billing/billing_admin.jd b/docs/html/guide/market/billing/billing_admin.jd index cd8f960..16a2a36 100755 --- a/docs/html/guide/market/billing/billing_admin.jd +++ b/docs/html/guide/market/billing/billing_admin.jd @@ -3,12 +3,6 @@ parent.title=In-app Billing parent.link=index.html @jd:body -<style type="text/css"> - #jd-content { - background:transparent url({@docRoot}assets/images/preliminary.png) repeat scroll 0 0; - } -</style> - <div id="qv-wrapper"> <div id="qv"> <h2>In this document</h2> @@ -35,25 +29,32 @@ parent.link=index.html </div> <div class="special" style="margin-right:345px"> - <p>This documentation provides an early look at the Android Market In-app Billing service. The documentation may change without notice.</p> + <p>During the testing phase of the in-app billing release you cannot publish applications that implement in-app billing. You can only upload in-app billing applications as draft applications. For more information, see <a href="{@docRoot}guide/market/billing/billing_about.html">About this Release</a></p> </div> <p>In-app billing frees you from processing financial transactions, but you still need to perform a few administrative tasks, including setting up and maintaining your product list on the publisher site, registering test accounts, and handling refunds when necessary.</p> -<p>You must have an Android Market publisher account to set up a product list and register test accounts. And you must have a Google Checkout merchant account to issue refunds to your users. If you already have a publisher account on Android Market, you can use your existing account. You do not need to register for a new account to support in-app billing. If you do not have a publisher account, you can register as an Android Market developer and set up a publisher account at the Android Market <a href="http://market.android.com/publish">publisher site</a>. If you do not have a Google Checkout merchant account, you can register for one at the <a href="http://checkout.google.com">Google Checkout site</a>.</p> +<p>You must have an Android Market publisher account to register test accounts. And you must have a Google Checkout Merchant account to create a product list and issue refunds to your users. If you already have a publisher account on Android Market, you can use your existing account. You do not need to register for a new account to support in-app billing. If you do not have a publisher account, you can register as an Android Market developer and set up a publisher account at the Android Market <a href="http://market.android.com/publish">publisher site</a>. If you do not have a Google Checkout Merchant account, you can register for one at the <a href="http://checkout.google.com">Google Checkout site</a>.</p> <h2 id="billing-list-setup">Creating a Product List</h2> <p>The Android Market publisher site provides a product list for each of your published applications. You can sell an item using the in-app billing feature only if the item is listed on an application's product list. Each application has its own product list; you cannot sell items that are listed in another application's product list.</p> -<p>A product list contains information about the items you are selling, such as a product id, product description, and price (see figure 1). The product list stores only metadata about the items you are selling in your application. It does not store any digital content. You are responsible for storing and delivering the digital content that you sell in your applications.</p> +<p>You can access an application's product list by clicking the <strong>In-App Products</strong> link that appears under each of the applications that are listed for your publisher account (see figure 1). The <strong>In-App Products</strong> link appears only if you have a Google Checkout Merchant account and an application's manifest includes the <code>com.android.vending.BILLING</code> permission.</p> -<div style="margin-bottom:2em;"> -<img src="{@docRoot}images/billing_product_list.png" style="text-align:left;margin-bottom:0;" /> -<div style="margin:0 2em;padding:0"><strong>Figure 1.</strong> An application's product list.</div> -</div> +<img src="{@docRoot}images/billing_product_list_entry.png" height="540" id="figure1" /> +<p class="img-caption"> + <strong>Figure 1.</strong> You can access an application's product list by clicking the <strong>In-App Products</strong> link. +</p> + +<p>A product list contains information about the items you are selling, such as a product id, product description, and price (see figure 2). The product list stores only metadata about the items you are selling in your application. It does not store any digital content. You are responsible for storing and delivering the digital content that you sell in your applications.</p> + +<img src="{@docRoot}images/billing_product_list.png" height="742" id="figure2" /> +<p class="img-caption"> + <strong>Figure 2.</strong> An application's product list. +</p> -<p>You can create a product list for a published application or a draft application that's been uploaded and saved to the Android Market site. However, the application's manifest must include the com.android.vending.BILLING permission. If an application's manifest does not include this permission, you will be able to edit existing items in the product list but you will not be able to add new items to the list. For more information, see <a href="#billing-permission">Modifying your application's AndroidManifest.xml file</a>.</p> +<p>You can create a product list for a published application or a draft application that's been uploaded and saved to the Android Market site. However, you must have a Google Checkout Merchant account and the application's manifest must include the <code>com.android.vending.BILLING</code> permission. If an application's manifest does not include this permission, you will be able to edit existing items in the product list but you will not be able to add new items to the list. For more information, see <a href="#billing-permission">Modifying your application's AndroidManifest.xml file</a>.</p> <p>To create a product list for an application, follow these steps:</p> @@ -61,13 +62,13 @@ parent.link=index.html <li><a href="http://market.android.com/publish">Log in</a> to your publisher account.</li> <li>In the <strong>All Android Market listings</strong> panel, under the application name, click <strong>In-app Products</strong>.</li> <li>On the In-app Products List page, click <strong>Add in-app product</strong>.</li> - <li>On the Create New In-app Product page (see figure 2), provide details about the item you are selling and then click <strong>Save</strong>.</li> + <li>On the Create New In-app Product page (see figure 3), provide details about the item you are selling and then click <strong>Save</strong>.</li> </ol> -<div style="margin-bottom:2em;"> -<img src="{@docRoot}images/billing_list_form.png" style="text-align:left;margin-bottom:0;" /> -<div style="margin:0 2em;padding:0"><strong>Figure 2.</strong> The Create New In-app Product page lets you add items to an application's product list.</div> -</div> +<img src="{@docRoot}images/billing_list_form.png" height="854" id="figure3" /> +<p class="img-caption"> + f<strong>Figure 3.</strong> The Create New In-app Product page lets you add items to an application's product list. +</p> <p>You must enter the following information for each item in a product list:</p> <ul> @@ -79,23 +80,26 @@ parent.link=index.html <p>The purchase type can be "managed per user account" or "unmanaged." You can specify an item's purchase type only through the publisher site and you can never change an item's purchase type once you specify it. For more information, see <a href="#billing_purchase_type">Choosing a purchase type</a> later in this document.</p> </li> <li><strong>Publishing State</strong> - <p>An item's publishing state can be "published" or "unpublished." However, to be visible to a user during checkout, an item's publishing state must be set to "published" and the item's application must be published on Android Market. (Note: This is not true for test accounts: that is, an item is visible to a trusted tester if the application is not published and the item is published. See <a href="{@docRoot}guide/market/billing/billing_testing.html#billing-testing-real">Testing In-app Billing</a> for more information.)</p> + <p>An item's publishing state can be "published" or "unpublished." However, to be visible to a user during checkout, an item's publishing state must be set to "published" and the item's application must be published on Android Market.</p> + <p class="note"><strong>Note:</strong> This is not true for test accounts. An item is visible to a test account if the application is not published and the item is published. See <a href="{@docRoot}guide/market/billing/billing_testing.html#billing-testing-real">Testing In-app Billing</a> for more information.</p> </li> <li><strong>Language</strong> <p>A product list inherits its language from the parent application.</p> </li> <li><strong>Title</strong> - <p>The title is a short descriptor for the item. For example, "sleeping potion." Titles must be unique across an application's namespace. Every item must have a title. The title is visible to users during checkout.</p> + <p>The title is a short descriptor for the item. For example, "Sleeping potion." Titles must be unique across an application's namespace. Every item must have a title. The title is visible to users during checkout. For optimum appearance, titles should be no longer than 25 characters; however, titles can be up to 55 characters in length.</p> </li> <li><strong>Description</strong> - <p>The description is a long descriptor for the item. For example, "Instantly puts creatures to sleep. Does not work on angry elves." Every item must have a description. The description is visible to users during checkout.</p> + <p>The description is a long descriptor for the item. For example, "Instantly puts creatures to sleep. Does not work on angry elves." Every item must have a description. The description is visible to users during checkout. Descriptions can be up to 80 characters in length.</p> </li> <li><strong>Price</strong> - <p>Every item must have a price greater than zero; you cannot sell free items.</p> + <p>Every item must have a price greater than zero; you cannot set a price of "0" (free).</p> </li> </ul> -<p class="note"><strong>Note</strong>: Be sure to plan your product ID namespace. You cannot reuse or modify product IDs after you save them.</p> +<p>For more information about product IDs and product lists, see <a href="http://market.android.com/support/bin/answer.py?answer=1072599">Creating In-App Product IDs</a>. For more information about pricing, see <a href="http://market.android.com/support/bin/answer.py?answer=1153485">In-App Billing Pricing</a>.</p> + +<p class="note"><strong>Note</strong>: Be sure to plan your product ID namespace. You cannot reuse or modify product IDs after you save them.</p> <h3 id="billing-purchase-type">Choosing a Purchase Type</h3> @@ -113,7 +117,7 @@ parent.link=index.html <h2 id="billing-refunds">Handling Refunds</h2> -<p>The in-app billing feature does not allow users to send a refund request to Android Market. Refunds for purchases that were made with the in-app billing feature must be directed to you (the application developer). You can then process the refund through your Google Checkout merchant account. When you do this, Android Market receives a refund notification from Google Checkout, and Android Market sends a refund message to your application. 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 purchase state change message that includes information about the item that's been refunded.</p> +<p>The in-app billing feature does not allow users to send a refund request to Android Market. Refunds for purchases that were made with the in-app billing feature must be directed to you (the application developer). You can then process the refund through your Google Checkout Merchant account. When you do this, Android Market receives a refund notification from Google Checkout, and Android Market sends a refund message to your application. For more information, see <a href="{@docRoot}guide/market/billing/billing_overview.html#billing-action-notify">Handling IN_APP_NOTIFY messages</a> and <a href="http://www.google.com/support/androidmarket/bin/answer.py?answer=1153485">In-app Billing Pricing</a>.</p> <h2 id="billing-testing-setup">Setting Up Test Accounts</h2> @@ -134,16 +138,15 @@ parent.link=index.html <ol> <li><a href="http://market.android.com/publish">Log in</a> to your publisher account.</li> <li>On the upper left part of the page, under your name, click <strong>Edit profile</strong>.</li> - <li>On the Edit Profile page, scroll down to the Licensing & In-app Billing panel (see figure 3).</li> + <li>On the Edit Profile page, scroll down to the Licensing & In-app Billing panel (see figure 4).</li> <li>In Test Accounts, add the email addresses for the test accounts you want to register, separating each account with a comma.</li> <li>Click <strong>Save</strong> to save your profile changes.</li> </ol> -<div style="margin-bottom:2em;"> -<img src="{@docRoot}images/billing_public_key.png" style="text-align:left;margin-bottom:0;" /> -<div style="margin:0 2em;padding:0"><strong>Figure 3.</strong> The Licensing and In-app Billing -panel of your account's Edit Profile page lets you register test accounts.</div> -</div> +<img src="{@docRoot}images/billing_public_key.png" height="510" id="figure4" /> +<p class="img-caption"> + <strong>Figure 4.</strong> The Licensing and In-app Billing panel of your account's Edit Profile page lets you register test accounts. +</p> <h2 id="billing-support">Where to Get Support</h2> diff --git a/docs/html/guide/market/billing/billing_best_practices.jd b/docs/html/guide/market/billing/billing_best_practices.jd index 4743e88..a505de4 100755 --- a/docs/html/guide/market/billing/billing_best_practices.jd +++ b/docs/html/guide/market/billing/billing_best_practices.jd @@ -3,12 +3,6 @@ parent.title=In-app Billing parent.link=index.html @jd:body -<style type="text/css"> - #jd-content { - background:transparent url({@docRoot}assets/images/preliminary.png) repeat scroll 0 0; - } -</style> - <div id="qv-wrapper"> <div id="qv"> <h2>In this document</h2> @@ -31,9 +25,10 @@ parent.link=index.html </div> <div class="special" style="margin-right:345px"> - <p>This documentation provides an early look at the Android Market In-app Billing service. The documentation may change without notice.</p> + <p>During the testing phase of the in-app billing release you cannot publish applications that implement in-app billing. You can only upload in-app billing applications as draft applications. For more information, see <a href="{@docRoot}guide/market/billing/billing_about.html">About this Release</a></p> </div> -<p>As you design your in-app billing implementation, be sure to follow the security and design guidelines that are discussed in this document. These guidelines are recommended best practices for anyone who is using the Android Market In-app Billing service and can be incorporated into any in-app billing implementation.</p> + +<p>As you design your in-app billing implementation, be sure to follow the security and design guidelines that are discussed in this document. These guidelines are recommended best practices for anyone who is using the Android Market in-app billing service and can be incorporated into any in-app billing implementation.</p> <h2>Security Best Practices</h2> @@ -58,7 +53,7 @@ parent.link=index.html </ul> <p>Using these techniques can help reduce the attack surface of your application and help minimize attacks that can compromise your in-app billing implementation.</p> <div class="note"> - <p><strong>Note:</strong> If you use Proguard to obfuscate your code, you must add the following line to your Proguard configuration file:</p> + <p><strong>Note:</strong> If you use Proguard to obfuscate your code, you must add the following line to your Proguard configuration file:</p> <p><code>-keep class com.android.vending.billing.**</code></p> </div> diff --git a/docs/html/guide/market/billing/billing_integrate.jd b/docs/html/guide/market/billing/billing_integrate.jd index 0cac2eb..d027686 100755 --- a/docs/html/guide/market/billing/billing_integrate.jd +++ b/docs/html/guide/market/billing/billing_integrate.jd @@ -3,12 +3,6 @@ parent.title=In-app Billing parent.link=index.html @jd:body -<style type="text/css"> - #jd-content { - background:transparent url({@docRoot}assets/images/preliminary.png) repeat scroll 0 0; - } -</style> - <div id="qv-wrapper"> <div id="qv"> <h2>In this document</h2> @@ -16,7 +10,7 @@ parent.link=index.html <li><a href="#billing-download">Downloading the Sample Application</a></li> <li><a href="#billing-add-aidl">Adding the AIDL file to your project</a></li> <li><a href="#billing-permission">Updating Your Application's Manifest</a></li> - <li><a href="#billing-service">Creating a Service</a></li> + <li><a href="#billing-service">Creating a Service</a></li> <li><a href="#billing-broadcast-receiver">Creating a BroadcastReceiver</a></li> <li><a href="#billing-signatures">Creating a security processing component</a></li> <li><a href="#billing-implement">Modifying Your Application Code</a></li> @@ -37,10 +31,10 @@ parent.link=index.html </div> <div class="special" style="margin-right:345px"> - <p>This documentation provides an early look at the Android Market In-app Billing service. The documentation may change without notice.</p> + <p>During the testing phase of the in-app billing release you cannot publish applications that implement in-app billing. You can only upload in-app billing applications as draft applications. For more information, see <a href="{@docRoot}guide/market/billing/billing_about.html">About this Release</a></p> </div> -<p>The Android Market In-app Billing service provides a straightforward, simple interface for sending in-app billing requests and managing in-app billing transactions using Android Market. This document helps you implement in-app billing by stepping through the primary implementation tasks, using the in-app billing sample application as an example.</p> +<p>The Android Market in-app billing service provides a straightforward, simple interface for sending in-app billing requests and managing in-app billing transactions using Android Market. This document helps you implement in-app billing by stepping through the primary implementation tasks, using the in-app billing sample application as an example.</p> <p>Before you implement in-app billing in your own application, be sure that you read <a href="{@docRoot}guide/market/billing/billing_overview.html">Overview of In-app Billing</a> and <a href="{@docRoot}guide/market/billing/billing_best_practices.html">Security and Design</a>. These documents provide background information that will make it easier for you to implement in-app billing.</p> @@ -67,7 +61,7 @@ parent.link=index.html <li>Creating a user interface that lets users select items for purchase.</li> </ul> -<p>The sample application includes an application file (<code><code>Dungeons.java</code></code>), the AIDL file for the <code>MarketBillingService</code> (<code>IMarketBillingService.aidl</code>), and several classes that demonstrate in-app billing messaging. It also includes a class that demonstrates basic security tasks, such as signature verification.</p> +<p>The sample application includes an application file (<code>Dungeons.java</code>), the AIDL file for the <code>MarketBillingService</code> (<code>IMarketBillingService.aidl</code>), and several classes that demonstrate in-app billing messaging. It also includes a class that demonstrates basic security tasks, such as signature verification.</p> <p>Table 1 lists the source files that are included with the sample application.</p> <p class="table-caption" id="source-files-table"><strong>Table 1.</strong> @@ -86,7 +80,7 @@ In-app billing sample application source files.</p> <tr> <td>Dungeons.java</td> -<td>Sample application file that provides a UI for making purchases and diplaying purchase history.</td> +<td>Sample application file that provides a UI for making purchases and displaying purchase history.</td> </tr> <tr> @@ -130,19 +124,101 @@ In-app billing sample application source files.</p> </table> -<p>The in-app billing sample application is available as a downloadable component of the Android SDK. To download the sample application component, launch the Android SDK and AVD Manager and then select the "Market Billing package, revision 1" component (see figure 1), and click <strong>Install Selected</strong> to begin the download.</p> +<p>The in-app billing sample application is available as a downloadable component of the Android SDK. To download the sample application component, launch the Android SDK and AVD Manager and then select the "Google Market Billing package" component (see figure 1), and click <strong>Install Selected</strong> to begin the download.</p> <div style="margin-bottom:2em;"> -<img src="{@docRoot}images/billing_package.png" style="text-align:left;margin-bottom:0;" /> -<div style="margin:0 2em;padding:0"><strong>Figure 1.</strong> The Google Market -Billing package contains the sample application and the AIDL file. </div> -</div> +<img src="{@docRoot}images/billing_package.png" height="325" id="figure1" /> +<p class="img-caption"> + <strong>Figure 1.</strong> The Google Market Billing package contains the sample application and the AIDL file. +</p> <p>When the download is complete, the Android SDK and AVD Manager saves the component into the following directory:</p> <p><code><sdk>/google-market_billing/</code></p> +<p>If you want to see an end-to-end demonstration of in-app billing before you integrate in-app billing into your own application, you can build and run the sample application. Building and running the sample application involves three tasks:<p> + +<ul> + <li>Configuring and building the sample application.</li> + <li>Uploading the sample application to Android Market.</li> + <li>Setting up test accounts and running the sample application</li> +</ul> + +<p class="note"><strong>Note:</strong> Building and running the sample application is necessary only if you want to see a demonstration of in-app billing. If you do not want to run the sample application, you can skip to the next section, <a href="#billing-add-aidl">Adding the AIDL file to your project</a>.</p> + +<h3>Configuring and building the sample application</h3> + +<p>Before you can run the sample application, you need to configure it and build it by doing the following:</p> + +<ol> + <li><strong>Add your Android Market public key to the sample application code.</strong> + <p>This enables the application to verify the signature of the transaction information that is returned from Android Market. To add your public key to the sample application code, do the following:</p> + <ol> + <li>Log in to your Android Market <a href="http://market.android.com/publish">publisher account</a>.</li> + <li>On the upper left part of the page, under your name, click <strong>Edit Profile</strong>.</li> + <li>On the Edit Profile page, scroll down to the <strong>Licensing & In-app Billing</strong> panel.</li> + <li>Copy your public key.</li> + <li>Open <code>src/com/example/dungeons/Security.java</code> in the editor of your choice. + <p>You can find this file in the sample application's project folder.</p> + </li> + <li>Add your public key to the following line of code: + <p><code>String base64EncodedPublicKey = "your public key here";</code></p> + </li> + <li>Save the file.</li> + </ol> + </li> + <li><strong>Change the package name of the sample application.</strong> + <p>The current package name is <code>com.example.dungeons</code>. Android Market does not let you upload applications with package names that contain <code>com.example</code>, so you must change the package name to something else.</p> + </li> + <li><strong>Build the sample application in release mode and sign it.</strong> + <p>To learn how to build and sign applications, see <a href="{@docRoot}guide/developing/building/index.html">Building and Running</a>.</p> + </li> +</ol> + +<h3>Uploading the sample application</h3> + +<p>After you build a release version of the sample application and sign it, you need to upload it as a draft to the Android Market publisher site. You also need to create a product list for the in-app items that are available for purchase in the sample application. The following instructions show you how to do this.</p> +<ol> + <li><strong>Upload the release version of the sample application to Android Market.</strong> + <p>Do not publish the sample application; leave it as an unpublished draft application. The sample application is for demonstration purposes only and should not be made publicly available on Android Market. To learn how to upload an application to Android Market, see <a href="http://market.android.com/support/bin/answer.py?answer=113469">Uploading applications</a>.</p> + </li> + <li><strong>Create a product list for the sample application.</strong> + <p>The sample application lets you purchase two items: a two-handed sword (<code>sword_001</code>) and a potion (<code>potion_001</code>). We recommend that you set up your product list so that <code>sword_001</code> has a purchase type of "Managed per user account" and <code>potion_001</code> has a purchase type of "Unmanaged" so you can see how these two purchase types behave. To learn how to set up a product list, see <a href="{@docRoot}guide/market/billing/billing_admin.html#billing-list-setup">Creating a Product List</a>.</p> + <p class="note"><strong>Note:</strong> You must publish the items in your product list (<code>sword_001</code> and <code>potion_001</code>) even though you are not publishing the sample application. Also, you must have a Google Checkout Merchant account to add items to the sample application's product list.</p> + </li> +</ol> + +<h3>Running the sample application</h3> + +<p>You cannot run the sample application in the emulator. You must install the sample application onto a device to run it. To run the sample application, do the following:</p> + +<ol> + <li><strong>Make sure you have at least one test account registered under your Android Market publisher account.</strong> + <p>You cannot purchase items from yourself (Google Checkout prohibits this), so you need to create at least one test account that you can use to purchase items in the sample application. To learn how to set up a test account, see <a href="{@docRoot}guide/market/billing/billing_testing.html#billing-testing-setup">Setting up Test Accounts</a>.</p> + </li> + <li><strong>Verify that your device is running a supported version of the Android Market application or the MyApps application.</strong> + <p>If your device is running Android 3.0, in-app billing requires version 5.0.12 (or higher) of the MyApps application. If your device is running any other version of Android, in-app billing requires version 2.3.4 (or higher) of the Android Market application. To learn how to check the version of the Android Market application, see <a href="http://market.android.com/support/bin/answer.py?answer=190860">Updating Android Market</a>.</p> + </li> + <li><strong>Install the application onto your device.</strong> + <p>Even though you uploaded the application to Android Market, the application is not published, so you cannot download it from Android Market to a device. Instead, you must install the application onto your device. To learn how to install an application onto a device, see <a href="{@docRoot}guide/developing/building/building-cmdline.html#RunningOnDevice">Running on a device</a>.</p> + </li> + <li><strong>Make one of your test accounts the primary account on your device.</strong> + <p>The primary account on your device must be one of the <a href="{@docRoot}guide/market/billing/billing_admin.html#billing-testing-setup">test accounts</a> that you registered on the Android Market site. If the primary account on your device is not a test account, you must do a factory reset of the device and then sign in with one of your test accounts. To perform a factory reset, do the following:</p> + <ol> + <li>Open Settings on your device.</li> + <li>Touch <strong>Privacy</strong>.</li> + <li>Touch <strong>Factory data reset</strong>.</li> + <li>Touch <strong>Reset phone</strong>.</li> + <li>After the phone resets, be sure to sign in with one of your test accounts during the device setup process.</li> + </ol> + </li> + <li><strong>Run the application and purchase the sword or the potion.</strong> + <p>When you use a test account to purchase items, the test account is billed through Google Checkout and your Google Checkout Merchant account receives a payout for the purchase. Therefore, you may want to refund purchases that are made with test accounts, otherwise the purchases will show up as actual payouts to your merchant account.</p> +</ol> + +<p class="note"><strong>Note</strong>: Debug log messages are turned off by default in the sample application. You can turn them on by setting the variable <code>DEBUG</code> to <code>true</code> in the <code>Consts.java</code> file.</p> + <h2 id="billing-add-aidl">Adding the AIDL file to your project</h2> <p>The sample application contains an Android Interface Definition Language (AIDL) file, which defines the interface to the Android Market in-app billing service <code>MarketBillingService</code>). When you add this file to your project, the Android build environment creates an interface file (<code>IMarketBillingService.java</code>). You can then use this interface to make billing requests by invoking IPC method calls.</p> @@ -159,15 +235,15 @@ Billing package contains the sample application and the AIDL file. </div> <li>Build your application.</li> </ol> -<p>You should now find a generated interface file named <code><code>IMarketBillingService.java</code></code> in the <code>gen</code> folder of your project.</p> +<p>You should now find a generated interface file named <code>IMarketBillingService.java</code> in the <code>gen</code> folder of your project.</p> <h2 id="billing-permission">Updating Your Application's Manifest</h2> <p>In-app billing relies on the Android Market application, which handles all communication between your application and the Android Market server. To use the Android Market application, your application must request the proper permission. You can do this by adding the <code>com.android.vending.BILLING</code> permission to your AndroidManifest.xml file. If your application does not declare the in-app billing permission, but attempts to send billing requests, Android Market will refuse the requests and respond with a <code>RESULT_DEVELOPER_ERROR</code> response code.</p> -<p>In addition to the billing permission, you need to declare the {@link android.content.BroadcastReceiver} that you will use to receive asynchronous response messages (broadcast intents) from Android Market, and you need to declare the {@link android.app.Service} that you will use to bind with the <code>IMarketBillingService</code> and send messages to Android Market. You must also declare <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">intent filters</a> for the {@link android.content.BroadcastReceiver} so that the Android system knows how to handle broadcast intents that are sent from the Android Market application.</p> +<p>In addition to the billing permission, you need to declare the {@link android.content.BroadcastReceiver} that you will use to receive asynchronous response messages (broadcast intents) from Android Market, and you need to declare the {@link android.app.Service} that you will use to bind with the <code>IMarketBillingService</code> and send messages to Android Market. You must also declare <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">intent filters</a> for the {@link android.content.BroadcastReceiver} so that the Android system knows how to handle the broadcast intents that are sent from the Android Market application.</p> -<p>For example, here's how the in-app billing sample application declares the billing permission, the {@link android.content.BroadcastReceiver}, the {@link android.app.Service}, and the intent filters. In the sample application, <code>BillingReceiver</code> is the {@link android.content.BroadcastReceiver} that handles broadcast intents from the Android Market application and <code>BillingService</code> is the {@link android.app.Service} that sends requests to the Android Market application.</p> +<p>For example, here is how the in-app billing sample application declares the billing permission, the {@link android.content.BroadcastReceiver}, the {@link android.app.Service}, and the intent filters. In the sample application, <code>BillingReceiver</code> is the {@link android.content.BroadcastReceiver} that handles broadcast intents from the Android Market application and <code>BillingService</code> is the {@link android.app.Service} that sends requests to the Android Market application.</p> <pre> <?xml version="1.0" encoding="utf-8"?> @@ -236,7 +312,7 @@ try { } </pre> -<p>After you bind to the service, you need to create a reference to the <code>IMarketBillingService</code> interface so you can make billing requests via IPC method calls. The following code shows you how to do this using the {@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback method.</p> +<p>After you bind to the service, you need to create a reference to the <code>IMarketBillingService</code> interface so you can make billing requests via IPC method calls. The following code shows you how to do this using the {@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback method.</p> <pre> /** @@ -265,7 +341,7 @@ try { <li><code>RESTORE_TRANSACTIONS</code>—retrieves a user's transaction history for <a href="{@docRoot}guide/market/billing/billing_admin.html#billing-purchase-type">managed purchases</a>.</li> </ul> -<p>To make any of these billing requests, you first need to build an initial Bundle that contains the three keys that are required for all requests: <code>BILLING_REQUEST</code>, <code>API_VERSION</code>, and <code>PACKAGE_NAME</code>. The following code sample shows you how to create a helper method named <code>makeRequestBundle()</code> that does this.</p> +<p>To make any of these billing requests, you first need to build an initial {@link android.os.Bundle} that contains the three keys that are required for all requests: <code>BILLING_REQUEST</code>, <code>API_VERSION</code>, and <code>PACKAGE_NAME</code>. The following code sample shows you how to create a helper method named <code>makeRequestBundle()</code> that does this.</p> <pre> protected Bundle makeRequestBundle(String method) { @@ -296,13 +372,17 @@ protected Bundle makeRequestBundle(String method) { <p>The <code>makeRequestBundle()</code> method constructs an initial Bundle, which contains the three keys that are required for all requests: <code>BILLING_REQUEST</code>, <code>API_VERSION</code>, and <code>PACKAGE_NAME</code>. The request returns a synchronous {@link android.os.Bundle} response, which contains only a single key: <code>RESPONSE_CODE</code>. The <code>RESPONSE_CODE</code> key can have the following values:</p> <ul> <li><code>RESULT_OK</code>—in-app billing is supported.</li> - <li><code>RESULT_BILLING_UNAVAILABLE</code>—in-app billing is not supported or the in-app billing API version you specified is not recognized.</li> - <li><code>RESULT_ERROR</code>—there was an error connecting with the Android Market appliction.</li> - <li><code>RESULT_DEVELOPER_ERROR</code>—the 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.</li> + <li><code>RESULT_BILLING_UNAVAILABLE</code>—in-app billing is not available because the in-app billing API version you specified is not recognized or the user is not eligible to make in-app purchases (for example, the user resides in a country that prohibits in-app purchases).</li> + <li><code>RESULT_ERROR</code>—there was an error connecting with the Android Market application.</li> + <li><code>RESULT_DEVELOPER_ERROR</code>—the application is trying to make an in-app billing request but the application has not declared the <code>com.android.vending.BILLING</code> permission in its manifest. Can also indicate that an application is not properly signed, or that you sent a malformed request.</li> </ul> <p>The <code>CHECK_BILLING_SUPPORTED</code> request does not trigger any asynchronous responses (broadcast intents).</p> +<p>We recommend that you invoke the <code>CHECK_BILLING_SUPPORTED</code> request within a <code>RemoteException</code> block. When your code throws a <code>RemoteException</code> it indicates that the remote method call failed, which means that the Android Market application is out of date and needs to be updated. In this case, you can provide users with an error message that contains a link to the <a href="http://market.android.com/support/bin/answer.py?answer=190860">Updating Android Market</a> Help topic.</p> + +<p>The sample application demonstrates how you can handle this error condition (see <code>DIALOG_CANNOT_CONNECT_ID</code> in <code>Dungeons.java</code>).</p> + <h4>Making a purchase request (REQUEST_PURCHASE)</h4> <p>To make a purchase request you must do the following:</p> @@ -336,7 +416,7 @@ protected Bundle makeRequestBundle(String method) { <h5>Launching the pending intent</h5> -<p>How you use the pending intent depends on which version of Android a device is running. On Android 1.6, you must use the pending intent to launch the checkout UI in its own separate task instead of your application's activity stack. On Android 2.0 and higher, you can use the pending intent to launch the checkout UI on your application's activity stack. The following code shows you how to do this. You can find this code in the PurchaseObserver.java file in the sample application.</p> +<p>How you use the pending intent depends on which version of Android a device is running. On Android 1.6, you must use the pending intent to launch the checkout UI in its own separate task instead of your application's activity stack. On Android 2.0 and higher, you can use the pending intent to launch the checkout UI on your application's activity stack. The following code shows you how to do this. You can find this code in the <code>PurchaseObserver.java</code> file in the sample application.</p> <pre> void startBuyPageActivity(PendingIntent pendingIntent, Intent intent) { @@ -369,17 +449,17 @@ void startBuyPageActivity(PendingIntent pendingIntent, Intent intent) { } </pre> -<p class="note">You must launch the pending intent from an activity context and not an application context.</p> +<p class="caution"><strong>Important:</strong> You must launch the pending intent from an activity context and not an application context. Also, you cannot use the <code>singleTop</code> <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">launch mode</a> to launch the pending intent. If you do either of these, the Android system will not attach the pending intent to your application process. Instead, it will bring Android Market to the foreground, disrupting your application.</p> <h5>Handling broadcast intents</h5> -<p>A <code>REQUEST_PURCHASE</code> request also triggers two asynchronous responses (broadcast intents). First, the Android Market application sends an <code>ACTION_RESPONSE_CODE</code> broadcast intent, which provides error information about the request. Next, if the request was successful, the Android Market application sends an <code>ACTION_NOTIFY</code> broadcast intent. This message contains a notification ID, which you can use to retrieve the transaction details for the <code>REQUEST_PURCHASE</code> request.</p> +<p>A <code>REQUEST_PURCHASE</code> request also triggers two asynchronous responses (broadcast intents). First, the Android Market application sends a <code>RESPONSE_CODE</code> broadcast intent, which provides error information about the request. Next, if the request was successful, the Android Market application sends an <code>IN_APP_NOTIFY</code> broadcast intent. This message contains a notification ID, which you can use to retrieve the transaction details for the <code>REQUEST_PURCHASE</code> request.</p> -<p>Keep in mind, the Android Market application also sends an <code>ACTION_NOTIFY</code> for refunds. For more information, see <a href="{@docRoot}guide/market/billing/billing_overview.html#billing-action-notify">Handling ACTION_NOTIFY messages</a>.</p> +<p>Keep in mind, the Android Market application also sends an <code>IN_APP_NOTIFY</code> for refunds. For more information, see <a href="{@docRoot}guide/market/billing/billing_overview.html#billing-action-notify">Handling IN_APP_NOTIFY messages</a>.</p> <h4>Retrieving transaction information for a purchase or refund (GET_PURCHASE_INFORMATION)</h4> -<p>You retrieve transaction information in response to an <code>ACTION_NOTIFY</code> broadcast intent. The <code>ACTION_NOTIFY</code> message contains a notification ID, which you can use to retrieve transaction information.</p> +<p>You retrieve transaction information in response to an <code>IN_APP_NOTIFY</code> broadcast intent. The <code>IN_APP_NOTIFY</code> message contains a notification ID, which you can use to retrieve transaction information.</p> <p>To retrieve transaction information for a purchase or refund you must specify five keys in the request {@link android.os.Bundle}. The following code sample shows how to set these keys and make the request. In the sample, <code>mService</code> is an instance of the <code>MarketBillingService</code> interface.</p> @@ -394,11 +474,11 @@ void startBuyPageActivity(PendingIntent pendingIntent, Intent intent) { // Do something with this response. } </pre> -<p>The <code>makeRequestBundle()</code> method constructs an initial Bundle, which contains the three keys that are required for all requests: <code>BILLING_REQUEST</code>, <code>API_VERSION</code>, and <code>PACKAGE_NAME</code>. The additional keys are then added to the bundle prior to invoking the <code>sendBillingRequest()</code> method. The <code>REQUEST_NONCE</code> key contains a cryptographically secure nonce (number used once) that you must generate. The Android Market application returns this nonce with the <code>ACTION_PURCHASE_STATE_CHANGED</code> broadcast intent so you can verify the integrity of the transaction information. The <code>NOTIFY_IDS</code> key contains an array of notification IDs, which you received in the <code>ACTION_NOTIFY</code> broadcast intent.</p> +<p>The <code>makeRequestBundle()</code> method constructs an initial Bundle, which contains the three keys that are required for all requests: <code>BILLING_REQUEST</code>, <code>API_VERSION</code>, and <code>PACKAGE_NAME</code>. The additional keys are then added to the bundle prior to invoking the <code>sendBillingRequest()</code> method. The <code>REQUEST_NONCE</code> key contains a cryptographically secure nonce (number used once) that you must generate. The Android Market application returns this nonce with the <code>PURCHASE_STATE_CHANGED</code> broadcast intent so you can verify the integrity of the transaction information. The <code>NOTIFY_IDS</code> key contains an array of notification IDs, which you received in the <code>IN_APP_NOTIFY</code> broadcast intent.</p> <p>The request returns a synchronous {@link android.os.Bundle} response, which contains two keys: <code>RESPONSE_CODE</code> and <code>REQUEST_ID</code>. The <code>RESPONSE_CODE</code> key provides you with the status of the request and the <code>REQUEST_ID</code> key provides you with a unique request identifier for the request.</p> -<p>A <code>GET_PURCHASE_INFORMATION</code> request also triggers two asynchronous responses (broadcast intents). First, the Android Market application sends an <code>ACTION_RESPONSE_CODE</code> broadcast intent, which provides status and error information about the request. Next, if the request was successful, the Android Market application sends an <code>ACTION_PURCHASE_STATE_CHANGED</code> broadcast intent. This message contains detailed transaction information. The transaction information is contained in a signed JSON string (unencrypted). The message includes the signature so you can verify the integrity of the signed string.</p> +<p>A <code>GET_PURCHASE_INFORMATION</code> request also triggers two asynchronous responses (broadcast intents). First, the Android Market application sends a <code>RESPONSE_CODE</code> broadcast intent, which provides status and error information about the request. Next, if the request was successful, the Android Market application sends a <code>PURCHASE_STATE_CHANGED</code> broadcast intent. This message contains detailed transaction information. The transaction information is contained in a signed JSON string (unencrypted). The message includes the signature so you can verify the integrity of the signed string.</p> <h4>Acknowledging transaction information (CONFIRM_NOTIFICATIONS)</h4> @@ -414,11 +494,13 @@ void startBuyPageActivity(PendingIntent pendingIntent, Intent intent) { // Do something with this response. } </pre> -<p>The <code>makeRequestBundle()</code> method constructs an initial Bundle, which contains the three keys that are required for all requests: <code>BILLING_REQUEST</code>, <code>API_VERSION</code>, and <code>PACKAGE_NAME</code>. The additional <code>NOTIFY_IDS</code> key is then added to the bundle prior to invoking the <code>sendBillingRequest()</code> method. The <code>NOTIFY_IDS</code> key contains an array of notification IDs, which you received in an <code>ACTION_NOTIFY</code> broadcast intent and also used in a <code>GET_PURCHASE_INFORMATION</code> request.</p> +<p>The <code>makeRequestBundle()</code> method constructs an initial Bundle, which contains the three keys that are required for all requests: <code>BILLING_REQUEST</code>, <code>API_VERSION</code>, and <code>PACKAGE_NAME</code>. The additional <code>NOTIFY_IDS</code> key is then added to the bundle prior to invoking the <code>sendBillingRequest()</code> method. The <code>NOTIFY_IDS</code> key contains an array of notification IDs, which you received in an <code>IN_APP_NOTIFY</code> broadcast intent and also used in a <code>GET_PURCHASE_INFORMATION</code> request.</p> <p>The request returns a synchronous {@link android.os.Bundle} response, which contains two keys: <code>RESPONSE_CODE</code> and <code>REQUEST_ID</code>. The <code>RESPONSE_CODE</code> key provides you with the status of the request and the <code>REQUEST_ID</code> key provides you with a unique request identifier for the request.</p> -<p>A <code>CONFIRM_NOTIFICATIONS</code> request triggers a single asynchronous response—an <code>ACTION_RESPONSE_CODE</code> broadcast intent. This broadcast intent provides status and error information about the request.</p> +<p>A <code>CONFIRM_NOTIFICATIONS</code> request triggers a single asynchronous response—a <code>RESPONSE_CODE</code> broadcast intent. This broadcast intent provides status and error information about the request.</p> + +<p class="note"><strong>Note:</strong> 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 Android Market indicating that you need to deliver the product.</p> <h4>Restoring transaction information (RESTORE_TRANSACTIONS)</h4> @@ -434,29 +516,29 @@ void startBuyPageActivity(PendingIntent pendingIntent, Intent intent) { // Do something with this response. } </pre> -<p>The <code>makeRequestBundle()</code> method constructs an initial Bundle, which contains the three keys that are required for all requests: <code>BILLING_REQUEST</code>, <code>API_VERSION</code>, and <code>PACKAGE_NAME</code>. The additional <code>REQUEST_NONCE</code> key is then added to the bundle prior to invoking the <code>sendBillingRequest()</code> method. The <code>REQUEST_NONCE</code> key contains a cryptographically secure nonce (number used once) that you must generate. The Android Market application returns this nonce with the transactions information contained in the <code>ACTION_PURCHASE_STATE_CHANGED</code> broadcast intent so you can verify the integrity of the transaction information.</p> +<p>The <code>makeRequestBundle()</code> method constructs an initial Bundle, which contains the three keys that are required for all requests: <code>BILLING_REQUEST</code>, <code>API_VERSION</code>, and <code>PACKAGE_NAME</code>. The additional <code>REQUEST_NONCE</code> key is then added to the bundle prior to invoking the <code>sendBillingRequest()</code> method. The <code>REQUEST_NONCE</code> key contains a cryptographically secure nonce (number used once) that you must generate. The Android Market application returns this nonce with the transactions information contained in the <code>PURCHASE_STATE_CHANGED</code> broadcast intent so you can verify the integrity of the transaction information.</p> <p>The request returns a synchronous {@link android.os.Bundle} response, which contains two keys: <code>RESPONSE_CODE</code> and <code>REQUEST_ID</code>. The <code>RESPONSE_CODE</code> key provides you with the status of the request and the <code>REQUEST_ID</code> key provides you with a unique request identifier for the request.</p> -<p>A <code>RESTORE_TRANSACTIONS</code> request also triggers two asynchronous responses (broadcast intents). First, the Android Market application sends an <code>ACTION_RESPONSE_CODE</code> broadcast intent, which provides status and error information about the request. Next, if the request was successful, the Android Market application sends an <code>ACTION_PURCHASE_STATE_CHANGED</code> broadcast intent. This message contains the detailed transaction information. The transaction information is contained in a signed JSON string (unencrypted). The message includes the signature so you can verify the integrity of the signed string.</p> +<p>A <code>RESTORE_TRANSACTIONS</code> request also triggers two asynchronous responses (broadcast intents). First, the Android Market application sends a <code>RESPONSE_CODE</code> broadcast intent, which provides status and error information about the request. Next, if the request was successful, the Android Market application sends a <code>PURCHASE_STATE_CHANGED</code> broadcast intent. This message contains the detailed transaction information. The transaction information is contained in a signed JSON string (unencrypted). The message includes the signature so you can verify the integrity of the signed string.</p> <h3>Other service tasks</h3> -<p>You may also want your {@link android.app.Service} to receive intent messages from your {@link android.content.BroadcastReceiver}. You can use these intent messages to convey the information that was sent asynchronously from the Android Market application to your {@link android.content.BroadcastReceiver}. To see an example of how you can send and receive these intent messages, see the BillingReceiver.java and BillingService.java files in the sample application. You can use these samples as a basis for your own implementation. However, if you use any of the code from the sample application, be sure you follow the guidelines in <a href="{@docRoot}guide/market/billing/billing_best_practices.html">Security and Design</a>.</p> +<p>You may also want your {@link android.app.Service} to receive intent messages from your {@link android.content.BroadcastReceiver}. You can use these intent messages to convey the information that was sent asynchronously from the Android Market application to your {@link android.content.BroadcastReceiver}. To see an example of how you can send and receive these intent messages, see the <code>BillingReceiver.java</code> and <code>BillingService.java</code> files in the sample application. You can use these samples as a basis for your own implementation. However, if you use any of the code from the sample application, be sure you follow the guidelines in <a href="{@docRoot}guide/market/billing/billing_best_practices.html">Security and Design</a>.</p> <h2 id="billing-broadcast-receiver">Creating a BroadcastReceiver</h2> <p>The Android Market application uses broadcast intents to send asynchronous billing responses to your application. To receive these intent messages, you need to create a {@link android.content.BroadcastReceiver} that can handle the following intents:</p> <ul> - <li>ACTION_RESPONSE_CODE + <li>com.android.vending.billing.RESPONSE_CODE <p>This broadcast intent contains an Android Market response code, and is sent after you make an in-app billing request. For more information about the response codes that are sent with this response, see <a href="{@docRoot}guide/market/billing/billing_reference.html#billing-codes">Android Market Response Codes for In-app Billing</a>.</p> </li> - <li>ACTION_NOTIFY + <li>com.android.vending.billing.IN_APP_NOTIFY <p>This response indicates that a purchase has changed state, which means a purchase succeeded, was canceled, or was refunded. For more information about notification messages, see <a href="{@docRoot}guide/market/billing/billing_reference.html#billing-intents">In-app Billing Broadcast Intents</a></p> </li> - <li>ACTION_PURCHASE_STATE_CHANGED + <li>com.android.vending.billing.PURCHASE_STATE_CHANGED <p>This broadcast intent contains detailed information about one or more transactions. For more information about purchase state messages, see <a href="{@docRoot}guide/market/billing/billing_reference.html#billing-intents">In-app Billing Broadcast Intents</a></p> </li> </ul> @@ -473,28 +555,28 @@ void startBuyPageActivity(PendingIntent pendingIntent, Intent intent) { <th>Description</th> </tr> <tr> - <td><code>ACTION_RESPONSE_CODE</code></td> - <td><code>INAPP_REQUEST_ID</code></td> + <td><code>com.android.vending.billing.RESPONSE_CODE</code></td> + <td><code>request_id</code></td> <td>A <code>long</code> representing a request ID. A request ID identifies a specific billing request and is returned by Android Market at the time a request is made.</td> </tr> <tr> - <td><code>ACTION_RESPONSE_CODE</code></td> - <td><code>INAPP_RESPONSE_CODE</code></td> + <td><code>com.android.vending.billing.RESPONSE_CODE</code></td> + <td><code>response_code</code></td> <td>An <code>int</code> representing the actual Android Market server response code.</td> </tr> <tr> - <td><code>ACTION_NOTIFY</code></td> - <td><code>NOTIFICATION_ID</code></td> + <td><code>com.android.vending.billing.IN_APP_NOTIFY</code></td> + <td><code>notification_id</code></td> <td>A <code>String</code> representing the notification ID for a given purchase state change. Android Market 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.</td> </tr> <tr> - <td><code>ACTION_PURCHASE_STATE_CHANGED</code></td> - <td><code>INAPP_SIGNED_DATA</code></td> + <td><code>com.android.vending.billing.PURCHASE_STATE_CHANGED</code></td> + <td><code>inapp_signed_data</code></td> <td>A <code>String</code> representing the signed JSON string. The JSON string contains information about the billing transaction, such as order number, amount, and the item that was purchased or refunded.</td> </tr> <tr> - <td><code>ACTION_PURCHASE_STATE_CHANGED</code></td> - <td><code>INAPP_SIGNATURE</code></td> + <td><code>com.android.vending.billing.PURCHASE_STATE_CHANGED</code></td> + <td><code>inapp_signature</code></td> <td>A <code>String</code> representing the signature of the JSON string.</td> </tr> </table> @@ -547,17 +629,17 @@ public class BillingReceiver extends BroadcastReceiver { } </pre> -<p>In addition to receiving broadcast intents from the Android Market application, your {@link android.content.BroadcastReceiver} must handle the information it received in the broadcast intents. Usually, your {@link android.content.BroadcastReceiver} does this by sending the information to a local service (discussed in the next section). The BillingReceiver.java file in the sample application shows you how to do this. You can use this sample as a basis for your own {@link android.content.BroadcastReceiver}. However, if you use any of the code from the sample application, be sure you follow the guidelines that are discussed in <a href="{@docRoot}guide/market/billing/billing_best_practices.html">Security and Design </a>.</p> +<p>In addition to receiving broadcast intents from the Android Market application, your {@link android.content.BroadcastReceiver} must handle the information it received in the broadcast intents. Usually, your {@link android.content.BroadcastReceiver} does this by sending the information to a local service (discussed in the next section). The <code>BillingReceiver.java</code> file in the sample application shows you how to do this. You can use this sample as a basis for your own {@link android.content.BroadcastReceiver}. However, if you use any of the code from the sample application, be sure you follow the guidelines that are discussed in <a href="{@docRoot}guide/market/billing/billing_best_practices.html">Security and Design </a>.</p> <h2 id="billing-signatures">Verifying Signatures and Nonces</h2> -<p>The in-app billing service uses two mechanisms to help verify the integrity of the transaction information you receive from Android Market: nonces and signatures. A nonce (number used once) is a cryptographically secure number that your application generates and sends with every <code>GET_PURCHASE_INFORMATION</code> and <code>RESTORE_TRANSACTIONS</code> request. The nonce is returned with the <code>ACTION_PURCHASE_STATE_CHANGED</code> broadcast intent, enabling you to verify that any given <code>ACTION_PURCHASE_STATE_CHANGED</code> response corresponds to an actual request that you made. Every <code>ACTION_PURCHASE_STATE_CHANGED</code> broadcast intent also includes a signed JSON string and a signature, which you can use to verify the integrity of the response.</p> +<p>The in-app billing service uses two mechanisms to help verify the integrity of the transaction information you receive from Android Market: nonces and signatures. A nonce (number used once) is a cryptographically secure number that your application generates and sends with every <code>GET_PURCHASE_INFORMATION</code> and <code>RESTORE_TRANSACTIONS</code> request. The nonce is returned with the <code>PURCHASE_STATE_CHANGED</code> broadcast intent, enabling you to verify that any given <code>PURCHASE_STATE_CHANGED</code> response corresponds to an actual request that you made. Every <code>PURCHASE_STATE_CHANGED</code> broadcast intent also includes a signed JSON string and a signature, which you can use to verify the integrity of the response.</p> <p>Your application must provide a way to generate, manage, and verify nonces. The following sample code shows some simple methods you can use to do this.</p> <pre> private static final SecureRandom RANDOM = new SecureRandom(); - private static HashSet<Long> sKnownNonces = new HashSet<Long>(); + private static HashSet<Long> sKnownNonces = new HashSet<Long>(); public static long generateNonce() { long nonce = RANDOM.nextLong(); @@ -574,7 +656,7 @@ public class BillingReceiver extends BroadcastReceiver { } </pre> -<p>Your application must also provide a way to verify the signatures that accompany every <code>ACTION_PURCHASE_STATE_CHANGED</code> broadcast intent. The Security.java file in the sample application shows you how to do this. If you use this file as a basis for your own security implementation, be sure to follow the guidelines in <a href="{@docRoot}guide/market/billing/billing_best_practices.html">Security and Design</a> and obfuscate your code.</p> +<p>Your application must also provide a way to verify the signatures that accompany every <code>PURCHASE_STATE_CHANGED</code> broadcast intent. The <code>Security.java</code> file in the sample application shows you how to do this. If you use this file as a basis for your own security implementation, be sure to follow the guidelines in <a href="{@docRoot}guide/market/billing/billing_best_practices.html">Security and Design</a> and obfuscate your code.</p> <p>You will need to use your Android Market public key to perform the signature verification. The following procedure shows you how to retrieve Base64-encoded public key from the Android Market publisher site.</p> @@ -582,17 +664,17 @@ public class BillingReceiver extends BroadcastReceiver { <li>Log in to your <a href="http://market.android.com/publish">publisher account</a>.</li> <li>On the upper left part of the page, under your name, click <strong>Edit profile</strong>.</li> <li>On the Edit Profile page, scroll down to the Licensing & In-app Billing panel (see figure 2).</li> - <li>Copy your public key to the clipboard.</li> + <li>Copy your public key.</li> </ol> <p class="caution"><strong>Important</strong>: To keep your public key safe from malicious users and hackers, do not embed your public key as an entire literal string. Instead, construct the string at runtime from pieces or use bit manipulation (for example, XOR with some other string) to hide the actual key. The key itself is not secret information, but you do not want to make it easy for a hacker or malicious user to replace the public key with another key.</p> <div style="margin-bottom:2em;"> -<img src="{@docRoot}images/billing_public_key.png" style="text-align:left;margin-bottom:0;" /> -<div style="margin:0 2em;padding:0"><strong>Figure 2.</strong> The Licensing and In-app Billing -panel of your account's Edit Profile page lets you see your public key.</div> -</div> +<img src="{@docRoot}images/billing_public_key.png" height="510" id="figure2" /> +<p class="img-caption"> + <strong>Figure 2.</strong> The Licensing and In-app Billing panel of your account's Edit Profile page lets you see your public key. +</p> <h2 id="billing-implement">Modifying Your Application Code</h2> diff --git a/docs/html/guide/market/billing/billing_overview.jd b/docs/html/guide/market/billing/billing_overview.jd index b899b9b..36f9d53 100755 --- a/docs/html/guide/market/billing/billing_overview.jd +++ b/docs/html/guide/market/billing/billing_overview.jd @@ -3,12 +3,6 @@ parent.title=In-app Billing parent.link=index.html @jd:body -<style type="text/css"> - #jd-content { - background:transparent url({@docRoot}assets/images/preliminary.png) repeat scroll 0 0; - } -</style> - <div id="qv-wrapper"> <div id="qv"> <h2>In this document</h2> @@ -19,7 +13,7 @@ parent.link=index.html <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 ACTION_NOTIFY messages</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> @@ -40,10 +34,10 @@ parent.link=index.html </div> <div class="special" style="margin-right:345px"> - <p>This documentation provides an early look at the Android Market In-app Billing service. The documentation may change without notice.</p> + <p>During the testing phase of the in-app billing release you cannot publish applications that implement in-app billing. You can only upload in-app billing applications as draft applications. For more information, see <a href="{@docRoot}guide/market/billing/billing_about.html">About this Release</a></p> </div> -<p>The Android Market In-app Billing service is an Android Market feature that provides checkout processing for in-app purchases. To use the service, your application sends a billing request to the service for a specific in-app product. The service then handles all of the checkout details for the transaction, including requesting and validating the form of payment and processing the financial transaction. When the checkout process is complete, the service sends your application the purchase details, such as the order number, the order date and time, and the price paid. At no point does your application have to handle any financial transactions; that role is provided by the in-app billing service.</p> +<p>The Android Market In-app Billing service is an Android Market feature that provides checkout processing for in-app purchases. To use the service, your application sends a billing request for a specific in-app product. The service then handles all of the checkout details for the transaction, including requesting and validating the form of payment and processing the financial transaction. When the checkout process is complete, the service sends your application the purchase details, such as the order number, the order date and time, and the price paid. At no point does your application have to handle any financial transactions; that role is provided by the in-app billing service.</p> <h2 id="billing-arch">In-app Billing Architecture</h2> @@ -52,8 +46,9 @@ parent.link=index.html <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> <div class="figure" style="width:440px"> -<img src="{@docRoot}images/billing_arch.png" alt=""/> -<p class="img-caption"><strong>Figure 1.</strong> Your application sends and receives billing messages through the Android Market application, which handles all communication with the Android Market server.</p> +<img src="{@docRoot}images/billing_arch.png" alt="" height="582" /> +<p class="img-caption"> + <strong>Figure 1.</strong> Your application sends and receives billing messages through the Android Market application, which handles all communication with the Android Market server.</p> </div> <p>A typical in-app billing implementation relies on three components:</p> @@ -77,7 +72,7 @@ parent.link=index.html <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/developing/tools/aidl.html">Android Interface Definition Language</a> file (<code>IMarketBillingService.aidl</code>). You can download this AIDL file with the in-app billing sample application.</p> +<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/developing/tools/aidl.html">Android Interface Definition Language</a> file (<code>IMarketBillingService.aidl</code>). You can <a href="{@docRoot}guide/market/billing/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} parameter. The Bundle that you deliver must include several key-value pairs that specify various parameters for the request, such as the type of billing request you are making, the item that is being purchased, and the application that is making the request. For more information about the Bundle keys that are sent with a request, see <a href="{@docRoot}guide/market/billing/billing_reference.html#billing-interface">In-app Billing Service Interface</a>. @@ -97,7 +92,7 @@ parent.link=index.html <p>This request acknowledges that your application received the details of a purchase state change. Android Market sends purchase state change notifications to your application until you confirm that you received them.</p> </li> <li><code>RESTORE_TRANSACTIONS</code> - <p>This request retrieves a user's transaction status for managed purchases (see <a href="{@docRoot}guide/market/billing/billing_admin.html#billing-purchase-type">Choosing a Purchase Type</a> for more information). You should send this request only when you need to retrieve a user's transaction status, which is usually only when your application is reinstalled or installed for the first time on a device.</p> + <p>This request retrieves a user's transaction status for <a href="{@docRoot}guide/market/billing/billing_admin.html#billing-purchase-type">managed purchases</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> @@ -121,18 +116,18 @@ parent.link=index.html <p>The asynchronous response messages are sent in the form of individual broadcast intents and include the following:</p> <ul> - <li><code>ACTION_RESPONSE_CODE</code> + <li><code>com.android.vending.billing.RESPONSE_CODE</code> <p>This response contains an Android Market server response code, and is sent after you make an in-app billing request. A server response code can indicate that a billing request was successfully sent to Android Market or it can indicate that some error occurred during a billing request. This response is <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}guide/market/billing/billing_reference.html#billing-codes">Server Response Codes for In-app Billing</a>.</p> </li> - <li><code>ACTION_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>ACTION_NOTIFY</code> broadcast intent, you send a <code>GET_PURCHASE_INFORMATION</code> request with the notification IDs to retrieve message details.</p> + <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>ACTION_PURCHASE_STATE_CHANGED</code> + <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>ACTION_PURCHASE_STATE_CHANGED</code> intent provides your application with the details of one or more billing transactions. An example of this JSON string is shown below:</p> +<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 is shown below:</p> <pre class="no-pretty-print" style="color:black"> { "nonce" : 1836535032137741465, "orders" : @@ -146,113 +141,85 @@ parent.link=index.html } </pre> -<p>The fields in the JSON string are described in the following table (see table 1):</p> - -<p class="table-caption"><strong>Table 1.</strong> Description of JSON fields that are returned with an <code>ACTION_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. Android Market 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>ACTION_NOTIFY</code> broadcast intent. Each <code>notificationId</code> corresponds to a specify message that is waiting to be retrieved on the Android Market server. Your application sends back the <code>notificationId</code> with the <code>GET_PURCHASE_INFORMATION</code> message so Android Market 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 Checkout 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 Android Market publisher site.</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 enum value for the purchase state, which indicates whether the purchase was successful, canceled, or refunded.</td> -</tr> -<tr> - <td>developerPayload</td> - <td>A developer-specified string that is associated with an order. This field is returned in the JSON string that contains transaction information for an order. You can use this field to send information with an order. For example, you can use this field to send index keys with an order, which is useful if you are using a database to store purchase information. We recommend that you do not use this field to send data or content.</td> -</tr> -</table> +<p>For more information about the fields in this JSON string, see <a href="{@docRoot}guide/market/billing/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>, responses are shown in standard text. For clarity, Figure 2 does not show the <code>ACTION_RESPONSE_CODE</code> broadcast intents that are sent for every request. These responses provide status information or error information and are returned after each request.</p> +<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 Android Market application sends your application a Bundle with a <code>RESPONSE_CODE</code>, <code>PURCHASE_INTENT</code>, and <code>REQUEST_ID</code>. The <code>PURCHASE_INTENT</code> provides a {@link android.app.PendingIntent}, which your application uses to start the checkout flow for the given product ID.</li> + <li>The Android Market 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}, 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.</li> - <li>When the checkout flow finishes (that is, the user successfully purchases the item or cancels the purchase), Android Market sends your application a notification message (an <code>ACTION_NOTIFY</code> intent). The notification message includes a notification ID, which references the completed transaction.</li> + <li>When the checkout flow finishes (that is, the user successfully purchases the item or cancels the purchase), Android Market sends your application a notification message (an <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 Android Market application sends a Bundle with a <code>RESPONSE_CODE</code> and a <code>REQUEST_ID</code>. - <li>Android Market sends the transaction information to your application in an <code>ACTION_PURCHASE_STATE_CHANGED</code> intent.</li> + <li>The Android Market application sends a Bundle with a <code>RESPONSE_CODE</code> key and a <code>REQUEST_ID</code> key. + <li>Android Market 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 Android Market applications sends your application a Bundle with a <code>RESPONSE_CODE</code> and a <code>REQUEST_ID</code>.</li> + <li>The Android Market application sends your application a Bundle with a <code>RESPONSE_CODE</code> key and a <code>REQUEST_ID</code> key.</li> </ol> <p class="note"><strong>Note:</strong> You must launch the pending intent from an activity context and not an application context.</p> -<div style="margin:2em 1em 1em 1em;"> -<img src="{@docRoot}images/billing_request_purchase.png" style="text-align:left;" /> -<div style="margin:.25em 1.25em;padding:0"><strong>Figure 2.</strong> Message sequence for a typical purchase request. Request types for each <code>sendBillingRequest()</code> method are shown in <strong>bold</strong> (<code>ACTION_RESPONSE_CODE</code> broadcast intents have been omitted).</div> -</div> +<img src="{@docRoot}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>The messaging sequence for a restore transaction request is shown in Figure 3. The request type for the <code>sendBillingRequest()</code> method is shown in <strong>bold</strong>, the responses are shown in standard text.</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="{@docRoot}images/billing_restore_transactions.png" alt=""/> -<p class="img-caption"><strong>Figure 3.</strong> Message sequence for a restore transactions request.</p> +<img src="{@docRoot}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} with a <code>RESPONSE_CODE</code> and a <code>REQUEST_ID</code>. Next, the Android Market application sends an <code>ACTION_RESPONSE_CODE</code> broadcast intent, which provides status information or error information about the request. As always, the <code>ACTION_RESPONSE_CODE</code> message references a specific request ID, so you can determine which request an <code>ACTION_RESPONSE_CODE</code> message pertains to.</p> +<p>The request triggers three responses. The first is a {@link android.os.Bundle} with a <code>RESPONSE_CODE</code> key and a <code>REQUEST_ID</code> key. Next, the Android Market 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 an <code>ACTION_PURCHASE_STATE_CHANGED</code> broadcast intent, which contains the same type of transaction information that is sent during a purchase request, although you do not need to respond to this intent with a <code>CONFIRM_NOTIFICATIONS</code> message.</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, although you do not need to respond to this intent with a <code>CONFIRM_NOTIFICATIONS</code> message.</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>, the response is shown in regular text.</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="{@docRoot}images/billing_check_supported.png" alt=""/> -<p class="img-caption"><strong>Figure 4.</strong> Message sequence for checking whether in-app billing is supported.</p> +<img src="{@docRoot}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 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 the Android Market application does not support in-app billing and may need to be updated. A <code>SERVER_ERROR</code> can also be returned, indicating that there was a problem with the Android Market server. The <code>RESULT_BILLING_UNAVAILABLE</code> response code can also indicate that the user is ineligible for in-app billing (for example, the user resides in a country that does not allow in-app billing).</p> +<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 in-app billing 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 Android Market server.</p> -<h3 id="billing-action-notify">Handling ACTION_NOTIFY messages</h3> +<h3 id="billing-action-notify">Handling IN_APP_NOTIFY messages</h3> -<p>Usually, your application receives an <code>ACTION_NOTIFY</code> intent from Android Market in response to a <code>REQUEST_PURCHASE</code> message (see figure 2). The <code>ACTION_NOTIFY</code> intent informs your application that the state of a requested purchase has changed. To retrieve the details of that state change, your application sends a <code>GET_PURCHASE_INFORMATION</code> request. Android Market responds with an <code>ACTION_PURCHASE_STATE_CHANGED</code> intent, which contains the details of the purchase state change. Your application then sends a <code>CONFIRM_NOTIFICATIONS</code> message, informing Android Market that you've received the purchase state change information.</p> +<p>Usually, your application receives an <code>IN_APP_NOTIFY</code> broadcast intent from Android Market 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. Android Market 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 Android Market that you've received the purchase state change information.</p> -<p>When Android Market receives a <code>CONFIRM_NOTIFICATIONS</code> message for a given message, it usually stops sending <code>ACTION_NOTIFY</code> intents for that message. However, there are some cases where Android Market may send repeated <code>ACTION_NOTIFY</code> intents for a 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, Android Market might not receive your <code>CONFIRM_NOTIFICATIONS</code> message and it could send multiple <code>ACTION_NOTIFY</code> messages until it receives acknowledgement that you received the message. Therefore, your application must be able to recognize that the subsequent <code>ACTION_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> +<p>When Android Market receives a <code>CONFIRM_NOTIFICATIONS</code> message for a given message, it usually stops sending <code>IN_APP_NOTIFY</code> intents for that message. However, there are some cases where Android Market may send repeated <code>IN_APP_NOTIFY</code> intents for a 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, Android Market 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 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> -<p>Your application may also receive <code>ACTION_NOTIFY</code> intents even though your application has not sent a <code>REQUEST_PURCHASE</code> message. This can occur when a user has your application installed on two (or more) devices and the user makes an in-app purchase from one of the devices. In this case, Android Market sends an <code>ACTION_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 purchase state change message that includes information about the item that's been purchased. This scenario applies only to items that have their <a href="{@docRoot}guide/market/billing/billing_admin.html#billing-purchase-type">purchase type</a> set to "managed per user account."</p> +<p>There are two cases where your application may also 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="{@docRoot}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 can 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, Android Market 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 <a href="{@docRoot}guide/market/billing/billing_admin.html#billing-purchase-type">purchase type</a> 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 Android Market receives a refund notification from Google Checkout. In this case, Android Market 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> <h2 id="billing-security">Security Controls</h2> -<p>To help ensure the integrity of the transaction information that is sent to your application, Android Market signs the JSON string that is contained in the <code>ACTION_PURCHASE_STATE_CHANGED</code> broadcast intent. Android Market uses the private key that is associated with your publisher account to create this signature. The publisher site generates an RSA key pair for each publisher account. You can find the public key portion of this key pair on your account's profile page. It is the same public key that is used with Android Market licensing.</p> +<p>To help ensure the integrity of the transaction information that is sent to your application, Android Market signs the JSON string that is contained in the <code>PURCHASE_STATE_CHANGED</code> broadcast intent. Android Market uses the private key that is associated with your publisher account to create this signature. The publisher site generates an RSA key pair for each publisher account. You can find the public key portion of this key pair on your account's profile page. It is the same public key that is used with Android Market licensing.</p> <p>When Android Market signs a billing response, it includes the signed JSON string (unencrypted) and the signature. When your application receives this signed response you can use the public key portion of your RSA key pair to verify the signature. By performing signature verification you can help detect responses that have been tampered with or that have been spoofed. You can perform this signature verification step in your application; however, if your application connects to a secure remote server then we recommend that you perform the signature verification on that server.</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 Android Market. 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 Android Market receives the request, it adds the nonce to the JSON string that contains the transaction information. The JSON string is then signed and returned to your application. When your application receives the JSON string, you need to verify the nonce as well as the signature of the JSON string.</p> -<p>For more information about best practices for security and design, see <a href="{@docRoot}guide/market/billing/billing_best_practices.html">Security and Design</a>.</p> +<p>For more information about best practices for security and design, see <a href="{@docRoot}guide/market/billing/billing_best_practices.html">Security and Design</a>.</p> <h2 id="billing-limitations">In-app Billing Requirements and Limitations</h2> @@ -260,10 +227,12 @@ parent.link=index.html <ul> <li>In-app billing can be implemented only in applications that you publish through Android Market.</li> - <li>You must have a Google Checkout merchant account to use the in-app billing service.</li> - <li>An application can use in-app billing only if the current Android Market application is installed on its host device and the device is running Android 1.6 (API level 4) or higher.</li> - <li>A device must be running version 2.3.0 (or higher) of the Android Market application to support in-app billing.</li> + <li>You must have a Google Checkout Merchant account to use the in-app billing service.</li> + <li>If your device is running Android 3.0, in-app billing requires version 5.0.12 (or higher) of the MyApps application. If your device is running any other version of Android, in-app billing requires version 2.3.4 (or higher) of the Android Market application.</li> + <li>An application can use in-app billing only if the device is running 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>Android Market 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 Android Market server over the network. </li> </ul> + +<p>For more information about in-app billing requirements, see <a href="http://market.android.com/support/bin/answer.py?answer=1153481">In-App Billing Availability and Policies</a>.</p> diff --git a/docs/html/guide/market/billing/billing_reference.jd b/docs/html/guide/market/billing/billing_reference.jd index 2e5c9c6..744c4d1 100755 --- a/docs/html/guide/market/billing/billing_reference.jd +++ b/docs/html/guide/market/billing/billing_reference.jd @@ -3,12 +3,6 @@ parent.title=In-app Billing parent.link=index.html @jd:body -<style type="text/css"> - #jd-content { - background:transparent url({@docRoot}assets/images/preliminary.png) repeat scroll 0 0; - } -</style> - <div id="qv-wrapper"> <div id="qv"> <h2>In this document</h2> @@ -34,7 +28,7 @@ parent.link=index.html </div> <div class="special" style="margin-right:345px"> - <p>This documentation provides an early look at the Android Market In-app Billing service. The documentation may change without notice.</p> + <p>During the testing phase of the in-app billing release you cannot publish applications that implement in-app billing. You can only upload in-app billing applications as draft applications. For more information, see <a href="{@docRoot}guide/market/billing/billing_about.html">About this Release</a></p> </div> <p>The following document provides technical reference information for the following:</p> @@ -47,7 +41,7 @@ parent.link=index.html <h2 id="billing-codes">Android Market Server Response Codes for In-app Billing</h2> -<p>The following table lists all of the server response codes that are sent from Android Market to your application. Android Market sends these response codes asynchronously as <code>INAPP_RESPONSE_CODE</code> extras in the <code>ACTION_RESPONSE_CODE</code> broadcast intent. Your application must handle all of these response codes.</p> +<p>The following table lists all of the server response codes that are sent from Android Market to your application. Android Market 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 1.</strong> Summary of response codes returned by Android Market.</p> @@ -71,7 +65,7 @@ parent.link=index.html </tr> <tr> <td><code>RESULT_BILLING_UNAVAILABLE</code></td> - <td>Indicates that the <code>BILLING_API_VERSION</code> that you specified is not recognized by the Android Market application and that the Android Market application may have to be updated. Can also indicate that the user is ineligible for in-app billing. For example, the user resides in a country that does not allow in-app purchases.</td> + <td>Indicates that in-app billing is not available because the <code>API_VERSION</code> that you specified is not recognized by the Android Market 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> @@ -90,8 +84,8 @@ parent.link=index.html <h2 id="billing-interface">In-app Billing Service Interface</h2> -<p>The following section describes the interface for the Android Market 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}guide/market/billing/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 2.</p> +<p>The following section describes the interface for the Android Market 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}guide/market/billing/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 2.</p> <p class="table-caption"><strong>Table 2.</strong> Description of Bundle keys passed in a <code>sendBillingRequest()</code> request.</p> @@ -106,52 +100,52 @@ parent.link=index.html </tr> <tr> <td><code>BILLING_REQUEST</code></td> - <td>String</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>BILLING_API_VERSION</code></td> - <td>int</td> - <td>0 (for alpha release); 1 (for beta release)</td> + <td><code>API_VERSION</code></td> + <td><code>int</code></td> + <td>1</td> <td>Yes</td> - <td>The version of the in-app billing service you are using.</td> + <td>The version of the in-app billing service you are using. The current version is 1.</td> </tr> <tr> <td><code>PACKAGE_NAME</code></td> - <td>String</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>String</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 the in-app billing service must have a unique product ID, which you specify on the Android Market publisher site.</td> </tr> <tr> <td><code>NONCE</code></td> - <td>long</td> - <td>Any valid long value.</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>ACTION_PURCHASE_STATE_CHANGED</code> intent, so you can use this value to verify the integrity of transaction responses form Android Market.</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 Android Market.</td> </tr> <tr> <td><code>NOTIFY_IDS</code></td> - <td>Array of long values</td> - <td>Any valid array of long values</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>ACTION_NOTIFY</code> intent every time a purchase changes state. You use the notification to retrieve the details of the purchase state change.</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>String</td> - <td>Any valid String less than 256 characters long.</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 is associated with an order. This field is returned in the JSON string that contains transaction information for an order. You can use this field to send information with an order. For example, you can use this field to send index keys with an order, which is useful if you are using a database to store purchase information. We recommend that you do not use this field to send data or content.</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> @@ -231,34 +225,81 @@ parent.link=index.html <p>The following section describes the in-app billing broadcast intents that are sent by the Android Market 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}guide/market/billing/billing_integrate.html#billing-download">sample application</a>.</p> -<h4>ACTION_RESPONSE_CODE</h4> +<h4>com.android.vending.billing.RESPONSE_CODE</h4> -<p>This broadcast intent contains an Android Market response code, and is sent after you make an in-app billing request. A server response code can indicate that a billing request was successfully sent to Android Market or it can indicate that some error occurred during a billing request. This 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">Android Market Response Codes for In-app Billing</a>.</p> +<p>This broadcast intent contains an Android Market response code, and is sent after you make an in-app billing request. A server response code can indicate that a billing request was successfully sent to Android Market or it can indicate that some error occurred during a billing request. This 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">Android Market 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>INAPP_REQUEST_ID</code>—a long representing a request ID. A request ID identifies a specific billing request and is returned by Android Market at the time a request is made.</li> - <li><code>INAPP_RESPONSE_CODE</code>—an int representing the Android Market server response code.</li> + <li><code>request_id</code>—a <code>long</code> representing a request ID. A request ID identifies a specific billing request and is returned by Android Market at the time a request is made.</li> + <li><code>response_code</code>—an <code>int</code> representing the Android Market server response code.</li> </ul> -<h4>ACTION_NOTIFY</h4> +<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>ACTION_NOTIFY</code> broadcast intent, you send a <code>GET_PURCHASE_INFORMATION</code> request with the notification IDs to retrieve the message details.</p> +<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>—a string representing the notification ID for a given purchase state change. Android Market 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> + <li><code>notification_id</code>—a <code>String</code> representing the notification ID for a given purchase state change. Android Market 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>ACTION_PURCHASE_STATE_CHANGED</h4> +<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.</p> +<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>—a string representing the signed JSON string.</li> - <li><code>INAPP_SIGNATURE</code>—a string representing the signature.</li> -</ul>
\ No newline at end of file + <li><code>inapp_signed_data</code>—a <code>String</code> representing the signed JSON string.</li> + <li><code>inapp_signature</code>—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 4):</p> + +<p class="table-caption"><strong>Table 4.</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. Android Market 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 Android Market server. Your application sends back the <code>notificationId</code> with the <code>GET_PURCHASE_INFORMATION</code> message so Android Market 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 Checkout 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 Android Market publisher site.</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), or 2 (refunded).</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> diff --git a/docs/html/guide/market/billing/billing_testing.jd b/docs/html/guide/market/billing/billing_testing.jd index 5ced9c7..c900e8b 100755 --- a/docs/html/guide/market/billing/billing_testing.jd +++ b/docs/html/guide/market/billing/billing_testing.jd @@ -3,12 +3,6 @@ parent.title=In-app Billing parent.link=index.html @jd:body -<style type="text/css"> - #jd-content { - background:transparent url({@docRoot}assets/images/preliminary.png) repeat scroll 0 0; - } -</style> - <div id="qv-wrapper"> <div id="qv"> <h2>In this document</h2> @@ -33,28 +27,26 @@ parent.link=index.html </div> <div class="special" style="margin-right:345px"> - <p>This documentation provides an early look at the Android Market In-app Billing service. The documentation may change without notice.</p> + <p>During the testing phase of the in-app billing release you cannot publish applications that implement in-app billing. You can only upload in-app billing applications as draft applications. For more information, see <a href="{@docRoot}guide/market/billing/billing_about.html">About this Release</a></p> </div> <p>The Android Market publisher site provides several tools that help you test your in-app billing implementation before it is published. You can use these tools to create test accounts and purchase special reserved items that send static billing responses to your application.</p> <p>To test in-app billing in an application you must install the application on an Android-powered device. You cannot use the Android emulator to test in-app billing. The device you use for testing must run a standard version of the Android 1.6 or later platform (API level 4 or higher), and have the most current version of the Android Market application installed. If a device is not running the most current Android Market application, your application won't be able to send in-app billing requests to Android Market. For general information about how to set up a device for use in developing Android applications, see <a -href="{@docRoot}guide/developing/device.html">Developing on a Device</a>.</p> +href="{@docRoot}guide/developing/device.html">Using Hardware Devices</a>.</p> <p>The following section shows you how to set up and use the in-app billing test tools.</p> -<p class="note"><strong>Note</strong>: Debug log messages are turned off by default in the sample application. You can turn them on by setting the variable <code>DEBUG</code> to <code>true</code> in the <code>Consts.java</code> file.</p> - <h2 id="billing-testing-static">Testing in-app purchases with static responses</h2> -<p>We recommend that you first test your in-app billing implementation using static responses from Android Market. This enables you to verify that your application is handling the primary Android Market responses correctly and that your application is able to verify the signature correctly.</p> +<p>We recommend that you first test your in-app billing implementation using static responses from Android Market. This enables you to verify that your application is handling the primary Android Market responses correctly and that your application is able to verify signatures correctly.</p> <p>To test your implementation with static responses, you make an in-app billing request using a special item that has a reserved product ID. Each reserved product ID returns a specific static response from Android Market. No money is transferred when you make in-app billing requests with the reserved product IDs. Also, you cannot specify the form of payment when you make a billing request with a reserved product ID. Figure 1 shows the checkout flow for the reserved item that has the product ID android.test.purchased.</p> -<div style="margin:2em 1em 1em 1em;"> -<img src="{@docRoot}images/billing_test_flow.png" style="text-align:left;" /> -<div style="margin:.25em 1.25em;padding:0"><strong>Figure 1.</strong> Checkout flow for the special reserved item android.test.purchased.</div> -</div> +<img src="{@docRoot}images/billing_test_flow.png" height="381" id="figure1" /> +<p class="img-caption"> + <strong>Figure 1.</strong> Checkout flow for the special reserved item android.test.purchased. +</p> <p>You do not need to list the reserved products in your application's product list. Android Market already knows about the reserved product IDs. Also, you do not need to upload your application to the publisher site to perform static response tests with the reserved product IDs. You can simply install your application on a device, log into the device, and make billing requests using the reserved product IDs.</p> @@ -68,14 +60,14 @@ href="{@docRoot}guide/developing/device.html">Developing on a Device</a>.</p> <p>When you make an in-app billing request with this product ID Android Market responds as though the purchase was canceled. This can occur when an error is encountered in the order process, such as an invalid credit card, or when you cancel a user's order before it is charged.</p> </li> <li><strong>android.test.refunded</strong> - <p>When you make an in-app billing request with this product ID, Android Market responds as though the purchase was refunded. Refunds cannot be initiated through the in-app billing feature. Refunds must be initiated by you (the merchant). A refund message is sent to your app by Android Market only when Android Market gets notification from Google Checkout that a refund has been made.</p> + <p>When you make an in-app billing request with this product ID, Android Market responds as though the purchase was refunded. Refunds cannot be initiated through the in-app billing feature. Refunds must be initiated by you (the merchant). A refund message is sent to your application by Android Market only when Android Market gets notification from Google Checkout that a refund has been made. For more information about refunds, see <a href="{@docRoot}guide/market/billing/billing_overview.html#billing-action-notify">Handling IN_APP_NOTIFY messages</a> and <a href="http://www.google.com/support/androidmarket/bin/answer.py?answer=1153485">In-app Billing Pricing</a>.</p> </li> <li><strong>android.test.item_unavailable</strong> - <p>When you make an in-app billing request with this product ID Android Market responds as though the item being purchased was not listed in your app's product list.</p> + <p>When you make an in-app billing request with this product ID, Android Market responds as though the item being purchased was not listed in your application's product list.</p> </li> </ul> -<p>In some cases, the reserved items may return signed static responses, which lets you test signature verification in your application. To test signature verification with the special reserved product IDs, you may need to set up <a href="{@docRoot}guide/market/billing/billing_admin.html#billing-testing-setup">trusted tester accounts</a> or upload your application as a unpublished draft application. The following table (Table 1) shows you the conditions under which static responses are signed.</p> +<p>In some cases, the reserved items may return signed static responses, which lets you test signature verification in your application. To test signature verification with the special reserved product IDs, you may need to set up <a href="{@docRoot}guide/market/billing/billing_admin.html#billing-testing-setup">test accounts</a> or upload your application as a unpublished draft application. Table 1 shows you the conditions under which static responses are signed.</p> <p class="table-caption" id="static-responses-table"><strong>Table 1.</strong> Conditions under which static responses are signed.</p> @@ -119,7 +111,7 @@ Conditions under which static responses are signed.</p> <tr> <td>Yes</td> <td>No</td> -<td>Trusted tester</td> +<td>Test account</td> <td>Signed</td> </tr> @@ -134,6 +126,22 @@ Conditions under which static responses are signed.</p> <p>To make an in-app billing request with a reserved product ID, you simply construct a normal <code>REQUEST_PURCHASE</code> request, but instead of using a real product ID from your application's product list you use one of the reserved product IDs.</p> +<p>To test your application using the reserved product IDs, follow these steps:</p> + +<ol> + <li><strong>Install your application on an Android-powered device.</strong> + <p>You cannot use the emulator to test in-app billing; you must install your application on a device to test in-app billing.</p> + <p>To learn how to install an application on a device, see <a href="{@docRoot}guide/developing/building/building-cmdline.html#RunningOnDevice">Running on a device</a>.</p> + </li> + <li><strong>Sign in to your device with your developer account.</strong> + <p>You do not need to use a test account if you are testing only with the reserved product IDs.</p> + </li> + <li><strong>Verify that your device is running a supported version of the Android Market application or the MyApps application.</strong> + <p>If your device is running Android 3.0, in-app billing requires version 5.0.12 (or higher) of the MyApps application. If your device is running any other version of Android, in-app billing requires version 2.3.4 (or higher) of the Android Market application. To learn how to check the version of the Android Market application, see <a href="http://market.android.com/support/bin/answer.py?answer=190860">Updating Android Market</a>.</p> + </li> + <li><strong>Run your application and purchase the reserved product IDs.</strong></li> +</ol> + <p class="note"><strong>Note</strong>: Making in-app billing requests with the reserved product IDs overrides the usual Android Market production system. When you send an in-app billing request for a reserved product ID, the quality of service will not be comparable to the production environment.</p> <h2 id="billing-testing-real">Testing In-app Purchases Using Your Own Product IDs</h2> @@ -146,29 +154,35 @@ Conditions under which static responses are signed.</p> <p>Also, a test account can purchase an item in your product list only if the item is published. The application does not need to be published, but the item does need to be published.</p> -<p>When you use a test account to purchase items, the account is billed through Google Checkout and your Google Checkout merchant account receives a payout for the purchase. Therefore, you need to refund purchases that are made with test accounts, otherwise the purchases will show up as actual payouts to your merchant account.</p> +<p>When you use a test account to purchase items, the test account is billed through Google Checkout and your Google Checkout Merchant account receives a payout for the purchase. Therefore, you may want to refund purchases that are made with test accounts, otherwise the purchases will show up as actual payouts to your merchant account.</p> <p>To test your in-app billing implementation with actual purchases, follow these steps:</p> <ol> - <li>Upload your application as a draft application to the publisher site. You do not need to publish your application to perform end-to-end testing with real product IDs.</li> - <li>Add items to the application's product list. Make sure that you publish the items (the application can remain unpublished). - <p>See <a href="{@docRoot}guide/market/billing/billing_admin.html#billing-catalog">Creating a product list</a> to learn how to do this.</p> + <li><strong>Upload your application as a draft application to the publisher site.</strong> + <p>You do not need to publish your application to perform end-to-end testing with real product IDs. To learn how to upload an application to Android Market, see <a href="http://market.android.com/support/bin/answer.py?answer=113469">Uploading applications</a>.</p> + </li> + <li><strong>Add items to the application's product list.</strong> + <p>Make sure that you publish the items (the application can remain unpublished). See <a href="{@docRoot}guide/market/billing/billing_admin.html#billing-catalog">Creating a product list</a> to learn how to do this.</p> </li> - <li>Install your application on an Android-powered device. - <p>See <a href="{@docRoot}guide/developing/device.html">Developing on a Device</a> for more information about how to do this.</p> + <li><strong>Install your application on an Android-powered device.</strong> + <p>You cannot use the emulator to test in-app billing; you must install your application on a device to test in-app billing.</p> + <p>To learn how to install an application on a device, see <a href="{@docRoot}guide/developing/building/building-cmdline.html#RunningOnDevice">Running on a device</a>.</p> </li> - <li>Sign in to the device using one of the <a href="{@docRoot}guide/market/billing/billing_admin.html#billing-testing-setup">trusted tester accounts</a> that you registered on the Android Market site. - <p>We recommend that you make the test account the primary account on the device. To sign in to a device, do the following:</p> + <li><strong>Make one of your test accounts the primary account on your device.</strong> + <p>To perform end-to-end testing of in-app billing, the primary account on your device must be one of the <a href="{@docRoot}guide/market/billing/billing_admin.html#billing-testing-setup">test accounts</a> that you registered on the Android Market site. If the primary account on your device is not a test account, you must do a factory reset of the device and then sign in with one of your test accounts. To perform a factory reset, do the following:</p> <ol> - <li>Open Settings > Accounts & sync</li> - <li>Select <strong>Add Account</strong> and choose to add a "Google" account.</li> - <li>Select <strong>Next</strong> and then <strong>Sign in</strong>.</li> - <li>Enter the username and password of the test account.</li> - <li>Select <strong>Sign in</strong>. The system signs you in to the new account.</li> + <li>Open Settings on your device.</li> + <li>Touch <strong>Privacy</strong>.</li> + <li>Touch <strong>Factory data reset</strong>.</li> + <li>Touch <strong>Reset phone</strong>.</li> + <li>After the phone resets, be sure to sign in with one of your test accounts during the device setup process.</li> </ol> </li> - <li>Make in-app purchases in your application.</li> + <li><strong>Verify that your device is running a supported version of the Android Market application or the MyApps application.</strong> + <p>If your device is running Android 3.0, in-app billing requires version 5.0.12 (or higher) of the MyApps application. If your device is running any other version of Android, in-app billing requires version 2.3.4 (or higher) of the Android Market application. To learn how to check the version of the Android Market application, see <a href="http://market.android.com/support/bin/answer.py?answer=190860">Updating Android Market</a>.</p> + </li> + <li><strong>Make in-app purchases in your application.</strong></li> </ol> <p class="note"><strong>Note:</strong> The only way to change the primary account on a device is to do a factory reset, making sure you log on with your primary account first.</p> diff --git a/docs/html/guide/market/billing/index.jd b/docs/html/guide/market/billing/index.jd index 6985179..e7f8ee3 100755 --- a/docs/html/guide/market/billing/index.jd +++ b/docs/html/guide/market/billing/index.jd @@ -1,12 +1,6 @@ page.title=In-app Billing @jd:body -<style type="text/css"> - #jd-content { - background:transparent url({@docRoot}assets/images/preliminary.png) repeat scroll 0 0; - } -</style> - <div id="qv-wrapper"> <div id="qv"> @@ -30,23 +24,23 @@ page.title=In-app Billing </div> <div class="special" style="margin-right:345px"> - <p>This documentation provides an early look at the Android Market In-app Billing service. The documentation may change without notice.</p> + <p>During the testing phase of the in-app billing release you cannot publish applications that implement in-app billing. You can only upload in-app billing applications as draft applications. For more information, see <a href="{@docRoot}guide/market/billing/billing_about.html">About this Release</a></p> </div> <p>In-app billing is an Android Market service that lets you sell digital content in your applications. You can use the service to sell a wide range of content, including downloadable content such as media files or photos, and virtual content such as game levels or potions.</p> -<p>When you use the Android Market In-app Billing service to sell an item, Android Market handles all checkout details so your application never has to directly process any financial transactions. Android Market uses the same checkout service that is used for application purchases, so your users experience a consistent and familiar purchase flow (see figure 1). Also, the transaction fee for in-app purchases is the same as the transaction fee for application purchases (30%).</p> +<p>When you use the Android Market in-app billing service to sell an item, Android Market handles all checkout details so your application never has to directly process any financial transactions. Android Market uses the same checkout service that is used for application purchases, so your users experience a consistent and familiar purchase flow (see figure 1). Also, the transaction fee for in-app purchases is the same as the transaction fee for application purchases (30%).</p> -<p>Any application that you publish through Android Market can implement in-app billing. No special account or registration is required other than an Android Market publisher account and a Google Checkout merchant account. Also, because the service uses no dedicated framework APIs, you can add in-app billing to any application that uses a minimum API level of 4 or higher.</p> +<p>Any application that you publish through Android Market can implement in-app billing. No special account or registration is required other than an Android Market publisher account and a Google Checkout Merchant account. Also, because the service uses no dedicated framework APIs, you can add in-app billing to any application that uses a minimum API level of 4 or higher.</p> <p>To help you integrate in-app billing into your application, the Android SDK provides a sample application that demonstrates a simple implementation of in-app billing. The sample application contains examples of billing-related classes you can use to implement in-app billing in your application. It also contains examples of the database, user interface, and business logic you might use to implement in-app billing.</p> <p class="caution"><strong>Important</strong>: Although the sample application is a working example of how you can implement in-app billing, we <em>strongly recommend</em> that you modify and obfuscate the sample code before you use it in a production application. For more information, see <a href="{@docRoot}guide/market/billing/billing_best_practices.html">Security and Design</a>.</p> -<div style="margin:2em 1em 1em 1em;"> -<img src="{@docRoot}images/billing_checkout_flow.png" style="text-align:left;" /> -<div style="margin:.25em 1.25em;padding:0"><strong>Figure 1.</strong> Applications initiate in-app billing requests through their own UI (first screen). Android Market responds to the request by providing the checkout user interface (middle screen). When checkout is complete, the application resumes.</div> -</div> +<img src="{@docRoot}images/billing_checkout_flow.png" height="382" id="figure1" /> +<p class="img-caption"> + <strong>Figure 1.</strong> Applications initiate in-app billing requests through their own UI (first screen). Android Market responds to the request by providing the checkout user interface (middle screen). When checkout is complete, the application resumes. +</p> <p>To learn more about the in-app billing service and start integrating in-app billing into your applications, read the following documents:</p> diff --git a/docs/html/images/billing_product_list_entry.png b/docs/html/images/billing_product_list_entry.png Binary files differnew file mode 100755 index 0000000..b7bfc7a --- /dev/null +++ b/docs/html/images/billing_product_list_entry.png diff --git a/docs/html/images/billing_refund.png b/docs/html/images/billing_refund.png Binary files differnew file mode 100755 index 0000000..09fc33c --- /dev/null +++ b/docs/html/images/billing_refund.png diff --git a/docs/html/images/billing_request_purchase.png b/docs/html/images/billing_request_purchase.png Binary files differindex e8a1b30..c84016e 100755 --- a/docs/html/images/billing_request_purchase.png +++ b/docs/html/images/billing_request_purchase.png diff --git a/docs/html/images/billing_restore_transactions.png b/docs/html/images/billing_restore_transactions.png Binary files differindex 116aa0e..7911304 100755 --- a/docs/html/images/billing_restore_transactions.png +++ b/docs/html/images/billing_restore_transactions.png |