Dirk Dougherty | 57bb89f | 2013-06-11 20:10:54 -0700 | [diff] [blame] | 1 | page.title=Purchase Status API |
| 2 | page.tags="In-app Billing", "Google Play", "inapp billing", "in app billing", "iab", "billing" |
| 3 | |
| 4 | @jd:body |
| 5 | |
| 6 | <div id="qv-wrapper"> |
| 7 | <div id="qv"> |
| 8 | <h2>In this document</h2> |
| 9 | <ol> |
| 10 | <li><a href="#overview">Overview</a></li> |
| 11 | <li><a href="#using">Using the API</a></li> |
| 12 | <li><a href="#strategies">Verification Strategies</a></li> |
| 13 | <li><a href="#practices">Using the API Efficiently</a></li> |
| 14 | </ol> |
| 15 | <h2>See also</h2> |
| 16 | <ol> |
| 17 | <li><a href="https://developers.google.com/android-publisher/v1_1/">Google Play Android Developer API</a></li> |
| 18 | </ol> |
| 19 | </div> |
| 20 | </div> |
| 21 | |
| 22 | <p>Google Play provides an HTTP-based Purchase Status API that lets |
| 23 | you remotely query the status of a specific in-app product or subscription, |
| 24 | or cancel an active subscription. The API is designed to be used from your |
| 25 | backend servers as a way of securely managing in-app products and |
| 26 | subscriptions, as well as extending and integrating them with other services.</p> |
| 27 | |
| 28 | <h2 id="overview">Overview</h2> |
| 29 | |
| 30 | <p>With the Purchase Status API you can quickly retrieve the details of any |
| 31 | purchase using a standard GET request. In the request you supply information |
| 32 | about the purchase — app package name, purchase or subscription ID, |
| 33 | and the purchase token. The server responds with a JSON object describing |
| 34 | the associated purchase details, order status, developer payload, and other |
| 35 | information.</p> |
| 36 | |
| 37 | <p>You can use the Purchase Status API in several ways, such as for reporting |
| 38 | and reconciliation of individual orders and for verifying purchases and |
| 39 | subscription expirations. You can also use the API to learn about cancelled |
| 40 | orders and confirm whether in-app products have been consumed, including |
| 41 | whether they were consumed before being cancelled.</p> |
| 42 | |
| 43 | <p>For subscriptions, in addition to querying for order status and expiration, |
| 44 | you can use the Purchase Status API to remotely cancel a subscription. This is a |
| 45 | convenient way to manage cancellations on behalf of customers, without |
| 46 | requiring them to manage the cancellation themselves on their Android devices.</p> |
| 47 | |
| 48 | <p>If you plan to use the Purchase Status API, keep in mind that:</p> |
| 49 | <ul><li>You can use the API to check the status of individual items only |
| 50 | — bulk requests for order status are not supported at this time.</li> |
| 51 | <li>You can query for the details of orders placed on or after 12 June 2013, |
| 52 | but not for orders placed earlier.</li> |
| 53 | <li>You can query purchases of any item type made with the In-app |
| 54 | Billing v3 API, or purchases of managed items made with In-app Billing v1 and |
| 55 | v2. You can not use the Purchase Status API to query purchases of unmanaged items |
| 56 | made with In-app Billing v1 or v2.</li> |
| 57 | </ul> |
| 58 | |
| 59 | <p>The Purchase Status API is part of the <a |
| 60 | href="https://developers.google.com/android-publisher/v1_1/">Google Play Android |
Katie McCormick | 5719ee1 | 2013-12-10 16:08:16 -0800 | [diff] [blame] | 61 | Developer API v1.1</a>, available through the Google Developers Console. The new version |
Dirk Dougherty | 57bb89f | 2013-06-11 20:10:54 -0700 | [diff] [blame] | 62 | of the API supersedes the v1 API, which is deprecated. If you are using the v1 |
| 63 | API, please migrate your operations to the v1.1 API as soon as possible.</p> |
| 64 | |
| 65 | |
| 66 | <h2 id="using">Using the API</h2> |
| 67 | |
| 68 | <p>To use the API, you must first register a project at the <a |
Katie McCormick | 5719ee1 | 2013-12-10 16:08:16 -0800 | [diff] [blame] | 69 | href="https://cloud.google.com/console">Google Developers Console</a> and receive |
Dirk Dougherty | 57bb89f | 2013-06-11 20:10:54 -0700 | [diff] [blame] | 70 | a Client ID and shared secret that your app will present when calling the |
| 71 | API. All calls are authenticated with OAuth 2.0.</p> |
| 72 | |
| 73 | <p>Once your app is registered, you can access the API directly, using standard |
| 74 | HTTP methods to retrieve and manipulate resources. The API is built on a RESTful |
| 75 | design that uses HTTP and JSON. so any standard web stack can send requests and |
| 76 | parse the responses. However, if you don’t want to send HTTP requests and parse |
| 77 | responses manually, you can access the API using the Google APIs Client |
| 78 | Libraries, which provide better language integration, improved security, |
| 79 | and support for making calls that require user authorization.</p> |
| 80 | |
| 81 | <p>For more information about the API and how to access it through the Google |
| 82 | APIs Client Libraries, see the documentation at:</p> |
| 83 | |
| 84 | <p style="margin-left:1.5em;"><a |
| 85 | href="https://developers.google.com/android-publisher/v1_1/">https://developers. |
| 86 | google.com/android-publisher/v1_1/</a></p> |
| 87 | |
| 88 | <h3 id="quota">Quota</h3> |
| 89 | |
| 90 | <p>Applications using the Google Play Android Developer API are limited to an |
Dirk Dougherty | 1ef5374 | 2013-09-17 09:13:29 -0700 | [diff] [blame] | 91 | initial courtesy usage quota of <strong>200,000 requests per day</strong> (per |
Dirk Dougherty | 57bb89f | 2013-06-11 20:10:54 -0700 | [diff] [blame] | 92 | application). This should provide enough access for normal |
| 93 | subscription-validation needs, assuming that you follow the recommendation in |
| 94 | this section.</p> |
| 95 | |
Katie McCormick | 63cd380 | 2013-10-09 16:46:23 -0700 | [diff] [blame] | 96 | <p>If you need to request a higher limit for your application, see the |
| 97 | instructions in the <a |
Katie McCormick | 5719ee1 | 2013-12-10 16:08:16 -0800 | [diff] [blame] | 98 | href="https://developers.google.com/console/help/new/#trafficcontrols">Google Developers |
| 99 | Console Help</a>. |
Dirk Dougherty | 57bb89f | 2013-06-11 20:10:54 -0700 | [diff] [blame] | 100 | Also, please read the section below on design best practices for minimizing your |
| 101 | use of the API.</p> |
| 102 | |
| 103 | <h3 id="auth">Authorization</h3> |
| 104 | |
| 105 | <p>Calls to the Google Play Android Developer API require authorization. Google |
| 106 | uses the OAuth 2.0 protocol to allow authorized applications to access user |
| 107 | data. To learn more, see <a |
| 108 | href="https://developers.google.com/android-publisher/authorization">Authorization</a> |
| 109 | in the Google Play Android Developer API documentation.</p> |
| 110 | |
| 111 | <h2 id="strategies">Purchase Verification Strategies</h2> |
| 112 | |
| 113 | <p>In a typical scenario, your app verifies the order status for new purchases |
| 114 | to ensure that they are valid before granting access to the purchased content.</p> |
| 115 | |
| 116 | <p>To verify a purchase, the app passes the purchase token and other details up |
| 117 | to your backend servers, which verifies them directly with Google Play using the |
| 118 | Purchase Status API. For security reasons, the app should not normally attempt to verify |
| 119 | the purchase itself using the Purchase Status API.</p> |
| 120 | |
| 121 | <p>If the backend server determines that the purchase is valid, it notifies the |
Dirk Dougherty | a9dcc33 | 2013-06-18 10:35:42 -0700 | [diff] [blame] | 122 | app and grants access to the content. For improved performance, the backend servers |
| 123 | should store the purchase details and order status in a local database, updated at |
Dirk Dougherty | 57bb89f | 2013-06-11 20:10:54 -0700 | [diff] [blame] | 124 | intervals or as-needed.</p> |
| 125 | |
Dirk Dougherty | a9dcc33 | 2013-06-18 10:35:42 -0700 | [diff] [blame] | 126 | <p>Keep in mind that users will want the ability to use your app at any time, including |
Dirk Dougherty | 57bb89f | 2013-06-11 20:10:54 -0700 | [diff] [blame] | 127 | when there may be no network connection available. Make sure that your approach to |
Dirk Dougherty | a9dcc33 | 2013-06-18 10:35:42 -0700 | [diff] [blame] | 128 | purchase verification accounts for the offline use-case.</p> |
Dirk Dougherty | 57bb89f | 2013-06-11 20:10:54 -0700 | [diff] [blame] | 129 | |
| 130 | <h2 id="practices">Using the API Efficiently</h2> |
| 131 | |
| 132 | <p>Access to the Google Play Android Developer API is regulated to help ensure a |
| 133 | high-performance environment for all applications that use it. While you can |
| 134 | request a higher daily quota for your application, we highly recommend that you |
| 135 | minimize your access using the techniques below. </p> |
| 136 | |
| 137 | <ul> |
| 138 | <li><em>Query the Purchase Status API for new purchases only</em> — At |
| 139 | purchase, your app can pass the purchase token and other details to your backend |
| 140 | servers, which can use the Purchase Status API to verify the purchase.</li> |
| 141 | <li><em>Cache purchase details on your servers</em> — To the extent possible, |
| 142 | cache the purchase details for in-app products and subscriptions on your backend |
| 143 | servers. If your app contacts your backend servers at runtime to verify purchase |
| 144 | validity, your server can verify the purchase based on the cached details, to |
| 145 | minimize use of the Purchase Status API and to provide the fastest possible response |
| 146 | (and best experience) for the user.</li> |
| 147 | <li><em>Store subscription expiry on your servers</em> — Your servers should |
| 148 | use the Purchase Status API to query the expiration date for new subscription tokens, |
| 149 | then store the expiration date locally. This allows you to check the status of |
| 150 | subscriptions only at or after the expiration (see below).</li> |
| 151 | <li><em>Query for subscription status only at expiration</em> — Once your |
| 152 | server has retrieved the expiration date of subscription tokens, it should not query |
| 153 | the Google Play servers for the subscription status again until the subscription is |
| 154 | reaching or has passed the expiration date. Typically, your servers would run a batch |
| 155 | query each day to check the status of expiring subscriptions, then update the database. |
| 156 | Note that: |
| 157 | <ul> |
Dirk Dougherty | a9dcc33 | 2013-06-18 10:35:42 -0700 | [diff] [blame] | 158 | <li>Your servers should not query all subscriptions every day.</li> |
Dirk Dougherty | 57bb89f | 2013-06-11 20:10:54 -0700 | [diff] [blame] | 159 | <li>Your servers should never query subscription status dynamically, based on |
| 160 | individual requests from your Android application.</li> |
| 161 | </ul> |
| 162 | </li> |
| 163 | </ul> |
| 164 | |
| 165 | <p>By following those general guidelines, your implementation will offer the |
Dirk Dougherty | a9dcc33 | 2013-06-18 10:35:42 -0700 | [diff] [blame] | 166 | best possible performance for users and minimize use of the <a |
| 167 | href="https://developers.google.com/android-publisher/v1_1/">Google Play Android |
| 168 | Developer API</a>.</p> |