How to Verify Purchase for Android App in Server Side (Google Play in App Billing V3)

How to verify purchase for android app in server side (google play in app billing v3)

It sounds what you're looking for is a way to check if the user has premium features enabled on their account, so this is where I would start;

Ensure there is a flag of some sort on your database indicating if the user has premium features and include that in the API response payload when requesting account info. This flag will be your primary authority for "premium features".

When a user makes an in-app purchase, cache the details (token, order id, and product id) locally on the client (i.e the app) then send it to your API.

Your API should then send the purchaseToken to the Google Play Developer API for validation.

A few things might happen from here:

  1. The receipt is valid, your API responds to the client with a 200 Ok status code
  2. The receipt is invalid, your API responds to the client with a 400 Bad Request status code
  3. Google Play API is down, your API responds with a 502 Bad Gateway status code

In the case of 1. or 2. (2xx or 4xx status codes) your client clears the cache of purchase details because it doesn't need it anymore because the API has indicated that it has been received.

Upon a successful validation (case 1.), you should set the premium flag to true for the user.

In the case of 3. (5xx status code) or a network timeout the client should keep trying until it receives a 2xx or 4xx status code from your API.

Depending on your requirements, you could make it wait a few seconds before sending again or just send the details to your API when ever the app is launched again or comes out of background if the purchase details are present on the app cache.

This approach should take care of network timeouts, servers being unavailable, etc.

There are now a few questions you need to consider:

What should happen immediately after a purchase? Should the app wait until validation is successful before providing premium content or should it tentatively grant access and take it away if the validation fails?

Granting tentative access to premium features smooths the process for a majority of your users, but you will be granting access to a number of fraudulent users too while your API validates the purchaseToken.

To put this in another way: Purchase is valid until proven fraudulent or; fraudulent until proven valid?

In order to identify if the user still has a valid subscription when their subscription period comes up for renewal, you will need to schedule a re-validation on the purchaseToken to run at the expiryTimeMillis that was returned in the result.

If the expiryTimeMillis is in the past, you can set the premium flag to false. If it's in the future, re-schedule it again for the new expiryTimeMillis.

Lastly, to ensure the user has premium access (or not), your app should query your API for the users details on app launch or when it comes out of background.

Server-side verification of Google Play In-app billing version 3 purchase

where do I get the signature from ?

Have a look at official docs,

It says that inside your onActivityResult() method you can get following data as shown in example,

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1001) {
int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");//this is the signature which you want

if (resultCode == RESULT_OK) {
try {
JSONObject jo = new JSONObject(purchaseData);//this is the JSONObject which you have included in Your Question right now
String sku = jo.getString("productId");
String purchaseToken = jo.getString("purchaseToken");
//you need to send sku and purchaseToken to server for verification
}
catch (JSONException e) {
alert("Failed to parse purchase data.");
e.printStackTrace();
}
}
}
}

For verification on server end,
Have a look at official docs

As mentioned earlier, client app will send sku and purchaseToken to server API. Server will have to receive those values and will have to perform check with android publish api to verify purchase:

Server may call following GET request by adding necessary parameters:

https://www.googleapis.com/androidpublisher/v2/applications/packageName/purchases/products/productId/tokens/token

here,

packageName = packageName of the client app

productId = sku received from client app

token = purchaseToken received from client app

It will result into a JSONObject response as mentioned format:

{
"kind": "androidpublisher#productPurchase",
"purchaseTimeMillis": long,
"purchaseState": integer,
"consumptionState": integer,
"developerPayload": string,
"orderId": string,
"purchaseType": integer
}

here, purchaseState = 0 means valid purchase

I hope it will be helpful !!

Server side verification of Google Play in-app billing version 3 purchase (part 2)

I hate to answer my own question, but hey, nobody else did! Me and my colleagues took another look at the problem again this morning. The solution to my problem finally occurred to me after taking another look at how the client side verification works in the TrivialDrive example. Man, did I feel like putting on my "stupid-hat", when I understood what was wrong.

I thought that it was the purchaseToken and the signature that was used to verify the purchase, but that way there was no means of verifying if it was item A or item B that was purchased.

If you want to do server-side verification (or any kind of verification for that matter) before making content available to the buyer it's actually the original JSON data (if you use the IabHelper classes, you get the original JSON from the Purchase class) that you're supposed to use together with the signature and the public key. And since it's the original JSON data you're passing along to your server it also contains all the information about the purchase (such as SKU id etc).

It's also important to set the developer payload to something that uniquely identifies your user (not the device!). In our case each user has an account on the server and I use the unique user id as developer payload.

/Mr.Stupid signing off!

Do I need to verify Android in-app billing server side?

Purchased items are linked to the Google account used during the purchase. You don't need a server to implement ads removal premium purchase.

Once the user purchases the item, IAB keeps track of it and syncs it across all devices the user is logged in. The most important thing is to NOT consume the item once it has been purchased.

Verify In-App Purchases with Firebase Realtime Database

If you have a key that contains characters that are not allowed (such as a .), then I typically encoded that character either with something else (e.g. it is common to replace the . in an email address with a , in RTDB keys), or with a generic URL encoding.



Related Topics



Leave a reply



Submit