1page.title=In-app Promotions 2parent.title=In-app Billing 3parent.link=index.html 4page.metaDescription=Support promo codes in your app, which lets 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. After 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 Google Play Store app 34 and receives the item at no cost. You can use promo codes in many ways to 35 creatively engage with users, such as the following: 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 codes 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 <em>friends and family codes</em> 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 an SKU off the Play Store, so that 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 an 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 71 registered in the developer console. 72</p> 73 74<p> 75 A user can redeem a promo code in one of these 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. Google doesn't 89 currently support redeeming promo codes from the Google Play web store. 90 </li> 91</ul> 92 93<h2 id="supporting">Supporting Promo Codes in Your App</h2> 94 95<p> 96 To support promotion codes, your app must call the <a href= 97 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 98 ><code>getPurchases()</code></a> 99 method whenever the app starts or resumes. This method returns a bundle of all 100 current, unconsumed purchases, including purchases the user made by redeeming 101 a promo code. The simplest approach is to call <a href= 102 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 103 ><code>getPurchases()</code></a> 104 in your activity's {@link android.app.Activity#onResume onResume()} method, 105 since that callback fires when the activity is created, as well as when the 106 activity is unpaused. Calling <a href= 107 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 108 ><code>getPurchases()</code></a> 109 on startup and resume guarantees that your app finds out about all 110 purchases and redemptions the user may have made while the app wasn't 111 running. Furthermore, if a user makes a purchase while the app is running and 112 your app misses it for any reason, your app still finds out about the 113 purchase the next time the activity resumes and calls <a href= 114 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 115 ><code>getPurchases()</code></a>. 116</p> 117 118<p> 119 Your app should allow users to redeem promo codes inside the app 120 itself. If your app supports the in-app purchase workflow (described in 121 <a href= 122 "{@docRoot}google/play/billing/billing_integrate.html#billing-requests">Making 123 In-app Billing requests</a>), your app automatically supports in-app 124 redemption of promo codes. When you launch the in-app purchase UI, 125 the user has the option to pay for the purchase with 126 a promo code. Your activity's {@link android.app.Activity#onActivityResult 127 onActivityResult()} method receives a response intent telling the app whether the 128 purchase was completed. However, your app should still call <a href= 129 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 130 ><code>getPurchases()</code></a> 131 on startup and resume, in case the purchase and consumption workflow 132 didn't complete. For example, if the user successfully redeems a promo code 133 and then your app crashes before the item is consumed, your app still receives 134 information about the purchase when the app calls <a href= 135 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 136 ><code>getPurchases()</code></a> on its next startup. 137</p> 138 139<p> 140 Your app should also support the scenario where a user redeems a promo code 141 in the Play Store app while the app is running. Your app can find out right 142 away when the user redeems a code by registering a listener for the 143 <code>PURCHASES_UPDATED</code> intent. The Play Store fires this intent 144 whenever a user redeems a promo code. 145</p> 146 147<p> 148 To listen for the <code>PURCHASES_UPDATED</code> intent, dynamically create a 149 {@link android.content.BroadcastReceiver} object and register it to listen 150 for <code>com.android.vending.billing.PURCHASES_UPDATED</code>. Register 151 the receiver by inserting code similar to the following in your activity's {@link 152 android.app.Activity#onResume onResume()} method: 153</p> 154 155<pre>IntentFilter promoFilter = 156 new IntentFilter("com.android.vending.billing.PURCHASES_UPDATED"); 157registerReceiver(myPromoReceiver, promoFilter);</pre> 158 159<p> 160 When the user makes a purchase, the system invokes your broadcast receiver's 161 {@link android.content.BroadcastReceiver#onReceive onReceive()} method. That 162 method must call <a href= 163 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 164 ><code>getPurchases()</code></a> 165 to see what purchases the user has made. 166</p> 167 168<p>To reduce system overhead when your app 169 isn't running, your activity's {@link android.app.Activity#onPause onPause()} method must 170 unregister the broadcast receiver: 171</p> 172 173<pre>unRegisterReceiver(myPromoReceiver);</pre> 174 175<p class="note"> 176 <strong>Note:</strong> Don't register this broadcast receiver in the 177 app manifest. Declaring the receiver in the manifest can cause the system to 178 launch the app to handle the intent if the user makes a purchase while the app 179 isn't running. This behavior is not necessary and may be annoying to the 180 user. 181 To find out about any purchases the user made while the app wasn't running, 182 call <a href="{@docRoot}google/play/billing/billing_reference.html#getPurchases" 183 ><code>getPurchases()</code></a> when the user launches the app. 184</p> 185 186<h2 id="testing">Testing In-app Promotions</h2> 187 188<p> 189 If your app supports in-app promotions, test the following use 190 cases. 191</p> 192 193<h3 id="test-inapp">User redeems promo code in the app</h3> 194 195<p> 196 If the user redeems a promo code within the app's purchase flow, as described 197 in <a href= 198 "{@docRoot}google/play/billing/billing_integrate.html#billing-requests">Making 199 In-app Billing requests</a>, the system invokes your activity's {@link 200 android.app.Activity#onActivityResult onActivityResult()} method to handle 201 the purchase. Verify that {@link android.app.Activity#onActivityResult 202 onActivityResult()} handles the purchase properly, whether the user pays with money 203 or a promo code. 204</p> 205 206<h3 id="test-playstore">User redeems promo code in the Google Play Store</h3> 207 208<p> 209 If the user redeems a promo code in the Play Store, there are several 210 possible workflows. Verify each one of these workflows. 211</p> 212 213<h4 id="test-app-uninstalled">App is not installed</h4> 214 215<p> 216 If the user redeems a promo code for an app that is not installed on the 217 device, the Play Store prompts the user to install the app. (If the app is 218 installed but not up-to-date, the Play Store prompts the user to update the 219 app.) Test the following sequence on a device that doesn't 220 have your app installed. 221</p> 222 223<ol> 224 <li>The user redeems a promo code for the app in the Play Store. The Play Store 225 prompts the user to install your app. 226 </li> 227 228 <li>The user installs and launches your app. Verify that on startup, the app 229 calls <a href= 230 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 231 ><code>getPurchases()</code></a> 232 and correctly detects the purchase the user made with the promo code. 233 </li> 234</ol> 235 236<h4 id="test-app-not-running">App is installed, but not running</h4> 237 238<p> 239 If the user redeems a promo code for an app that is installed on the device, 240 the Play Store prompts the user to switch to the app. Test the 241 following sequence on a device that has your app installed but not running: 242</p> 243 244<ol> 245 <li>The user redeems a promo code for the app in the Play Store. The Play Store 246 prompts the user to switch to your app. 247 </li> 248 249 <li>The user launches your app. Verify that on startup the app calls <a href= 250 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 251 ><code>getPurchases()</code></a> 252 and correctly detects the purchase the user made with the promo code. 253 </li> 254</ol> 255 256<h4 id="test-app-running">App is installed and running 257</h4> 258 259<p> 260 If the user redeems a promo code for an app that is currently running on the 261 device, the Play Store notifies the app via a <code>PURCHASES_UPDATED</code> 262 intent. Test the following sequence: 263</p> 264 265<ol> 266 <li>The user launches the app. Verify that the app has properly registered itself to 267 receive the <code>PURCHASES_UPDATED</code> intent. 268 </li> 269 270 <li>The user launches the Play Store app and redeems a promo code for the app. The Play 271 Store fires a <code>PURCHASES_UPDATED</code> intent. Verify that your app's 272 {@link android.content.BroadcastReceiver#onReceive 273 BroadcastReceiver.onReceive()} callback fires to handle the intent. 274 </li> 275 276 <li>Your {@link android.content.BroadcastReceiver#onReceive onReceive()} 277 method should respond to the intent by calling <a href= 278 "{@docRoot}google/play/billing/billing_reference.html#getPurchases" 279 ><code>getPurchases()</code></a>. Verify that your app calls this method and that 280 it correctly detects the purchase the user made with the promo code. 281 </li> 282 283 <li>The user switches back to your app. Verify that the user has the purchased 284 item. 285 </li> 286</ol> 287