1 page.title=Implementing Subscriptions <span style="font-size:16px;">(IAB Version 2)</span> 2 excludeFromSuggestions=true 3 @jd:body 4 5 <p class="caution" style= 6 "background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;"> 7 The <strong>In-app Billing Version 2 API</strong> has been deprecated in 8 favor of the Version 3 API. If your app is using In-app Billing, please 9 <strong>make sure that it is using the Version 3 API</strong>. If your app is 10 still using the Version 2 API, you must <strong>migrate to the Version 3 API 11 as soon as possible</strong>.<br> 12 <br> 13 We plan to turn off the In-app Billing Version 2 service on <strong>January 14 27, 2015</strong>, after which time users will <strong>no longer be able to 15 purchase in-app items and subscriptions through the Version 2 API</strong>. 16 We strongly encourage and recommend you migrate your apps to use Version 3 17 API by November 2014, to provide ample time for users to update their apps to 18 the new version.<br> 19 <br> 20 For more information, please see the <a href= 21 "http://support.google.com/googleplay/android-developer/answer/6090268">Help Center 22 article</a>. For common questions about transitioning your implementation to 23 In-app Billing Version 3, please see <a href= 24 "{@docRoot}google/play/billing/billing_overview.html#migration">Migration 25 Considerations</a>. 26 </p> 27 <div id="qv-wrapper" style="margin-top:0;"> 28 <div id="qv"> 29 <h2>In this document</h2> 30 <ol> 31 <li><a href="#sample">Sample Application</a></li> 32 <li><a href="#model">Application Model</a></li> 33 <li><a href="#token">Purchase Token</a></li> 34 <li><a href="#version">Checking the In-app Billing API Version</a></li> 35 <li><a href="#purchase">Purchasing a Subscription</a></li> 36 <li><a href="#restore">Restoring Transactions</a></li> 37 <li><a href="#validity">Checking Subscription Validity</a></li> 38 <li><a href="#viewstatus">Letting Users Cancel or View Status</a></li> 39 <li><a href="#purchase-state-changes">Recurring Billing and Changes in Purchase State</a></li> 40 <li><a href="#modifying">Modifying Your App for Subscriptions</a></li> 41 </ol> 42 </div> 43 </div> 44 45 <p>This document is focused on highlighting implementation details that are 46 specific to subscriptions with the Version 2 API. To understand how 47 subscriptions work, see <a href="{@docRoot}google/play/billing/billing_subscriptions.html">In-app Billing Subscriptions</a>.</p> 48 49 50 <h2 id="sample">Sample Application</h2> 51 52 <p>To help you get started with your In-app Billing implementation and 53 subscriptions, an updated Version of the In-app Billing sample app is available. 54 You can download the sample app from the Android SDK repository using the 55 Android SDK Manager. For details, see <a 56 href="{@docRoot}google/play/billing/v2/billing_integrate.html#billing-download"> 57 Downloading the Sample Application</a>.</p> 58 59 <h2 id="model">Application Model</h2> 60 61 <p>With subscriptions, your app uses the standard In-app Billing application 62 model, sending billing requests to the Play Store application over interprocess 63 communication (IPC) and receiving purchase responses from the Play Store app in 64 the form of asynchronous broadcast intents. Your application does not manage any 65 network connections between itself and the Google Play server or use any special 66 APIs from the Android platform.</p> 67 68 <p>Your app also uses the standard In-app Billing components — a billing 69 Service for sending requests, a BroadcastReceiver for receiving the responses, 70 and a security component for verifying that the response was sent by Google 71 Play. Also recommended are a response Handler for processing notifications, 72 errors, and status messages, and an observer for sending callbacks to your 73 application as needed. All of these components and their interactions are 74 described in full in the <a 75 href="{@docRoot}google/play/billing/v2/api.html">In-app Billing 76 Overview</a> and related documents.</p> 77 78 <p>To initiate different types of billing communication with Google Play, your 79 app will use the standard set of in-app billing requests and receive the same 80 responses. Inside the requests and responses are two new fields described below. 81 </p> 82 83 <h2 id="token">Purchase Token</h2> 84 85 <p>Central to the end-to-end architecture for subscriptions is the purchase 86 token, a string value that uniquely identifies (and associates) a user ID and a 87 subscription ID. Google Play generates the purchase token when the user 88 completes the purchase of a subscription product (and payment is approved by 89 Google) and then sends it to the purchasing app on the device through the 90 In-app Billing API. </p> 91 92 <p>At the conclusion of a <code>PURCHASE_REQUEST</code> message flow, your app 93 can retrieve the purchase token and other transaction details by initiating a 94 <code>GET_PURCHASE_INFORMATION</code> request. The Bundle returned by the call 95 contains an JSON array of order objects. In the order corresponding to the 96 subscription purchase, the token is available in the <code>purchaseToken</code> 97 field. </p> 98 99 <p>An example of a JSON order object that includes a subscription purchase token 100 is shown below. </p> 101 102 <pre class="no-pretty-print" style="color:black">{ "nonce" : 1836535032137741465, 103 "orders" : 104 [{ "notificationId" : "android.test.purchased", 105 "orderId" : "12999556515565155651.5565135565155651" 106 "packageName" : "com.example.dungeons", 107 "productId" : "android.test.purchased", 108 "developerPayload" : "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ", 109 "purchaseTime" : 1290114783411, 110 "purchaseState" : 0, 111 "purchaseToken" : "rojeslcdyyiapnqcynkjyyjh" }] 112 } 113 </pre> 114 115 <p>After receiving a purchase token, your apps can store the token locally or 116 pass it to your backend servers, which can then use it to query the billing 117 status or cancel the subscription remotely. If your app will store the token 118 locally, please read the <a 119 href="{@docRoot}google/play/billing/billing_best_practices.html">Security and 120 Design</a> document for best practices for maintaining the security of your 121 data.</p> 122 123 <h2 id="version">Checking the In-app Billing API Version</h2> 124 125 <p>Subscriptions support is available only in versions of Google Play that 126 support the In-app Billing v2 API (Google Play 3.5 and higher). For your app, 127 an essential first step at launch is to check whether the Version of Google Play 128 installed on the device supports the In-app Billing v2 API and 129 subscriptions.</p> 130 131 <p>To do this, create a CHECK_BILLING_SUPPORTED request Bundle that includes the 132 required key-value pairs, together with</p> 133 134 <ul> 135 <li>The <code>API_VERSION</code> key, assigning a value of 2.</li> 136 <li>The <code>BILLING_REQUEST_ITEM_TYPE</code> key, assigning a value of subs</li> 137 </ul> 138 139 <p>Send the request using <code>sendBillingRequest(Bundle)</code> and receive 140 the response Bundle. You can extract the response from the 141 <code>BILLING_RESPONSE_RESPONSE_CODE</code> key of the response. RESULT_OK 142 indicates that subscriptions are supported.</p> 143 144 <p>The sample app declares constants for the accepted 145 <code>BILLING_REQUEST_ITEM_TYPE</code> values (from Consts.java):</p> 146 147 <pre class="pretty-print"> // These are the types supported in the IAB v2 148 public static final String ITEM_TYPE_INAPP = "inapp"; 149 public static final String ITEM_TYPE_SUBSCRIPTION = "subs"; 150 </pre> 151 152 <p>It sets up a convenience method for building the request bundle (from BillingService.java):</p> 153 154 <pre class="pretty-print"> protected Bundle makeRequestBundle(String method) { 155 Bundle request = new Bundle(); 156 request.putString(Consts.BILLING_REQUEST_METHOD, method); 157 request.putInt(Consts.BILLING_REQUEST_<code>API_VERSION</code>, 2); 158 request.putString(Consts.BILLING_REQUEST_PACKAGE_NAME, getPackageName()); 159 return request; 160 } 161 </pre> 162 163 <p>Heres an example of how to test support for In-App Billing v2 and subscriptions 164 (from BillingService.java):</p> 165 166 <pre class="pretty-print"> /** 167 * Wrapper class that checks if in-app billing is supported. 168 */ 169 class CheckBillingSupported extends BillingRequest { 170 public String mProductType = null; 171 public CheckBillingSupported() { 172 // This object is never created as a side effect of starting this 173 // service so we pass -1 as the startId to indicate that we should 174 // not stop this service after executing this request. 175 super(-1); 176 } 177 178 public CheckBillingSupported(String type) { 179 super(-1); 180 mProductType = type; 181 } 182 183 @Override 184 protected long run() throws RemoteException { 185 Bundle request = makeRequestBundle("CHECK_BILLING_SUPPORTED"); 186 if (mProductType != null) { 187 request.putString(Consts.<code>BILLING_REQUEST_ITEM_TYPE</code>, mProductType); 188 } 189 Bundle response = mService.sendBillingRequest(request); 190 int responseCode = response.getInt(Consts.<code>BILLING_RESPONSE_RESPONSE_CODE</code>); 191 if (Consts.DEBUG) { 192 Log.i(TAG, "CheckBillingSupported response code: " + 193 ResponseCode.valueOf(responseCode)); 194 } 195 boolean billingSupported = (responseCode == ResponseCode.RESULT_OK.ordinal()); 196 ResponseHandler.checkBillingSupportedResponse(billingSupported, mProductType); 197 return Consts.BILLING_RESPONSE_INVALID_REQUEST_ID; 198 } 199 } 200 </pre> 201 202 <h2 id="purchase">Requesting a Subscription Purchase</h2> 203 204 <p>Once youve checked the API Version as described above and determined that 205 subscriptions are supported, you can present subscription products to the user 206 for purchase. When the user has selected a subscription product and initiated a 207 purchase, your app handles the purchase just as it would for other in-app 208 products — by sending a REQUEST_PURCHASE request. You can then launch 209 Google Play to display the checkout user interface and handle the financial 210 transaction.. 211 212 <p>The REQUEST_PURCHASE includes a Bundle containing the item details, as 213 described in the <a 214 href="{@docRoot}google/play/billing/v2/api.html">In-app Billing 215 Overview</a>. For a subscription, the Bundle must also specify:</p> 216 217 <ul> 218 <li>The <code>ITEM_ID</code> key, with a value that specifies a valid, published 219 subscription product.</li> 220 <li>The <code>ITEM_TYPE</code> key, with a value of subs 221 (<code>ITEM_TYPE_SUBSCRIPTION</code> in the sample app). If the request does not 222 specify the subscription's <code>ITEM_TYPE</code>, Google Play attempts to 223 handle the request as a standard in-app purchase (one-time purchase).</li> 224 </ul> 225 226 <p>Google Play synchronously returns a response bundle that includes 227 <code>RESPONSE_CODE</code>, <code>PURCHASE_INTENT</code>, and 228 <code>REQUEST_ID</code>. Your app uses the <code>PURCHASE_INTENT</code> to 229 launch the checkout UI and the message flow proceeds exactly as described in <a 230 href="{@docRoot}google/play/billing/v2/api.html#billing-message- 231 sequence">Messaging sequence</a>.</p> 232 233 <p>Heres how the sample app initiates a purchase for a subscription, where 234 <code>mProductType</code> is <code>ITEM_TYPE_SUBSCRIPTION</code> (from 235 BillingService.java).</p> 236 237 <pre class="pretty-print"> /** 238 * Wrapper class that requests a purchase. 239 */ 240 class RequestPurchase extends BillingRequest { 241 public final String mProductId; 242 public final String mDeveloperPayload; 243 public final String mProductType; 244 245 . . . 246 247 @Override 248 protected long run() throws RemoteException { 249 Bundle request = makeRequestBundle("REQUEST_PURCHASE"); 250 request.putString(Consts.BILLING_REQUEST_ITEM_ID, mProductId); 251 request.putString(Consts.<code>BILLING_REQUEST_ITEM_TYPE</code>, mProductType); 252 // Note that the developer payload is optional. 253 if (mDeveloperPayload != null) { 254 request.putString(Consts.BILLING_REQUEST_DEVELOPER_PAYLOAD, mDeveloperPayload); 255 } 256 Bundle response = mService.sendBillingRequest(request); 257 PendingIntent pendingIntent 258 = response.getParcelable(Consts.BILLING_RESPONSE_PURCHASE_INTENT); 259 if (pendingIntent == null) { 260 Log.e(TAG, "Error with requestPurchase"); 261 return Consts.BILLING_RESPONSE_INVALID_REQUEST_ID; 262 } 263 264 Intent intent = new Intent(); 265 ResponseHandler.buyPageIntentResponse(pendingIntent, intent); 266 return response.getLong(Consts.BILLING_RESPONSE_REQUEST_ID, 267 Consts.BILLING_RESPONSE_INVALID_REQUEST_ID); 268 } 269 270 @Override 271 protected void responseCodeReceived(ResponseCode responseCode) { 272 ResponseHandler.responseCodeReceived(BillingService.this, this, responseCode); 273 } 274 } 275 </pre> 276 277 <h2 id="restoring">Restoring Transactions</h2> 278 279 <p>Subscriptions always use the <em>managed by user account</em> purchase type, 280 so that you can restore a record of subscription transactions on the device when 281 needed. When a user installs your app onto a new device, or when the user 282 uninstalls/reinstalls the app on the original device, your app should restore 283 the subscriptions that the user has purchased.</p> 284 285 <p>The process for restoring subscriptions transactions is the same as described 286 in <a 287 href="{@docRoot}google/play/billing/v2/api.html#billing-message- 288 sequence">Messaging sequence</a>. Your app sends a 289 <code>RESTORE_TRANSACTIONS</code> request to Google Play. Google Play sends two 290 broadcast intents as asynchronous responses — a <code>RESPONSE_CODE</code> 291 intent and a <code>PURCHASE_STATE_CHANGED</code> intent.</p> 292 293 <p>The <code>PURCHASE_STATE_CHANGED</code> intent contains a notification ID 294 that your app can use to retrieve the purchase details, including the purchase 295 token, by sending a standard <code>GET_PURCHASE_INFORMATION</code> request. The 296 <code>Bundle</code> returned in the call includes an JSON array of order objects 297 corresponding to subscription (and in-app product) purchases that you can 298 restore locally.</p> 299 300 <p>Your app can store the restored purchase state and other transaction details 301 in the way that best meets your needs. Your app can use it later to check the 302 subscription validity, although please read the <a 303 href="{@docRoot}google/play/billing/billing_best_practices.html">Security and 304 Design</a> document for best practices for maintaining the security of your 305 data.</p> 306 307 <h2 id="validity">Checking Subscription Validity</h2> 308 309 <p>Subscriptions are time-bound purchases that require successful billing 310 recurrences over time to remain valid. Your app should check the validity of 311 purchased subscriptions at launch or prior to granting access to subscriber 312 content.</p> 313 314 <p>With In-app Billing, you validate a subscription by keeping track of its 315 purchase state and then checking the state whenever needed. Google Play 316 provides two ways to let you know when the purchase 317 state of a subscription changes:</p> 318 319 <ul> 320 <li><em>In-app Billing Notifications</em>. Google Play pushes a notification 321 to your app to indicate a change in the purchase state of a subscription. Your app can 322 store the most recent purchase state for a given purchase token and then check 323 that state at run time, as needed.</li> 324 <li><em>Google Play Android Developer API</em>. You can use this HTTP-based 325 API to poll Google Play for the current purchase state of a subscription. You 326 can store the purchased state for each <code>purchaseToken</code> on your 327 backend servers. For more information, see <a href="#play-dev-api">Google Play 328 Android Developer API</a>, below.</li> 329 </ul> 330 331 <p>For most use-cases, especially those where backend servers are already keeping 332 track of subscribed users, implementing a combination of both methods is the 333 recommended approach. A typical implementation might work like this:</p> 334 335 <ul> 336 <li>When the user successfully purchases a new subscription, your app notifies a 337 backend server, which stores the purchase token, user name, and other 338 information in a secure location.</li> 339 <li>Since your app cannot know the expiration date, your server can poll Google 340 Play to get the expiration and store it with the purchase token and other 341 data.</li> 342 <li>Because your server now knows the expiration date, it does not need to poll 343 Google Play again until after the expiration date, at which time it can confirm 344 that the subscription was not cancelled.</li> 345 <li>On the client side, your app can continue to update the server whenever the 346 purchase state changes, storing the state locally.</li> 347 </ul> 348 349 <p>If you are using both notifications and the Google Play Android Developer API to validate subscriptions, we recommend the following:</p> 350 351 <ul> 352 <li>If your app wants to check validity but you cant reach your server (or 353 you dont have a server), use the latest purchase state received by 354 notification.</li> 355 <li>If you have a server and its reachable, always give preference to the 356 purchase state obtained from your server over the state received in 357 notifications.</li> 358 </ul> 359 360 <p>If necessary, you can also use a <code>RESTORE_TRANSACTIONS</code> request to retrieve a record of all managed and in-app products purchased by the user, which you can then store locally. However, using <code>RESTORE_TRANSACTIONS</code> on a regular basis is not recommended because of performance impacts.</p> 361 362 <p>Regardless of the approach you choose, your app should check subscriptions 363 and validity at launch, such as prior to accessing subscriber content, game 364 levels, and so on.</p> 365 366 <p class="table-caption"><strong>Table 1.</strong> Summary of purchaseState 367 values for subscription purchases, as received with a 368 <code>PURCHASE_STATE_CHANGED</code> intent.</p> 369 370 <table> 371 <tr> 372 <th>State</th><th>purchaseState Value</th><th>Comments</th> 373 </tr> 374 <tr> 375 <td>Purchased successfully</td><td><code>0</code></td><td>Sent at original purchase only (not at recurring billing cycles).</td></tr> 376 <td>Cancelled</td><td><code>1</code></td><td>Sent at original purchase only if the purchase has failed for some reason. </td></tr> 377 <td>Refunded</td><td><code>2</code></td><td>The purchase was refunded.</code></td></tr> 378 <td>Subscription expired</td><td><code>3</code></td><td>Sent at the end of a billing cycle to indicate that the subscription expired without renewal because of non-payment or user-cancellation. Your app does not need to grant continued access to the subscription content. 379 </td></tr> 380 </table> 381 382 383 <h2 id="viewstatus">Letting the User Cancel or View Subscriptions</h2> 384 385 <p>In-app Billing does not currently provide an API to let users directly view or cancel 386 subscriptions from within the purchasing app. Instead, users can launch the Play 387 Store app on their devices and go to the My Apps screen to manage subscriptions. In My Apps, 388 users can see a list of their subscriptions organized by application. Tapping one of the 389 subscriptions loads the app's product page, from which users can see active subscriptions 390 and billing status and cancel subscriptions as needed.</p> 391 392 <p>To make it easier for users to find and manage their subscriptions from inside your app, 393 we recommend that you offer a "View My Subscriptions" or "Manage Subscriptions" option in 394 your UI that directly loads your app's product page in the Play Store app.</p> 395 396 <p>To do this, create an intent with the <a 397 href="{@docRoot}reference/android/content/Intent.html#ACTION_VIEW">ACTION_VIEW</a> 398 action and include the <code>market://</code> URI (rather than the <code>http://</code> 399 URI) of your app's details page. Heres an example:</p> 400 401 <pre style="pretty-print">Intent intent = new Intent(Intent.ACTION_VIEW); 402 intent.setData(Uri.parse("market://details?id=com.example.app")); 403 startActivity(intent);</pre> 404 405 <p>For more information, see 406 <a href="{@docRoot}distribute/tools/promote/linking.html">Linking to Your Products</a>.</p> 407 408 <h2 id="purchase-state-changes">Recurring Billing, Cancellation, and Changes In Purchase State</h2> 409 410 <p>Google Play notifies your app when the user completes the purchase of a 411 subscription, but the purchase state does not change over time, provided that 412 recurring billing takes place successfully. Google Play does not notify your app 413 of a purchase state change <em>until the subscription expires because of 414 non-payment or user cancellation</em>. </p> 415 416 <p>Over the life of a subscription, your app does not need to initiate any 417 recurring billing events — those are all handled by Google Play and they 418 are transparent to your application if billing is successful.</p> 419 420 <p>When the user cancels a subscription during an active billing cycle, Google 421 Play <em>does not</em> notify your app immediately of the change in purchase 422 state. Instead, it waits until the end of the active billing cycle and then 423 notifies your app that the purchase state has changed to "Expired". </p> 424 425 <p>Similarly, if payment for the next billing cycle fails, Google Play waits 426 until the end of the active billing cycle and then notifies your app at that time that the 427 purchase state has changed to "Expired".</p> 428 429 <p>Your app can handle user cancellation and non-payment in the same way, since both cause 430 a change to the same "Expired" purchase state. Once the purchase state has become "Expired", 431 your app does not need to grant further access to the subscription content.</p> 432 433 <h2 id="modifying">Modifying Your App for Subscriptions</h2> 434 435 <p>For subscriptions, you make the same types of modifications to your app as 436 are described in <a 437 href="{@docRoot}google/play/billing/v2/billing_integrate.html#billing-implement"> 438 Modifying your Application Code</a>.</p> 439 440 <p>Note that, in your UI that lets users view and select subscriptions for 441 purchase, you should add logic to check for purchased subscriptions and validate 442 them. Your UI should not present subscriptions if the user has already purchased 443 them.</p> 444 445 446 447 448 449