我想在Android应用程序中对购买收据进行服务器端验证。我使用的是node.js后端。
我目前正在尝试使用google-play-purchase-validator节点模块(https://www.npmjs.org/package/google-play-purchase-validator),这似乎是最新的模块(执行实时请求)谷歌购买api)。
在Google开发者控制台中,我创建了一个Google服务帐户,然后获得了要在模块中使用的电子邮件和密钥,我还将此服务帐户与我的应用程序相关联,如本文Use service account to verify Google InAppPurchase中所述。不幸的是,它不起作用。似乎节点模块生成的jwt令牌没有正确签名(我收到以下错误:未能签署JWT,密钥可能无效)。
这里有一些代码:
var Verifier = require('google-play-purchase-validator');
var options = {
email:'myemail@developer.gserviceaccount.com',
key: 'myprivatekey',
};
var verifier = new Verifier(options);
verifier.verify(item.Receipt, function cb(err, response) {
if (err) {
console.log("there was an error validating the receipt");
console.log(err);
}
else{
console.log("sucessfully validated the receipt");
console.log(response);
}
私钥来自.pem文件,我可以使用以下命令从谷歌提供的.p12文件中生成:
openssl pkcs12 -in downloaded-key-file.p12 -out your-key-file.pem -nodes
google-play-purchase-validator模块基于其他一些模块(google-oauth-jwt,request,crypto)。我尝试调试一下,一切似乎都正确完成。
知道我哪里错了吗?
保
答案 0 :(得分:5)
刚刚添加了有关如何获取模块自述文件的正确凭据的说明。
https://www.npmjs.org/package/google-play-purchase-validator
或者在这里找到它们:
答案 1 :(得分:1)
仅当您按照上面接受的答案的步骤进行操作时,此答案才有用。我正在使用googleapis npm软件包来验证耗材购买。
import { google } from 'googleapis';
const auth = new google.auth.GoogleAuth({
credentials: {
client_email: 'email from json file',
private_key:
'private key from json file',
},
scopes: ['https://www.googleapis.com/auth/androidpublisher'],
});
const authClient = await auth.getClient();
google.options({ auth: authClient });
try {
// packageName,productId,token you can get from request sent from android
const purchaseResponse: AndroidPurchaseResponse = await google
.androidpublisher({
version: 'v3',
}).purchases.products.get({
packageName: 'packageName',
productId: 'productId',
token: 'purchaseToken',
});
if (purchaseResponse.data.purchaseState !== 0) {
throw new BadRequestException('Purchase is either Pending or Cancelled!');
}
if (purchaseResponse.data.consumptionState !== 0) {
throw new BadRequestException('Purchase is already consumed!');
}
if (purchaseResponse.data.developerPayload !== requestDto.developerPayload) {
throw new BadRequestException('Invalid developerPayload');
}
if (purchaseResponse.data.orderId !== requestDto.orderId) {
throw new BadRequestException('Invalid orderId');
}
return purchaseResponse;
} catch (e) {
throw new BadRequestException(e);
}