如何验证android计费收据服务器端

Pip*_*aul 3 validation android node.js receipt in-app-billing

我想在android应用程序中对购买收据进行服务器端验证。我正在使用一个node.js后端。

我目前正在尝试使用google-play-purchase-validator节点模块(https://www.npmjs.org/package/google-play-purchase-validator)进行此操作,这似乎是最新的模块做到这一点(执行对Google Purchase API的实时请求)。

在Google开发人员控制台中,我创建了一个Google服务帐户,然后获得了要在该模块中使用的电子邮件和密钥,并且还将此服务帐户与我的应用程序进行了连接,如本文中的使用服务帐户来验证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);
}
Run Code Online (Sandbox Code Playgroud)

私钥来自.pem文件,我可以使用以下命令从google提供的.p12文件生成该文件:

openssl pkcs12 -in downloaded-key-file.p12 -out your-key-file.pem -nodes
Run Code Online (Sandbox Code Playgroud)

google-play-purchase-validator模块基于其他一些模块(google-oauth-jwt,request,crypto)。我尝试调试一下,似乎一切都正确完成了。

知道我哪里错了吗?

保罗

use*_*458 6

刚刚在模块的Readme.md中添加了有关如何获取正确凭据的说明。

https://www.npmjs.org/package/google-play-purchase-validator

或在这里找到它们:

  1. 首先以该帐户的主要管理员身份进入Google Play开发者控制台(此角色是唯一允许执行以下步骤的角色)。
  2. 转到“设置-> API访问权限”以将Google Developer项目链接到该帐户。
  3. 如果您是新手,请选择“创建新项目”。
  4. 您现在将有更多选择。选择“创建服务帐户”。
  5. 点击链接到Google Developer Console和您的项目
  6. 点击“创建新的客户ID”以创建新的客户ID
  7. 忽略将下载到您的计算机上的.p12文件,而是单击“生成新的JSON密钥”。
  8. 这会将JSON文件下载到您的计算机。一秒钟后,我们将回到该文件。
  9. 现在返回Play商店的发布者帐户,然后点击“完成”。您的新生成用户将出现在这里。
  10. 单击“授予访问权限”,然后授予用户读取您的项目的权限。
  11. 现在,使用此模块设置您的Node.JS项目,并提供在json文件中找到的电子邮件地址和私钥作为此模块的选项。

  • 我们做了完全相同的事情,但我们仍然得到“无法签署 JWT,密钥可能无效”。我们输入的私钥如下所示:`-----BEGIN RSA PRIVATE KEY-----....-----END RSA PRIVATE KEY-----`。我们还能做些什么吗?可能是新线路的问题? (4认同)

Sub*_*swa 5

只有在您遵循上述已接受答案的步骤后,此答案才会有用。我正在使用 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.orderId !== requestDto.orderId) {
                    throw new BadRequestException('Invalid orderId');
                }
                return purchaseResponse;
            } catch (e) {
                throw new BadRequestException(e);
            }
Run Code Online (Sandbox Code Playgroud)