• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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