Search code examples
androidin-app-billing

Play In-app Billing v3 - Should I save purchase tokens?


so I'm writing an android app with a special in-app currency. You can buy this currency in packets of 1, 5, 10 etc through in-app billing. Here is how I implemented it:

  1. Use managed products (When the app starts, I use IabHelper to query for purchased products)

  2. As soon as the purchase completes, consume the purchase

  3. When consumption finishes, send purchase token to the server
  4. Server checks through play API, and then provisions the account with the currency

My question is, what if step 3 fails? If the connection gets cut off or something, the purchase token will never get to my server. In that case, users will have paid for currency but their account won't get it. When my app starts again, and 1a runs, it won't find the purchase and it won't re-consume it either.

Is this reasoning correct? If so, do I need to store purchase tokens on the android side? Then, if something fails, I keep retrying until it works? It seems kind of messy... I was also thinking of making a "My purchases page" where you could see all your purchases, and then click them to redeem it if step 3 failed for some reason.


Solution

  • You should keep purchaseToken on your backend. There are two reasons to do so:

    • block repeated purchases
    • keep track of consumed purchases

    The scenario to consume a purchase should look like this:

    1. Send purchase to your backend
    2. Save purchaseToken
    3. Increase user balance (virtual currency)
    4. Send back infomation about successful operation

    Once you've received successful response from your backend, you should consume the item on Android side. If you've already added the virtual currency on your backend (without consuming the item) you should also return successful response so the item will be consumed without increasing user balance.

    Keep in mind that it's very easy to repeat the same purchase even if it's already been consumed so purchaseToken must be validated every time on your backend. If it already exists in your DB just do not increase the virtual currency.