Validating Cordova In App Purchases on iOS and Android Using Node.js
20 Mar 2016After integrating in app purchases to a cordova app, you need to validate the transactions on the server using the purchase receipt.
It is not critical (but still recommended) to validate non-consumable purchases, that unlock a feature for example, because even if someone fakes such a purchase, it will usually affect only their device.
However, it is important to validate consumable purchases, such as credits or coins, because fake transactions can affect other users, and deflate your application's currency.
After making a purchase using the buy() function, you will get the values that you need to send to your server for validation.
- on iOS - you only need to use the
receipt
attribure. - on Android - you need to use the
receipt
attribute, which will be a string containing a json of the purchase information, and the signature attribute.
voltrue2/in-app-purchase is a node.js library that validates purchases with Apple's and Google's APIs.
On both platforms, you can send the receipt for either sandbox or production and the validation will work. However, you need to check which environment the transaction was made on before giving away credits.
iOS Setup
For iOS, the itunes shared secret is only required for subscriptions validation. If you are validating consumable or non-consumable products, you don't need to include it.
The data
parameter that you will pass to the validate
function, has to be a string
of the purchase receipt.
iOS setup example:
var iap = require('in-app-purchase');
var validationType = iap.APPLE;
iap.config({ applePassword: config.itunesSecret });
var data = req.body.receipt;
Android Setup
On Android, the google play public key is required for all validations. You can specify different keys for sandbox and production, or use the production one for both.
The data
parameter that you will pass to the validate
function, has to be an object
containing the receipt (a string with the json of the purchase details as returned from the plugin's
buy
function) and the signature.
Android setup example:
var iap = require('in-app-purchase');
var validationType = iap.GOOGLE;
iap.config({ googlePublicKeyStrSandBox: config.googleKeySandbox, googlePublicKeyStrLive: config.googleKeyLive });
var data = { receipt: req.body.receipt, signature: req.body.signature };
Validation
After the configuration is set up, the validation is the same for both platforms:
iap.setup((err) => {
if (err) {
console.log(err);
} else {
iap.validate(iap.APPLE, data, (err, response) => {
if (err) {
console.log(err);
} else {
if (iap.isValidated(response)) {
var purcahseDataList = iap.getPurchaseData(response);
}
}
});
}
});
purchaseDataList
will be an array of all the transactions. On iOS, a receipt can contain
multiple transactions. On Android, it will always be an array with one item.
Each item in the array will have the following attributes:
-
bundleId (Apple only) - you must compare it to your bundle id to make sure this is a receipt generated by your app.
-
orderId (Android only) - same as bundleId but for Android.
-
productId - you must make sure that this is one of the products you offer, and only give this user credits if the productId is familiar.
-
transactionId
-
purchaseDate
-
quantity
You also must check that the receipt does not already exist in your database. The same receipt can be validated an unlimited number of times and be valid.