Or How to check if in-app purchase/subscription is valid?
In-depth tutorial on medium: How to check if in-app purchase / subscription is valid?
Install using npm
npm i google-play-billing-validator
var Verifier = require('google-play-billing-validator');
var options = {
"email": 'INSERT SERVICE ACCOUNT EMAIL HERE',
"key": "INSERT YOUR PRIVATE KEY HERE",
};
var verifier = new Verifier(options);
let receipt = {
packageName: "your app package name",
productId: "sku / subscription id",
purchaseToken: "purchase token"
};
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
})
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
})
To acknowledge a purchase or a subscription, simple add developerPayload: <String>
to the receipt
object
eg:
let receipt = {
packageName: "<packageName>",
productId: "<productId>",
purchaseToken: "<purchaseToken>",
developerPayload: "YOUR PAYLOAD"
};
If successful, the result will be
{
isSuccessful:true,
errorMessage:null,
payload:{
code:204,
message:'Acknowledged Purchase Successfully'
}
}
Purchases.products @ Google Documentation
{
"isSuccessful": boolean ,
"errorMessage": null / string,
"payload": {
"kind": "androidpublisher#productPurchase",
"purchaseTimeMillis": long,
"purchaseState": integer,
"consumptionState": integer,
"developerPayload": string,
"orderId": string,
"purchaseType": integer
}
}
Purchases.subscriptions @ Google Documentation
{
"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
}
}
}
{
"isSuccessful": false,
"errorMessage": "The purchase token does not match the product ID."
}
"Wrong productId (sku)" -> "The purchase token does not match the product ID."
"Wrong purchase token" -> "The purchase token was not found."
"Wrong package name" -> "No application was found for the given package name."
"Wrong service email" -> "Not a valid email or user ID."
"Wrong key" -> "Invalid JWT Signature."
"Wrong service account permissions" -> "The current user has insufficient permissions to perform the requested operation."
v1 was a callback based, where v2 is fully promise based. If you are unfamiliar with promises, read this
The migration is very simple:
verifyINAPP()
and/or verifySub()
functionspromise