©Nobuyori Takahashi < voltrue2@yahoo.com >
A node.js module for in-app purchase (in-app billing) and subscription for Apple, Google Play, Amazon Store, Roku, and Windows.
It supports Unity receipt also: Unity Documentation
NOTE Unity receipt supports the following: Apple, Google Play, and Amazon.
What is new
As of version 1.10.0
, The module lets you validate Google's receipts using Google Service Account also!
Thank you for the input maxs15
Required node.js version
0.12.0 >=
Online Demo and Documention
Online Demo
How to install
npm install in-app-purchase
How to use
The module supports both Promise and callbacks.
var iap = require('in-app-purchase');
iap.config({
requestDefaults: { },
amazonAPIVersion: 2,
secret: 'abcdefghijklmnoporstuvwxyz',
appleExcludeOldTransactions: true,
applePassword: 'abcdefg...',
googleServiceAccount: {
clientEmail: '<client email from Google API service account JSON key file>',
privateKey: '<private key string from Google API service account JSON key file>'
},
googlePublicKeyPath: 'path/to/public/key/directory/',
googlePublicKeyStrSandbox: 'publicKeySandboxString',
googlePublicKeyStrLive: 'publicKeyLiveString',
googleAccToken: 'abcdef...',
googleRefToken: 'dddd...',
googleClientID: 'aaaa',
googleClientSecret: 'bbbb',
rokuApiKey: 'aaaa...',
facebookAppId: '112233445566778',
facebookAppSecret: 'cafebabedeadbeefabcdef0123456789',
test: true,
verbose: true
});
iap.setup()
.then(() => {
iap.validate(receipt).then(onSuccess).catch(onError);
})
.catch((error) => {
});
function onSuccess(validatedData) {
var options = {
ignoreCanceled: true,
ignoreExpired: true
};
var purchaseData = iap.getPurchaseData(validatedData, options);
}
function onError(error) {
}
Receipt data format
Apple
An Apple's receipt is a base64 encoded string.
Google Play
A Google Play's receipt consists of two components.
The module requires the above two compoents to be as a JSON object.
{
"data": {Signed Data JSON},
"signature": "Base 64 encoded signature string"
}
data
property in the receipt object can be either an object or a stringified JSON string.
Google Play Using Google Service Account
If you are using Google service account instead of OAuth for Google, the receipt should look like:
The API used is v3.
{
packageName: 'The packge name of the item purchased',
productId: 'The product ID of the item purchased',
purchaseToken: 'PurchaseToken of the receipt from Google',
subscription: true/false // if the receipt is a subscription, then true
}
Google Play Using Google Service Account (with Unity receipt)
If you are using Google service account with unity receipt, you need to add a 'Subscription' field to your unity receipt.
The receipt should look like:
{
Store: 'The name of the store in use, such as GooglePlay or AppleAppStore',
TransactionID: 'This transaction's unique identifier, provided by the store',
Payload: 'Varies by platform, see [Unity Receipt Documentation](https://docs.unity3d.com/Manual/UnityIAPPurchaseReceipts.html)',
Subscription: true/false // if the receipt is a subscription, then true
}
Amazon
An Amazon's receipt contains the following:
The module requires the above two components to be as a JSON object or a string
{
"userId": "User ID",
"receiptId": "Receipt ID"
}
Roku
A Roku's receipt is a transaction ID string.
Windows
A Windows' receipt is an XML string.
Facebook (Payments Lite)
A Facebook's receipt is signed_request string of payment response.
Validate Receipts From Multiple Applications
You may feed different Google public key or Apple password etc to validate receipts of different applications with the same code:
Windows is NOT Supported
Google Public Key
iap.config(configObject);
iap.setup()
.then(() => {
iap.validateOnce(receipt, pubKeyString).then(onSuccess).catch(onError);
})
.catch((error) => {
});
Google Subscription
iap.config(configObject);
iap.setup()
.then(() => {
var credentials = {
clientId: 'xxxx',
clientSecret: 'yyyy',
refreshToken: 'zzzz'
};
iap.validateOnce(receipt, credentials).then(onSuccess).catch(onError);
})
Apple Subscription
iap.config(configObject);
iap.setup()
.then(() => {
iap.validateOnce(receipt, appleSecretString).then(onSuccess).catch(onError);
})
.catch((error) => {
});
Amazon
iap.config(configObject);
iap.setup()
.then(() => {
iap.validateOnce(receipt, amazonSecretString).then(onSuccess).catch(onError);
})
.catch((error) => {
});
Roku
iap.config(configObject);
iap.setup()
.then(() => {
iap.validateOnce(receipt, rokuApiKeyString).then(onSuccess).catch(onError);
})
.catch((error) => {
});
Facebook (Payments Lite)
iap.config(configObject);
iap.setup()
.then(() => {
iap.validateOnce(receipt, appAccessToken).then(onSuccess).catch(onError);
})
.catch((error) => {
});
Helper Methods
Array<[object]> getPurchaseData([object] response, [object] options)
Returns an Array of objects that to be used by isExpired
and isCanceled
.
[bool] options.ignoreCanceled
If true
, the returned purchaseData excludes canceled item(s).
[bool] options.ignoreExpired
If true
, the returned purchaseData excludes expired item(s).
[bool] isValidated([object] response)
Returns a boolean true
if the given response of a receipt validation is a valid.
iap.validate(receipt)
.then((response) => {
if (iap.isValidated(response)) {
}
})
.catch((error) => {
});
[bool] isCanceled([object] purchaseData)
Returns a boolean true
if a canceled receipt is validated.
iap.validate(receipt)
.then((response) => {
var purchaseData = iap.getPurchaseData(response);
if (iap.isCanceled(purchaseData[0])) {
}
})
.catch((error) => {
});
[bool] isExpired(object] purchaseData)
Returns a boolean true
if a canceled receipt is validated.
NOTE This is subscription only.
iap.validate(receipt)
.then((response) => {
var purchaseData = iap.getPurchaseData(response);
if (iap.isExpired(purchaseData[0])) {
}
})
.catch((error) => {
});
[void] setAmazonValidationHost([string] host)
Allows you to set custom validation host name for tests.
[void] resetAmazonValidationHost()
Resets to Amazon's validation host name.
Google Play Public Key With An Environment Variable
You may not want to keep the public key files on your server(s).
The module also supports environment variables for this.
Instead of using googlePublicKeyPath: 'path/to...'
in your configurations, you the following:
export=GOOGLE_IAB_PUBLICKEY_LIVE=PublicKeyHerePlz
export=GOOGLE_IAB_PUBLICKEY_SANDBOX=PublicKeyHerePlz
Google In-app-Billing Set Up
To set up your server-side Android in-app-billing correctly, you must provide the public key string as a file from your Developer Console account.
Reference: Implementing In-app Billing
Once you copy the public key string from the Developer Console account for your application, you simply need to copy and paste it to a file and name it iap-live
as shown in the example above.
NOTE: The public key string you copy from the Developer Console account is actually a base64 string. You do NOT have to convert this to anything yourself. The module converts it to the public key automatically for you.
Google Play Store API
To check expiration date or auto renewal status of an Android subscription, you should first setup the access to the Google Play Store API. You should follow these steps:
Part 1 - Get ClientID and ClientSecret
- Go to https://play.google.com/apps/publish/
- Click on
Settings
- Click on
API Access
- There should be a linked project already, if not, create one. If you have it, click it.
- Under Mobile API's, make sure "Google Play Developer API is enabled".
- Go back, on the left click on
Credentials
- Click
Create Credentials
button - Choose
OAuth Client ID
- Choose
Web Application
Part 2 - Get Access and Refresh Tokens
- Go to: https://developers.google.com/oauthplayground
- On the right, hit the gear/settings.
- Check the box:
Use your own OAuth credentials
- Enter in clientID and clientSecret
- Close
- On the left, find "Google Play Developer API v3"
- Hit Authorize Api's button
- Save
Authorization Code
- This is your: googleAccToken
- Hit
Exchange Authorization code for token
- Grab:
Refresh Token
- This is your: googleRefToken
Now you are able to query for Android subscription status!
Amazon App Store Reference
https://developer.amazon.com/docs/in-app-purchasing/iap-rvs-for-android-apps.html
Windows Signed XML
in-app-purchase module supports the following algorithms:
Canonicalization and Transformation Algorithms
Hashing Algorithms
Facebook Order Fulfillment and Signed Request Parsing
HTTP Request Configurations
The module supports the same configurations as [npm request module] (https://www.npmjs.com/package/request#requestoptions-callback)