mirror of
https://github.com/HackPlan/node-iap.git
synced 2026-01-12 22:44:35 +08:00
finished implementation of code to follow documentation. Also made fixes as per pr comments
This commit is contained in:
14
README.md
14
README.md
@@ -110,14 +110,26 @@ MIT
|
||||
|
||||
|
||||
### Google Play References
|
||||
**Code Inspiration**
|
||||
|
||||
* https://bitbucket.org/gooroo175/google-play-purchase-validator/src/d88278c30df0d0dc51b852b7bcab5f40e3a30923/index.js?at=master
|
||||
* https://github.com/machadogj/node-google-bigquery
|
||||
* https://github.com/extrabacon/google-oauth-jwt/blob/master/lib/request-jwt.js
|
||||
|
||||
**API Reference**
|
||||
|
||||
* https://developer.android.com/google/play/billing/gp-purchase-status-api.html
|
||||
* https://developers.google.com/android-publisher/
|
||||
* https://developers.google.com/android-publisher/getting_started
|
||||
* https://developers.google.com/android-publisher/authorization
|
||||
* https://developers.google.com/accounts/docs/OAuth2ServiceAccount
|
||||
* https://developers.google.com/android-publisher/api-ref/purchases/products
|
||||
* https://developers.google.com/android-publisher/api-ref/purchases/products/get
|
||||
* http://developer.android.com/google/play/billing/billing_testing.html
|
||||
* http://developer.android.com/google/play/billing/billing_testing.html
|
||||
* http://stackoverflow.com/questions/24323207/use-service-account-to-verify-google-inapppurchase
|
||||
|
||||
**Receipt Generation**
|
||||
|
||||
* http://developer.android.com/training/in-app-billing/preparing-iab-app.html
|
||||
* http://developer.android.com/tools/publishing/app-signing.html
|
||||
* http://developer.android.com/google/play/billing/api.html#managed
|
||||
@@ -43,11 +43,15 @@ function parseResult(result) {
|
||||
|
||||
|
||||
function verify(environmentUrl, options, cb) {
|
||||
https.post(environmentUrl, options, function (error, resultString) {
|
||||
https.post(environmentUrl, options, function (error, res, resultString) {
|
||||
if (error) {
|
||||
return cb(error);
|
||||
}
|
||||
|
||||
if (res.statusCode !== 200) {
|
||||
return cb(new Error('Received ' + res.statusCode + ' status code with body: ' + responseData));
|
||||
}
|
||||
|
||||
var resultObject;
|
||||
|
||||
try {
|
||||
|
||||
@@ -32,13 +32,29 @@ exports.verifyPayment = function (payment, cb) {
|
||||
requestToken.access_token
|
||||
);
|
||||
|
||||
https.get(requestUrl, null, function (error, responseString) {
|
||||
https.get(requestUrl, null, function (error, res, responseString) {
|
||||
if (error) {
|
||||
return cb(error);
|
||||
}
|
||||
|
||||
console.log('\nResult:', responseString);
|
||||
return cb();
|
||||
if (res.statusCode !== 200) {
|
||||
return cb(new Error('Received ' + res.statusCode + ' status code with body: ' + responseData));
|
||||
}
|
||||
|
||||
var responseObject;
|
||||
try {
|
||||
responseObject = JSON.parse(responseString);
|
||||
assert.equal(responseObject.purchaseState, 0, 'purchaseCancelled');
|
||||
assert.equal(responseObject.consumptionState, 1, 'notConsumed');
|
||||
} catch (e) {
|
||||
return cb(e);
|
||||
}
|
||||
|
||||
return cb(null, {
|
||||
receipt: responseObject,
|
||||
transactionId: payment.receipt,
|
||||
productId: payment.productId,
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -20,11 +20,15 @@ exports.getToken = function (iss, key, scope, cb) {
|
||||
assertion: jwtToken
|
||||
}
|
||||
|
||||
https.post(apiUrls.tokenRequest, { form: formData }, function (error, responseString) {
|
||||
https.post(apiUrls.tokenRequest, { form: formData }, function (error, res, responseString) {
|
||||
if (error) {
|
||||
return cb(error);
|
||||
}
|
||||
|
||||
if (res.statusCode !== 200) {
|
||||
return cb(new Error('Received ' + res.statusCode + ' status code with body: ' + responseData));
|
||||
}
|
||||
|
||||
var responseObject;
|
||||
try {
|
||||
responseObject = JSON.parse(responseString);
|
||||
|
||||
@@ -11,13 +11,12 @@ exports.publisherScope = 'https://www.googleapis.com/auth/androidpublisher';
|
||||
|
||||
// Android Purchases URLs & generators
|
||||
exports.purchasesProductsGet = function (packageName, productId, receipt, accessToken) {
|
||||
var baseUrl = 'https://www.googleapis.com/androidpublisher/v2';
|
||||
var packageUri = 'applications/' + encodeURIComponent(packageName);
|
||||
var productUri = 'purchases/products/' + encodeURIComponent(productId);
|
||||
var receiptUri = 'tokens/' + encodeURIComponent(receipt);
|
||||
var urlFormat = 'https://www.googleapis.com/androidpublisher/v2/applications/%s/purchases/products/%s/tokens/%s?access_token=%s';
|
||||
|
||||
var purchaseUrl = [baseUrl, packageUri, productUri, receiptUri].join('/');
|
||||
var accessToken = 'access_token=' + encodeURIComponent(accessToken);
|
||||
|
||||
return purchaseUrl + '?' + accessToken;
|
||||
return util.format(urlFormat,
|
||||
encodeURIComponent(packageName), // application package name
|
||||
encodeURIComponent(productId), // productId
|
||||
encodeURIComponent(receipt), // purchase token
|
||||
encodeURIComponent(accessToken) // API access token
|
||||
);
|
||||
};
|
||||
@@ -10,14 +10,12 @@ module.exports = function (url, options, cb) {
|
||||
try {
|
||||
if (options.form) {
|
||||
data = formUrlencoded.encode(options.form);
|
||||
delete options.form;
|
||||
options.headers = {
|
||||
'content-type': 'application/x-www-form-urlencoded',
|
||||
'content-length': Buffer.byteLength(data)
|
||||
};
|
||||
} else if (data.json) {
|
||||
data = JSON.stringify(data.json);
|
||||
delete options.json;
|
||||
options.headers = {
|
||||
'content-type': 'application/json',
|
||||
'content-length': Buffer.byteLength(data)
|
||||
|
||||
@@ -29,11 +29,7 @@ module.exports = function (requestUrl, options, data, cb) {
|
||||
});
|
||||
|
||||
res.on('end', function () {
|
||||
if (res.statusCode !== 200) {
|
||||
return cb(new Error('Received ' + res.statusCode + ' status code with body: ' + responseData));
|
||||
}
|
||||
|
||||
cb(null, responseData);
|
||||
cb(null, res, responseData);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user