finished implementation of code to follow documentation. Also made fixes as per pr comments

This commit is contained in:
Almir Kadric
2014-09-19 03:48:50 +00:00
parent d76eb10452
commit 8cfdc83044
7 changed files with 50 additions and 21 deletions

View File

@@ -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

View File

@@ -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 {

View File

@@ -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,
});
});
});
};

View File

@@ -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);

View File

@@ -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
);
};

View File

@@ -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)

View File

@@ -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);
});
});