android in app billing 购买验证失败

Posted

技术标签:

【中文标题】android in app billing 购买验证失败【英文标题】:android in app billing purchase verification failed 【发布时间】:2013-11-12 23:08:55 【问题描述】:

我无法在我的 android 应用中实现应用计费。 我收到购买签名验证失败。 在我第一次遇到困难时,它是 base64 密钥,但我检查了很多次,但我仍然收到错误,然后在我查看 Security.java 文件后,我发现我编辑了这个方法以获取一些信息关于出了什么问题:

    public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) 
    if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey) ||
            TextUtils.isEmpty(signature)) 
        if(TextUtils.isEmpty(signedData)) Log.d(TAG, "SIGNED DATA EMPTY");
        if(TextUtils.isEmpty(base64PublicKey)) Log.d(TAG, "KEY IS EMPTY");
        if(TextUtils.isEmpty(signature)) Log.d(TAG, "SIGNATURE IS EMPTY");
        Log.e(TAG, "Purchase verification failed: missing data.");
        return false;
    

    PublicKey key = Security.generatePublicKey(base64PublicKey);
    return Security.verify(key, signedData, signature);

我得到“签名为空”。 即使我按照以下步骤操作: - 使用我的发布密钥签署 apk - 上传草稿 - 使用“adb -d install app.apk”将其安装在设备上

我正在测试真实的购买。 谢谢。

编辑购买流程没问题,打电话queryInventoryAsync时报错

【问题讨论】:

检查我下面的答案,希望它能解决你的问题。 【参考方案1】:

您可以使用测试 SKU 进行测试,as explained here。它们是:

android.test.purchased android.test.canceled android.test.refunded android.test.item_unavailable

即使在测试和调试场景中,这些购买也会成功(至少是 android.test.purchased),而无需取消购买。

在 verifyPurchase 中,我将 return false 更改为:

    Log.e(TAG, "Purchase verification failed: missing data.");
    if (BuildConfig.DEBUG) 
            return true;
    
    return false;           

但您应该注意仅在测试场景中使用它。

如果您有调试版本并且签名数据丢失,这将返回 true。由于 BuildConfig.DEBUG 在生产构建中将是错误的,这应该没问题。但最好是在调试完所有内容后删除此代码。

【讨论】:

我得到了相同的结果,我可以购买该商品,但是 queryInventoryAsinc(listener) 给了我错误 对我来说,这在调试时有效。您还可以在 verifyPurchase 或 IabHelper.handleActivityResult 中放置断点以查看哪里出错了。 @GvS,verifyPurchase() 的旧代码适用于所有人,但是当谷歌开发人员更新代码以在 verifyPurchase() 方法中进行更安全的交易时,他们添加了一些额外的代码验证签名也是如此,但现在他们正试图改进这个错误。根据我目前所听到的。 @Maulik:我喜欢新的 verifyPurchase 更安全。但我不喜欢它阻止我的调试。 Java 优化将从生产中的应用程序中删除if (BuildConfig.Debug)。所以我可以调试并从增加的安全性中获益。 +1 为答案。是的,这也是测试购买的临时好解决方案。【参考方案2】:

用下面的方法替换你的verifyPurchase() 方法。使用下面给出的旧代码,谷歌开发人员正试图在不久的将来解决这个错误,但在他们更新他们的代码之前,你应该更喜欢下面的代码。

 public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) 
              if (signedData == null) 
                Log.e(TAG, "data is null");
                return false;
            

            boolean verified = false;
            if (!TextUtils.isEmpty(signature)) 
                PublicKey key = Security.generatePublicKey(base64PublicKey);
                verified = Security.verify(key, signedData, signature);
                if (!verified) 
                    Log.w(TAG, "signature does not match data.");
                    return false;
                
            
            return true;
        

查看此链接了解更多信息:

In App billing not working after update - Google Store

在您的项目中使用 try 替换 OLD CODE 方法 verifyPurchase() 方法。但这应该只发生在您尝试购买测试产品时。使用此代码后,请让我知道购买的真实产品。

编辑:

为什么会发生,因为我们在使用像“android.test.purchased”这样的虚拟产品时不会得到任何签名。所以在旧代码中它运行良好,因为即使没有给出签名,我们也会返回 true,而对于新代码,我们会返回 false。

有关来自链接 1 和链接 2 的签名数据 null 或空白的更多信息

所以我建议你只替换旧代码方法verifyPurchase() 而不是新代码方法。

我认为新代码可能适用于真实产品,但不适用于虚拟产品。但是我还没有测试过真正的产品。

使用 GvS 的答案进行测试购买它也是新代码的好解决方案。

希望它能解决你的问题。

【讨论】:

@Maulik 谢谢它为我的测试项目服务,但我有一个问题,它是在使用 inAppBilling 应用程序购买书籍等场景中的应用程序吗?请推荐我 我似乎找不到该方法Security.generatePublicKey(base64PublicKey); Security 类是 java.security 的一部分吗?谢谢。 @Chan - 它不是 Java 安全性的一部分,而是 Google 建议用于应用内计费实施的示例应用的一部分,该方法位于 Security.java 文件中。【参考方案3】:

确保您在手机上使用正确的用户登录,例如在开发者控制台中将您手机的 google 帐户添加为测试用户。

http://developer.android.com/google/play/billing/billing_testing.html#billing-testing-static:

在某些情况下,保留的项目可能会返回签名的静态响应,这使您可以在应用程序中测试签名验证。仅当运行应用程序的用户拥有开发者或测试帐户时,保留项目才会返回签名响应。

【讨论】:

【参考方案4】:

设置返回值为真

public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) 
    return true;

测试后撤消更改

【讨论】:

以上是关于android in app billing 购买验证失败的主要内容,如果未能解决你的问题,请参考以下文章

Android In-App Billing:订单取消后购买状态保持“已购买”

您请求的项目不可购买 - android in app billing

In-App Billing v3 - 不检测退款

Android In-App Billing 失败,提示“您已经有此商品的待处理订单”。

Android In App Billing:无法启动launchPurchaseFlow,因为launchPurchaseFlow 正在进行中

google应用内购(in app billing),点击购买无响应