Nikita Pustovoi
AndroidHub
Published in
5 min readJun 13, 2018

--

How to check if in-app purchase/subscription is valid? (Node.js)

In this article, I am going to show you how to validate in-app purchases or subscriptions on your Node.js backend.

Updated: Dec 18 2018. Release 2.0

If your app serves some exclusive content to the users, once this exclusive content is requested, you want to make sure that they paid for it.

TL; DL

First of all, you will need to grant permissions to your Node.JS server to check billing information
For that, go to your Developer console and in the settings under “developer account” select “API assess”.

Link a project to your Developer Console, or create one here if you haven’t done it already. Google API Console

Now go to your project in Google API Console and select “Service accounts”.

Then create one service account, you can give any role for this account, but “Project -> Viewer” will be enough.

Once you create the account, don’t forget to save JSON file (we will need it later)

Service Account

Now go back to API access in developer console and find your newly created service account there and click on “Grand permissions.”

To check billing info, you need to check “View financial data.” (the scope you can choose by your self, either for all your apps or just for selected)

All done setting up permissions!

Now go to your Node.JS server and add npm dependency

npm i google-play-billing-validator

Now, in your server js file (in my case is index.js) import the dependency

var Verifier = require('google-play-billing-validator')

Then create config object with the following info:

var options = {
email: "INSERT EMAIL HERE",
key: "INSERT KEY HERE"
}

Find the email and the key in JSON config file you downloaded earlier from Google API Console, remember ? :)

And create a verifier object from it.

var verifier = new Verifier(options);

Now, somewhere in your code where you need to validate a purchase
Perhaps the code where you return exclusive content back to the app, create an object that contains package name of your app, SKU and token that your app sends to node.js

let receipt = {
packageName: "your app package name",
productId: "sku / subscription id",
purchaseToken: "purchase token"
};

For example, you can get them with a GET request like this:

app.get(‘/getPaidContent/:token/:sku’, async (req, res, next) => {
var token = req.params.token;
var sku = req.params.sku;
let receipt = {
packageName: "your app package name",
productId: "sku / subscription id",
purchaseToken: "purchase token"
};

Now it’s time to validate!

In-App Purchase:

let promiseData = verifier.verifyINAPP(receipt)

promiseData.then(function(response) {
// Yay! Purchase is valid
// See response structure below
})
.then(function(response) {
// Here for example you can chain your work if purchase is valid
// eg. add coins to the user profile, etc
// If you are new to promises API
// Awesome docs: https://developers.google.com/web/fundamentals/primers/promises
})
.catch(function(error) {
// Purchase is not valid or API error
// See possible error messages below
})

Subscription:

let promiseData = verifier.verifySub(receipt)

promiseData.then(function(response) {
// Yay! Subscription is valid
// See response structure below
})
.then(function(response) {
// Here for example you can chain your work if subscription is valid
// eg. add coins to the user profile, etc
// If you are new to promises API
// Awesome docs: https://developers.google.com/web/fundamentals/primers/promises
})
.catch(function(error) {
// Subscription is not valid or API error
// See possible error messages below
})

Successful Response (Subscription):

{
"isSuccessful": boolean ,
"errorMessage": null / string,
"payload": {
"kind": "androidpublisher#productPurchase",
"purchaseTimeMillis": long,
"purchaseState": integer,
"consumptionState": integer,
"developerPayload": string,
"orderId": string,
"purchaseType": integer
}
}

Successful Response (Subscription:

{
"isSuccessful": boolean ,
"errorMessage": null / string,
"payload": {
{
"kind": "androidpublisher#subscriptionPurchase",
"startTimeMillis": long,
"expiryTimeMillis": long,
"autoRenewing": boolean,
"priceCurrencyCode": string,
"priceAmountMicros": long,
"countryCode": string,
"developerPayload": string,
"paymentState": integer,
"cancelReason": integer,
"userCancellationTimeMillis": long,
"cancelSurveyResult": {
"cancelSurveyReason": integer,
"userInputCancelReason": string
},
"orderId": string,
"linkedPurchaseToken": string,
"purchaseType": integer,
"profileName": string,
"emailAddress": string,
"givenName": string,
"familyName": string,
"profileId": string
}
}
}

That’s it! Very simple!

Bonus part:

If you use Billing library (code example), token and SKU you can get in the callback in

void onPurchasesUpdated(List<Purchase> purchases);

Where you can save the token and SKU, so later when your app will make a request to your node.js you can pass these values for validation

If you have any suggestions, let me know in the comments!

Also, if you like, don’t forget to clap and like the repo on GitHub!

Link to npmjs: https://www.npmjs.com/package/google-play-billing-validator

Github: https://github.com/Deishelon/google-play-billing-validator

--

--

Nikita Pustovoi
AndroidHub

Android / Kotlin / Python / JS / Flutter❤️