1page.title=In-app Promotions 2parent.title=In-app Billing 3parent.link=index.html 4page.metaDescription=Support promo codes in your app, which let you give content or features away to a limited number of users free of charge. 5page.image=/images/play_dev.jpg 6page.tags="promotions, billing, promo codes" 7meta.tags="monetization, inappbilling, promotions" 8@jd:body 9 10<div id="qv-wrapper"> 11<div id="qv"> 12 <h2>Quickview</h2> 13 <h2>In this document</h2> 14 <ol> 15 <li><a href="#workflow">Creating and Redeeming Promo Codes</a></li> 16 <li><a href="#supporting">Supporting Promo Codes In Your App</a></li> 17 <li><a href="#testing">Testing In-app Promotions</a></li> 18 </ol> 19 <h2>See also</h2> 20 <ol> 21 <li><a href="{@docRoot}google/play/billing/billing_integrate.html">Implementing 22 In-app Billing</a></li> 23 <!-- TODO: link to blog post when available --> 24 </ol> 25</div> 26</div> 27 28<p> 29 Promo codes let you give content or features away to a limited number of 30 users free of charge. Once you create a promo code, you can distribute it 31 subject to the 32 <!--TODO: Link to TOS when/if they're available as a web page --> terms of 33 service. The user enters the promo code in your app or in the Play Store app, 34 and gets the item at no cost. You can use promo codes in many ways to 35 creatively engage with users. For example: 36</p> 37 38<ul> 39 <li>A game could have a special item, such as a character or decoration, 40 that's only available to players who attend an event. The developer could 41 distribute cards with promo codes at the event, and users would enter their 42 promo code to unlock the item. 43 </li> 44 45 <li>An app developer might distribute promo codes at local businesses, to 46 encourage potential users to try the app. 47 </li> 48 49 <li>An app developer might give out "friends and family" codes to its employees to 50 share with their friends. 51 </li> 52</ul> 53 54<p> 55 Every promo code is associated with a particular <em>product ID</em> (also 56 known as a <em>SKU</em>). You can create promo codes for your existing in-app 57 products. You can also keep a SKU off the Play Store, so the only way to get 58 that item is by entering that SKU's promo code. When a user enters the promo 59 code in the Play Store or in their app, the user gets the item, just as if 60 they paid full price for it. If your app already uses <a href= 61 "{@docRoot}google/play/billing/api.html">In-app Billing version 3</a> to 62 support in-app purchases, it's easy to add support for promo codes. 63</p> 64 65<h2 id="workflow">Creating and Redeeming Promo Codes</h2> 66 67<p> 68 You create promo codes through the <a href= 69 "https://play.google.com/apps/publish/" class="external-link">Google Play 70 Developer Console</a>. Each promo code is associated with a single product item 71 registered in the developer console. 72</p> 73 74<p> 75 When a user gets a promo code, they redeem it in one of two ways: 76</p> 77 78<ul> 79 <li>The user can enter the promo code as part of the app's ordinary purchase flow, as 80 described in <a href="{@docRoot}google/play/billing/billing_integrate.html"> 81 Implementing In-app Billing</a>. As far as the app is concerned, this is 82 just like an ordinary purchase, except that the user makes payment with a 83 promo code instead of with money. 84 </li> 85 86 <li>The user can redeem the code in the Google Play Store app. Once the user 87 enters the code, the Play Store prompts the user to open the app (if they have 88 the latest version installed) or to download or update it. (We do not 89 currently support redeeming promo codes from the Google Play web store.) 90 </li> 91</ul> 92 93<p> 94 If the promo code is for a <a href= 95 "{@docRoot}google/play/billing/api.html#consumetypes">consumable product</a>, 96 the user can apply an additional code for the same product <em>after</em> the first 97 product is consumed. For example, a game might offer promo codes for a bundle 98 of extra lives. Betty has two different promo codes for that bundle. She 99 redeems a single promo code, then launches the game. When the game launches, 100 the her character receives the lives, consuming the item. She can now redeem 101 the second promo code for another bundle of lives. (She cannot redeem the 102 second promo code until after she consumes the item she purchased with the 103 first promo code.) 104</p> 105 106<h2 id="supporting">Supporting Promo Codes In Your App</h2> 107 108<p> 109 To support promotion codes, your app should call the <a href= 110 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 111 ><code>getPurchases()</code></a> 112 method whenever the app starts or resumes. This method returns a bundle of all 113 current, unconsumed purchases, including purchases the user made by redeeming 114 a promo code. This simplest approach is to call <a href= 115 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 116 ><code>getPurchases()</code></a> 117 in your activity's {@link android.app.Activity#onResume onResume()} method, 118 since that callback fires when the activity is created, as well as when the 119 activity is unpaused. Calling <a href= 120 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 121 ><code>getPurchases()</code></a> 122 on startup and resume guarantees that your app will find out about all 123 purchases and redemptions the user may have made while the app wasn't 124 running. Furthermore, if a user makes a purchase while the app is running and 125 your app misses it for any reason, your app will still find out about the 126 purchase the next time the activity resumes and calls <a href= 127 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 128 ><code>getPurchases()</code></a>. 129</p> 130 131<p> 132 In addition, your app should allow users to redeem promo codes inside the app 133 itself. If your app supports the in-app purchase workflow (described in 134 <a href= 135 "{@docRoot}google/play/billing/billing_integrate.html#billing-requests">Making 136 In-app Billing Requests</a>), your app automatically supports in-app 137 redemption of promo codes. When you launch the in-app purchase UI, 138 the user has the option to pay for the purchase with 139 a promo code. Your activity's {@link android.app.Activity#onActivityResult 140 onActivityResult()} method receives a response intent telling the app whether the 141 purchase was completed. However, your app should still call <a href= 142 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 143 ><code>getPurchases()</code></a> 144 on startup and resume, just in case the purchase and consumption workflow 145 didn't complete. For example, if the user successfully redeems a promo code, 146 and then your app crashes before the item is consumed, your app still gets 147 information about the purchase when the app calls <a href= 148 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 149 ><code>getPurchases()</code></a> on its next startup. 150</p> 151 152<p> 153 Your app should also support the scenario where a user redeems a promo code 154 in the Play Store app while the app is running. Your app can find out right 155 away when the user redeems a code by registering a listener for the 156 <code>PURCHASES_UPDATED</code> intent. The Play Store fires this intent 157 whenever a user redeems a promo code. 158</p> 159 160<p> 161 To listen for the <code>PURCHASES_UPDATED</code> intent, dynamically create a 162 {@link android.content.BroadcastReceiver} object and register it to listen 163 for <code>"com.android.vending.billing.PURCHASES_UPDATED"</code>. Register 164 the receiver by putting code like this in your activity's {@link 165 android.app.Activity#onResume onResume()} method: 166</p> 167 168<pre>IntentFilter promoFilter = 169 new IntentFilter("com.android.vending.billing.PURCHASES_UPDATED"); 170registerReceiver(myPromoReceiver, promoFilter);</pre> 171 172<p> 173 When the user makes a purchase, the system invokes your broadcast receiver's 174 {@link android.content.BroadcastReceiver#onReceive onReceive()} method. That 175 method should call <a href= 176 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 177 ><code>getPurchases()</code></a> 178 to see what purchases the user has made. 179</p> 180 181<p> 182 Your activity's {@link android.app.Activity#onPause onPause()} method should 183 unregister the broadcast receiver, to reduce system overhead when your app 184 isn't running: 185</p> 186 187<pre>unRegisterReceiver(myPromoReceiver);</pre> 188 189<p class="note"> 190 <strong>Note:</strong> You should not register this broadcast receiver in the 191 app manifest. Declaring the receiver in the manifest can cause the system to 192 launch the app to handle the intent if the user makes a purchase while the app 193 isn't running. This behavior is not necessary, and may be annoying to the 194 user. Instead, your app should call <a href= 195 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 196 ><code>getPurchases()</code></a> 197 when the user launches it, to find out about any purchases the user made 198 while the app wasn't running. 199</p> 200 201<h2 id="testing">Testing In-app Promotions</h2> 202 203<p> 204 If your app supports in-app promotions, you should test the following use 205 cases. 206</p> 207 208<h3 id="test-inapp">User redeems promo code in the app</h3> 209 210<p> 211 If the user redeems a promo code within the app's purchase flow, as described 212 in <a href= 213 "{@docRoot}google/play/billing/billing_integrate.html#billing-requests">Making 214 In-app Billing Requests</a>, the system invokes your activity's {@link 215 android.app.Activity#onActivityResult onActivityResult()} method to handle 216 the purchase. Verify that {@link android.app.Activity#onActivityResult 217 onActivityResult()} handles the purchase properly, whether the user uses cash 218 or a promo code. 219</p> 220 221<h3 id="test-playstore">User redeems promo code in the Play Store</h3> 222 223<p> 224 If the user redeems a promo code in the Play Store, there are several 225 possible workflows. You should verify each one of these. 226</p> 227 228<h4 id="test-app-uninstalled">App is not installed</h4> 229 230<p> 231 If the user redeems a promo code for an app that is not installed on the 232 device, the Play Store prompts the user to install the app. (If the app is 233 installed but not up-to-date, the Play Store prompts the user to update the 234 app.) You should test the following sequence on a device that does not 235 have your app installed. 236</p> 237 238<ol> 239 <li>User redeems a promo code for the app in the Play Store. The Play Store 240 prompts the user to install your app. 241 </li> 242 243 <li>User installs and launches your app. Verify that on startup, the app 244 calls <a href= 245 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 246 ><code>getPurchases()</code></a> 247 and correctly detects the purchase the user made with the promo code. 248 </li> 249</ol> 250 251<h4 id="test-app-not-running">App is installed, but not running</h4> 252 253<p> 254 If the user redeems a promo code for an app that is installed on the device, 255 the Play Store prompts the user to switch to the app. You should test the 256 following sequence on a device that has your app installed but not running: 257</p> 258 259<ol> 260 <li>User redeems a promo code for the app in the Play Store. The Play Store 261 prompts the user to switch to your app. 262 </li> 263 264 <li>User launches your app. Verify that on startup, the app calls <a href= 265 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 266 ><code>getPurchases()</code></a> 267 and correctly detects the purchase the user made with the promo code. 268 </li> 269</ol> 270 271<h4 id="test-app-running">App is installed and running 272</h4> 273 274<p> 275 If the user redeems a promo code for an app that is currently running on the 276 device, the Play Store notifies the app via a <code>PURCHASES_UPDATED</code> 277 intent. You should test the following sequence: 278</p> 279 280<ol> 281 <li>User launches the app. Verify that the app has properly registered itself to 282 receive the <code>PURCHASES_UPDATED</code> intent. 283 </li> 284 285 <li>User launches the Play Store app and redeems a promo code for the app. The Play 286 Store fires a <code>PURCHASES_UPDATED</code> intent. Verify that your app's 287 {@link android.content.BroadcastReceiver#onReceive 288 BroadcastReceiver.onReceive()} callback fires to handle the intent. 289 </li> 290 291 <li>Your {@link android.content.BroadcastReceiver#onReceive onReceive()} 292 method should respond to the intent by calling <a href= 293 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 294 ><code>getPurchases()</code></a>. Verify that it calls this method, and that 295 it correctly detects the purchase the user made with the promo code. 296 </li> 297 298 <li>User switches back to your app. Verify that the user has the purchased 299 item. 300 </li> 301</ol> 302