page.title=In-app Promotions parent.title=In-app Billing parent.link=index.html page.metaDescription=Support promo codes in your app, which let you give content or features away to a limited number of users free of charge. page.image=/images/play_dev.jpg page.tags="promotions, billing, promo codes" meta.tags="monetization, inappbilling, promotions" @jd:body

Quickview

In this document

  1. Creating and Redeeming Promo Codes
  2. Supporting Promo Codes In Your App
  3. Testing In-app Promotions

See also

  1. Implementing In-app Billing

Promo codes let you give content or features away to a limited number of users free of charge. Once you create a promo code, you can distribute it subject to the terms of service. The user enters the promo code in your app or in the Play Store app, and gets the item at no cost. You can use promo codes in many ways to creatively engage with users. For example:

Every promo code is associated with a particular product ID (also known as a SKU). You can create promo codes for your existing in-app products. You can also keep a SKU off the Play Store, so the only way to get that item is by entering that SKU's promo code. When a user enters the promo code in the Play Store or in their app, the user gets the item, just as if they paid full price for it. If your app already uses In-app Billing version 3 to support in-app purchases, it's easy to add support for promo codes.

Creating and Redeeming Promo Codes

You create promo codes through the Google Play Developer Console. Each promo code is associated with a single product item registered in the developer console.

When a user gets a promo code, they redeem it in one of two ways:

If the promo code is for a consumable product, the user can apply an additional code for the same product after the first product is consumed. For example, a game might offer promo codes for a bundle of extra lives. Betty has two different promo codes for that bundle. She redeems a single promo code, then launches the game. When the game launches, the her character receives the lives, consuming the item. She can now redeem the second promo code for another bundle of lives. (She cannot redeem the second promo code until after she consumes the item she purchased with the first promo code.)

Supporting Promo Codes In Your App

To support promotion codes, your app should call the getPurchases() method whenever the app starts or resumes. This method returns a bundle of all current, unconsumed purchases, including purchases the user made by redeeming a promo code. This simplest approach is to call getPurchases() in your activity's {@link android.app.Activity#onResume onResume()} method, since that callback fires when the activity is created, as well as when the activity is unpaused. Calling getPurchases() on startup and resume guarantees that your app will find out about all purchases and redemptions the user may have made while the app wasn't running. Furthermore, if a user makes a purchase while the app is running and your app misses it for any reason, your app will still find out about the purchase the next time the activity resumes and calls getPurchases().

In addition, your app should allow users to redeem promo codes inside the app itself. If your app supports the in-app purchase workflow (described in Making In-app Billing Requests), your app automatically supports in-app redemption of promo codes. When you launch the in-app purchase UI, the user has the option to pay for the purchase with a promo code. Your activity's {@link android.app.Activity#onActivityResult onActivityResult()} method receives a response intent telling the app whether the purchase was completed. However, your app should still call getPurchases() on startup and resume, just in case the purchase and consumption workflow didn't complete. For example, if the user successfully redeems a promo code, and then your app crashes before the item is consumed, your app still gets information about the purchase when the app calls getPurchases() on its next startup.

Your app should also support the scenario where a user redeems a promo code in the Play Store app while the app is running. Your app can find out right away when the user redeems a code by registering a listener for the PURCHASES_UPDATED intent. The Play Store fires this intent whenever a user redeems a promo code.

To listen for the PURCHASES_UPDATED intent, dynamically create a {@link android.content.BroadcastReceiver} object and register it to listen for "com.android.vending.billing.PURCHASES_UPDATED". Register the receiver by putting code like this in your activity's {@link android.app.Activity#onResume onResume()} method:

IntentFilter promoFilter =
    new IntentFilter("com.android.vending.billing.PURCHASES_UPDATED");
registerReceiver(myPromoReceiver, promoFilter);

When the user makes a purchase, the system invokes your broadcast receiver's {@link android.content.BroadcastReceiver#onReceive onReceive()} method. That method should call getPurchases() to see what purchases the user has made.

Your activity's {@link android.app.Activity#onPause onPause()} method should unregister the broadcast receiver, to reduce system overhead when your app isn't running:

unRegisterReceiver(myPromoReceiver);

Note: You should not register this broadcast receiver in the app manifest. Declaring the receiver in the manifest can cause the system to launch the app to handle the intent if the user makes a purchase while the app isn't running. This behavior is not necessary, and may be annoying to the user. Instead, your app should call getPurchases() when the user launches it, to find out about any purchases the user made while the app wasn't running.

Testing In-app Promotions

If your app supports in-app promotions, you should test the following use cases.

User redeems promo code in the app

If the user redeems a promo code within the app's purchase flow, as described in Making In-app Billing Requests, the system invokes your activity's {@link android.app.Activity#onActivityResult onActivityResult()} method to handle the purchase. Verify that {@link android.app.Activity#onActivityResult onActivityResult()} handles the purchase properly, whether the user uses cash or a promo code.

User redeems promo code in the Play Store

If the user redeems a promo code in the Play Store, there are several possible workflows. You should verify each one of these.

App is not installed

If the user redeems a promo code for an app that is not installed on the device, the Play Store prompts the user to install the app. (If the app is installed but not up-to-date, the Play Store prompts the user to update the app.) You should test the following sequence on a device that does not have your app installed.

  1. User redeems a promo code for the app in the Play Store. The Play Store prompts the user to install your app.
  2. User installs and launches your app. Verify that on startup, the app calls getPurchases() and correctly detects the purchase the user made with the promo code.

App is installed, but not running

If the user redeems a promo code for an app that is installed on the device, the Play Store prompts the user to switch to the app. You should test the following sequence on a device that has your app installed but not running:

  1. User redeems a promo code for the app in the Play Store. The Play Store prompts the user to switch to your app.
  2. User launches your app. Verify that on startup, the app calls getPurchases() and correctly detects the purchase the user made with the promo code.

App is installed and running

If the user redeems a promo code for an app that is currently running on the device, the Play Store notifies the app via a PURCHASES_UPDATED intent. You should test the following sequence:

  1. User launches the app. Verify that the app has properly registered itself to receive the PURCHASES_UPDATED intent.
  2. User launches the Play Store app and redeems a promo code for the app. The Play Store fires a PURCHASES_UPDATED intent. Verify that your app's {@link android.content.BroadcastReceiver#onReceive BroadcastReceiver.onReceive()} callback fires to handle the intent.
  3. Your {@link android.content.BroadcastReceiver#onReceive onReceive()} method should respond to the intent by calling getPurchases(). Verify that it calls this method, and that it correctly detects the purchase the user made with the promo code.
  4. User switches back to your app. Verify that the user has the purchased item.