Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,44 @@ function cancelSubscription(platform, payment, cb) {
});
}

function acknowledgePurchase(platform, payment, cb) {
function syncError(error) {
process.nextTick(function () {
cb(error);
});
}

if (!payment) {
return syncError(new Error('No payment given'));
}

const engine = platforms[platform];

if (!engine) {
return syncError(new Error(`Platform ${platform} not recognized`));
}

if (!engine.acknowledgePurchase) {
return syncError(new Error(`Platform ${platform} does not have acknowledgePurchase method`));
}

engine.acknowledgePurchase(payment, function (error, result) {
if (error) {
return cb(error);
}

cb(null, result);
});
}


exports.verifyPayment = (platform, payment, cb) => {
return (cb ? verifyPayment(platform, payment, cb) : promisify(verifyPayment)(platform, payment));
};

exports.cancelSubscription = (platform, payment, cb) => {
return (cb ? cancelSubscription(platform, payment, cb) : promisify(cancelSubscription)(platform, payment));
};
exports.acknowledgePurchase = (platform, payment, cb) => {
return (cb ? acknowledgePurchase(platform, payment, cb) : promisify(acknowledgePurchase)(platform, payment));
};
69 changes: 69 additions & 0 deletions lib/google/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,72 @@ exports.cancelSubscription = function (payment, cb) {
});
});
};



exports.acknowledgePurchase = function (payment, cb) {
let keyObject;

try {
keyObject = validatePaymentAndParseKeyObject(payment);
} catch (error) {
return process.nextTick(() => {
return cb(error);
});
}

jwt.getToken(
keyObject.client_email,
keyObject.private_key,
apiUrls.publisherScope,
function (error, token) {
if (error) {
return cb(error);
}

const requestUrl = apiUrls.purchasesProductsAcknowledge(
payment.packageName,
payment.productId,
payment.receipt,
token
);

const postData = JSON.stringify({
developerPayload: payment.developerPayload || 'Acknowledged by server'
});

const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`
},
body: postData
};

https.post(
requestUrl,
requestOptions,
function (error, res, resultString) {
if (error) {
return cb(error);
}

if (res.statusCode === 204) {
return cb(null, { message: 'Purchase acknowledged successfully' });
}
if (res.statusCode !== 200) {
return cb(
new Error(
`Received ${res.statusCode} status code with body: ${resultString}`
)
);
}

return cb(null, { message: 'Purchase acknowledged successfully' });
}
);
}
);
};

12 changes: 12 additions & 0 deletions lib/google/urls.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,15 @@ exports.purchasesSubscriptionsCancel = function (packageName, productId, receipt
encodeURIComponent(accessToken) // API access token
);
};

exports.purchasesProductsAcknowledge = function (packageName, productId, receipt, accessToken) {
const urlFormat = 'https://www.googleapis.com/androidpublisher/v3/applications/%s/purchases/products/%s/tokens/%s:acknowledge?access_token=%s';

return util.format(
urlFormat,
encodeURIComponent(packageName), // application package name
encodeURIComponent(productId), // productId
encodeURIComponent(receipt), // purchase token
encodeURIComponent(accessToken) // API access token
);
};