21

我在我的android应用程序的应用程序结算中遇到问题。 我收到购买签名验证失败。 在第一次我强硬这是base64的关键,但我检查了很多次,我仍然得到错误,然后我看了一下Security.java文件后,我发现这个方法,我编辑得到一些有关错误的信息:android在应用程序结算购买验证失败

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

而且我越来越“签名是空的”。 即使我按照以下步骤操作: -Sign我释放钥匙 的APK使用-upload它作为一个草案 -install它的设备上“亚行-d安装app.apk”

我测试与真正的购买。 谢谢。

编辑购买流程是好的,我得到的错误,当我打电话queryInventoryAsync

+1

检查我下面的回答,希望它会解决你的问题。 – Maulik

回答

35

将您的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

使用尝试替换旧代码的方法在你的项目verifyPurchase()方法。但是,只有当您试图购买测试产品时才会发生这种情况。使用此代码后,还请让我知道真正的产品购买情况。

编辑:

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

来自LINK1签名数据空或空白,并链接2

更多信息,所以我建议你只是替换旧代码的方法,而不是verifyPurchase()新代码的方法。

我认为可能是新代码将工作正常的真实产品,但不是在虚拟产品。但是我还没有测试过真正的产品。

利用GVS的回答为购买测试它也为新的代码很好的解决方案。

希望它能解决您的问题。

+0

谢谢!这解决了我的问题 –

+0

@Maulik感谢它为我的目的测试项目,但我有一个问题,它是应用程序在像购买书籍使用inAppBilling应用程序?请建议我 –

+0

我似乎无法找到该方法'Security.generatePublicKey(base64PublicKey);'Security类是java.s的一部分ecurity?谢谢。 – Chan

40

您可以使用测试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在生产版本中将为false,因此应该可以。但更好的是在调试完所有东西后删除这些代码。

+2

我得到了同样的结果,我能够购买该项目,但然后queryInventoryAsinc(监听)给了我错误 – TheRedFox

+0

对我来说,这在调试时工作。您还可以在verifyPurchase或IabHelper.handleActivityResult中放置断点以查看错误出现的位置。 – GvS

+0

@GvS,verifyPurchase()的旧代码可以正常工作,但是当google开发人员更新代码以在verifyPurchase()方法中创建更安全的事务时,他们会放置一些额外的代码来验证签名,但现在他们正在努力改善这个错误。根据我现在听到的情况。 – Maulik

1

确保您使用正确的用户登录了您的手机或在开发者控制台中添加手机的Google帐户作为测试用户。

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

在某些情况下,保留的项目可能会返回签署的静态回覆,它可以让你在你的应用程序中测试签名验证。如果运行应用程序的用户有开发人员或测试帐户,则保留项目只会返回已签名的响应。

0

集返回值true在

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

tesing后撤消更改

相关问题