Google Play 计费 - sku 为android.test.purchased的签名验证失败

6

编辑:由于仍有人查看此帖子,我想提醒一下,这是高度过时的内容,因为它涉及到应用内购买版本2,而现在已经不再使用。请查看最新(目前是v3)文档,这很简单。

关于这个问题有很多讨论,我认为我理解了问题,但是目前我无法进行实际购买的测试,因为我没有可接受的信用卡,只有一张不被接受的Maestro卡。因此,我请求帮助(不是购买验证,而是验证我的思路是否正确)。

首先,问题来自新的verifyPurchase方法。这个新方法检查签名,这应该没问题。然而,Google没有为测试id(例如android.test.purchased)提供任何签名。这导致以下方法始终失败,并且无论虚假购买是否完成并出现确认对话框,它始终返回false进行验证。这个方法:

public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) {
    //if(BuildConfig.DEBUG) return true;

    if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey) ||
            TextUtils.isEmpty(signature)) {
        Log.e(TAG, "Purchase verification failed: missing data.");
        return false;
    }

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

问题出在TextUtils.isEmpty()的检查上,由于签名为空,代码将返回false。我的临时测试解决方案在代码中被注释掉了。如果我在测试的方法开始处添加if(BuildConfig.DEBUG) return true;,一切正常,用户可以使用高级功能,所以问题确实与签名有关。
另一个问题是,如果我购买了android.test.purchased,我无法查询用户的库存,所以我不能确定,我的检查方法是否有效,用于检查用户是否已购买了高级功能。
我的两个问题是:
如果我从verifyPurchase中删除if(BuildConfig.DEBUG) return true;行,并用我提供的真实SKU的真实ID替换android.test.purchased id,那么我能确定在我的情况下一切都会正常工作吗?重申,添加了调试功能后一切正常。如果您需要看更多的代码,请告诉我!
以下方法检查用户是否已购买高级功能,如果是,则设置相应的首选项,否则,如果出现任何问题,它将保持原样。这个方法正确吗?我在Application类中执行此操作,每次启动应用程序时,以防止篡改。
private void checkPremium()
{
    //get the helper up and running
    final IabHelper helper=new IabHelper(INSTANCE, getBase64Key());
    helper.startSetup(new IabHelper.OnIabSetupFinishedListener()
    {
        @Override
        public void onIabSetupFinished(IabResult result)
        {
            //if the helper is in a correct state, check the inventory
            if(result.isSuccess())
            {
                helper.queryInventoryAsync(new IabHelper.QueryInventoryFinishedListener()
                {
                    @Override
                    public void onQueryInventoryFinished(IabResult result, Inventory inv)
                    {
                        //if the inventory is reachable, check if we got the premium
                        if(result.isSuccess())
                        {
                            setPremium(inv.hasPurchase(ActWidgetSearch.SKU));
                        }
                    }
                });
            }
        }
    });
}

谢谢您提前的支持!

尝试使用以下链接来帮助您进行应用内购买测试:https://dev59.com/wGUq5IYBdhLWcg3wT-yD#22088718 - Girish Patel
2个回答

4
几天前我也面临着和你一样的问题。对于从Google Play下载您的实时应用程序的用户,如果测试ID(“android.test.purchased”)像您所说的那样有效,则他们将能够购买您的应用内购买。 Google Play将其视为“真实购买”,并通过与个人SKU相同的渠道进行处理。请参见下文:
引用: 测试购买(应用内结算沙盒) 一旦获得测试访问权限,这些用户可以侧向加载您的应用程序,并测试您产品的完整商品化、购买和履行流程。测试购买是真实订单,Google Play会像处理其他订单一样进行处理。购买完成后,Google Play会阻止订单进入财务处理,确保用户帐户没有实际费用,并在14天后自动取消已完成的订单。 http://developer.android.com/google/play/billing/billing_testing.html#test-purchases 我现在刚刚测试了我的个人SKU,我可以肯定地说它们正在工作! (我在我的Google Merchant帐户中看到了订单)。所以去吧,赚点钱 :)

顺便说一下,开发者之间...你能给我展示一些如何在Application类中运行我的购买验证的示例或教程链接吗?我认为这是一个我一定要从你那里偷走的想法。干杯!


谢谢回复,确实有效,我的应用内购买已经上线一段时间了。我已经剪切并粘贴了我的解决方案到以下链接:http://pastebin.com/xmCAJGNb。在我的解决方案中,每个方法都是应用程序类的一部分。干杯! - hundeva

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

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接