This document describes how to detect and deliver one-time products in your game
after players purchase them with Play Points in the Google Play app.

Once users redeem their Play Points for a one-time product in the Google Play
app, the items should be delivered immediately in your game. The following
displays how a user purchases items with Play Points.

|---|---|---|---|
| 1. Click **Play Points**. | 2. Click the **Use** tab to view items. | 3. Select an item and click **Use Points** to complete the purchase. | 4. Receive the item. |
| ![A screenshot](https://developer.android.com/static/images/guide/playpoints/deliver-step1.png) | ![A screenshot](https://developer.android.com/static/images/guide/playpoints/deliver-step2.png) | ![A screenshot](https://developer.android.com/static/images/guide/playpoints/deliver-step3.png) | ![A screenshot](https://developer.android.com/static/images/guide/playpoints/deliver-step4.png) |

In the example, the game is not running while the product is purchased. Users
can also exchange Play Points for products when the game isn't installed on their
device. Because of this, you must design your game to handle in-app item
delivery from outside of the in-game store.

## Before you get started

Before you detect and deliver a one-time product, you must
[create the product and Play Points promotions](https://developer.android.com/guide/playpoints/create-products).

## Delivery requirements

When you deliver one-time products in your game using a Play Points promotion, you
must follow the requirements in this section.

### Delivery timing

When a player exchanges Play Points for a one-time product, you must deliver the
item immediately without requiring the player to restart the game. In cases
where game content must be completed beforehand, such as completing a tutorial,
the item should be delivered immediately after.

### Delivery message

Once a user returns to your game after purchasing a one-time product outside of
the game, you must display a confirmation that the product was successfully
granted within the game. The message should come in the form of a dialog
or an in-game message. Users shouldn't have to take any additional steps to
receive the item.

Here's the required messaging format:

- A clear message that the item has been received.

- Refer to the item name clearly and refer to "Play Points" to ensure users can
  distinguish it from other content they receive.

- The name of the item must also include the correct denomination of the item if
  there are similar items with multiple denominations.

- The dialog, message, or in-game notification should be visible to the
  user until the user clicks a confirmation such as, **Continue** or **OK**.
  There should not be a cancel button, as this message is only meant to notify
  users of the item they have received in-game. If there is no confirmation
  button, then the message should be visible to users for at least 3 seconds
  before disappearing to ensure users know they have received their item.

Here's an example message:

"Item received! You just got 100 Gems with Play Points. Continue."

Users should see an animation or some visual confirmation displaying the
increase in their balance of in-game currency. If the item is a durable or
consumable in-app item, users should be directed to where the item has been
unlocked or is available within the game.

## Detect items received outside of the game

If your game uses the
[Google Play Billing Library](https://developer.android.com/google/play/billing/billing_overview), make the
following changes in order to detect one-time products that are received outside
of the game.

1. In your game's `[onResume()][onResume]` callback, call the
   `[queryPurchases()][queryPurchases]` method to retrieve a list of
   items, so you can determine which ones are not acknowledged.

2. If your game has a server, we strongly recommend that you
   [verify the purchase from your server](https://developer.android.com/google/play/billing/billing_library_overview#Verify-purchase)
   by using the
   [Subscriptions and In-App Purchases API](https://developers.google.com/android-publisher#subscriptions).

3. If there are owned but unacknowledged items, acknowledge the purchase either
   with `[consumeAsync()][consumeAsync]` for consumable items or with
   `[acknowledgePurchase()][acknowledgePurchase]` for non-consumable
   items.

4. Grant entitlement to the purchased item inside the game.

## Detect items received in split-screen mode

If your game supports
[multi-window mode](https://developer.android.com/guide/topics/ui/multi-window),
it is possible for users to redeem Play Points and receive the item, while
running the Play Store app and your game at the same time. This screenshot
displays an example:

![A screenshot where the Redeem points button is displayed while a game is running.](https://developer.android.com/static/images/guide/playpoints/split-screen.png)

To support this scenario with the Google Play Billing Library, do the following:

1. Google Play calls the `[onPurchasesUpdated()][onPurchasesUpdated]`
   method to notify your game that there is a new pending item.

2. If your game has a server, we strongly recommend that you
   [verify the purchase from your server](https://developer.android.com/google/play/billing/billing_library_overview#Verify-purchase)
   by using the
   [Subscriptions and In-App Purchases API](https://developers.google.com/android-publisher#subscriptions).

3. Acknowledge the purchase either with
   [consumeAsync()](https://developer.android.com/reference/com/android/billingclient/api/BillingClient#consumeasync) for consumable items or with
   [acknowledgePurchase()](https://developer.android.com/reference/com/android/billingclient/api/BillingClient#acknowledgePurchase(com.android.billingclient.api.AcknowledgePurchaseParams,%20com.android.billingclient.api.AcknowledgePurchaseResponseListener)) for non-consumable
   items.

4. Grant entitlement to the purchased item inside the game.

## Display a delivery confirmation

When users redeem Play Points and receive an exchange item, they expect the game
to show an in-game message, or use some kind of notification to let them know
that the game correctly received and processed the item. Here are some delivery
confirmation options:

- Show an in-game dialog.

- Deliver the message to an in-game message box, and clearly state that there
  is a new message in the in-game message box.

- Use an OS notification message.

It is possible for the game to be in any state when the promotional item is
received including not being installed on the device. You must detect
promotional items regardless of the state in which the game is when the item is
received. However, there are some exceptions where it may be acceptable to not
immediately notify the user that the item was received. For example:

- During the game action, where showing a message may distract the
  user. In this case, you must notify the user after the action ends.

- During cutscenes, where showing a message may distract the user. In this case,
  you must notify the user after the cutscene is over.

- During the initial tutorial and user setup parts of the game. We recommend you
  notify new users of the reward immediately after they open the game or during
  initial user set up. However, it is acceptable to wait until the main game
  sequence is available to notify the user.

If your app has multiple characters or accounts that the item could be applied
to, we recommend you prompt the user to select which account receives the
promotional items.

Consider users when deciding when and how to notify them of promotional items.
Any time a user doesn't immediately receive a notification, they may get
confused, stop playing the game, contact user support, or complain about
it on social media.

## Updates for specific game engines

Here are some considerations to make for specific game engines:

- If your game is built with Unity, we recommend that you verify whether the
  IAP implementation you're using already supports Play Points promotions.

- If your game is built with Cocos2d-x or Unreal Engine (C/C++), you will most
  likely need to write the JNI code that calls Java APIs from your C/C++ code.

## Server-side best practices

This section contains server-side best practices to use for Play Points
promotions:

- If you call
  [Purchases.products: get](https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.products/get)
  on your server, verify whether you need to handle Play rewards exchange items
  and other one-time products separately based on the `productId` values.

- If you use
  [Onetimeproducts: list](https://developers.google.com/android-publisher/api-ref/rest/v3/monetization.onetimeproducts/list)
  on your server, verify whether you need to separate Play rewards exchange
  items from other one-time products by `productId` values.

- Review the following best practices to verify whether you need to make
  additional changes:

  - Reference:
    - [Fight fraud and abuse](https://developer.android.com/google/play/billing/security)
    - [Best practices for unique identifiers](https://developer.android.com/training/articles/user-data-ids)
  - Implement server-side signature verification.
  - Ensure that the `purchaseToken` and `orderId` values are unique and have not been used before.

## Troubleshooting

This section contains recommendations for scenarios that can result in customer
inquiries.

### Multiple user accounts

If a user has multiple Google Accounts on their device and they redeem Play
Points on the wrong account, Google cannot transfer the items to the other
accounts. Likewise, your app can't transfer the item by calling the
`getPurchases()` method. In this scenario, consider manually providing the
in-app items to the user using your customer support operations.

### Delayed or missing items

If players experience delayed or missing rewards items, see the
[troubleshooting guide for in-app purchases](https://support.google.com/googleplay/answer/1050566?hl)
in the Google Play help documentation.