【问题标题】:How to validate android billing receipt server side如何验证 android 计费收据服务器端
【发布时间】:2015-01-12 12:08:22
【问题描述】:

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

我目前正在尝试使用 google-play-purchase-validator 节点模块 (https://www.npmjs.org/package/google-play-purchase-validator) 来执行此操作,这似乎是执行此操作的最新模块(执行对 google 购买 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 文件,我可以使用以下命令从 google 提供的 .p12 文件生成:

openssl pkcs12 -in downloaded-key-file.p12 -out your-key-file.pem -nodes

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

知道我可能错在哪里吗?

保罗

【问题讨论】:

  • 这个应用程序只适用于订阅,并且使用过时的 V2 api,有没有人有其他想法来验证 google play 收据?

标签: android node.js validation in-app-billing receipt


【解决方案1】:

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

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

或者在这里找到它们:

  1. 首先以帐户的主要管理员身份进入 google play 开发者控制台(此角色是唯一允许执行以下步骤的角色)。
  2. 转到“设置->API 访问”以将 Google 开发者项目链接到此帐户。
  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-----。还有什么我们可以做的吗?可能是新线路的问题?
【解决方案2】:

只有按照上述已接受答案的步骤进行操作后,此答案才有用。我正在使用 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);
            }

【讨论】:

  • 这么好的答案 - 关于这个主题有很多噪音。这几行代码就是你真正需要的。一个小的改进建议 - Google 已弃用 developerPayload,因此无需再在响应中检查此字段(2021 年 5 月)。 developer.android.com/google/play/billing/developer-payload
  • 感谢您的建议,将更新答案。
猜你喜欢
  • 2012-01-13
  • 2014-05-22
  • 2013-12-26
  • 2013-01-04
  • 2019-09-23
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
相关资源
最近更新 更多