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
Android In-App Billing 失败,提示“您已经有此商品的待处理订单”。
Android In App Billing:无法启动launchPurchaseFlow,因为launchPurchaseFlow 正在进行中