23

i' having trouble implementing in app billing in my android app. i'm getting a purchase signature verification failed. In a first time i tough it was the base64 key but i checked it many times and i'm still getting the error, then after i took a look at the Security.java file and i found this method which i edited for get some informations about what was wrong:

    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);
}

And i'm getting "signature is empty". Even after i follow the steps below: -Sign the apk with my release key -upload it as a draft -install it on a device with "adb -d install app.apk"

I'm testing with real purchases. Thanks.

Edit The purchase flow is fine, i get the error when i call queryInventoryAsync

4

4 回答 4

41

您可以使用测试 SKU 进行测试,如此处所述。这些是:

  • 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 在生产构建中将是错误的,这应该没问题。但更好的是在调试完所有内容后删除此代码。

于 2013-11-01T21:12:16.293 回答
40

用下面的方法替换你的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;
        }

检查此链接以获取更多信息:

更新后应用内计费不起作用 - Google 商店

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

编辑:

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

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

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

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

或者

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

希望它能解决你的问题。

于 2013-11-06T06:44:25.800 回答
1

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

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

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

于 2014-09-17T16:38:20.640 回答
0

将返回值设置为 true

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

测试后撤消更改

于 2015-01-22T07:26:28.610 回答