Search code examples
androidgoogle-playin-app-purchase

Confirmed on server side Android app installations


I want to store in Android app data a token (a random number, e.g. 128 bit long) unique for each install. I also want to deliver this token to the backend after confirmed purchase. That is, the backend should reject hacker's attempts to store the token, if it is not after an app purchase.

In other words, I need to implement app "activation" so, that the activation is possible only after a genuine Google Play purchase.

An explanation why I need this:

  • Suppose I resell a $1 product for $2 in a $10 paid app.
  • The right to use this service by the user appears when he purchases my paid app.
  • If the user can fake app install, then he may obtain 1000 products for $10 and thus I would have $990 loss.
  • Thus I need to store on server side a token generated on confirmed (on the backend side) purchase.

Is this possible with Play Market?


Solution

  • In Flutter (and I believe, in plain Android, too) it can be done this way:

    Every purchase needs to be "acknowledged".

    After verifying the purchase receipt and the delivering the content to the user it is important to call InAppPurchase.completePurchase to tell the underlying store that the purchase has been completed. Calling InAppPurchase.completePurchase will inform the underlying store that the app verified and processed the purchase and the store can proceed to finalize the transaction and bill the end user's payment account.

    Warning: Failure to call InAppPurchase.completePurchase and get a successful response within 3 days of the purchase will result a refund.

    So, the task can be done this way:

    • The purchase is created (on the client app side, by contacting Play Store).
    • The app contacts my server with purchase token (and possibly other info).
    • During the request from the app the server retrieves the purchase by purchases.products.get to verify that the purchase is not forged by a hacker and increases users in-app funds.
    • App, after receiving a successful reply from the server, acknowledges the purchase by InAppPurchase.completePurchase.

    If the app fails to acknowledge, the purchase is refunded in 3 days.