Android 安卓应用程序内计费:购买状态保持”;购买;订单取消后

Android 安卓应用程序内计费:购买状态保持”;购买;订单取消后,android,in-app-purchase,in-app-billing,Android,In App Purchase,In App Billing,我目前正在测试我的InApp计费机制(使用InApp计费版本3api,因此以triotivedrive示例为参考) 我有一个托管项目,它是升级到高级版本 现在,使用我的测试帐户购买商品是可行的,但是当我在Google checkout中取消整个订单后,我的代码仍然告诉我该商品是购买的,因此授予了高级功能 以下是我在MainActivity中检查购买的方式。我没有将购买状态保存在本地的某个地方,因为我了解到,使用计费API v3,您可以根据需要查询临时购买 @Override protec

我目前正在测试我的InApp计费机制(使用InApp计费版本3api,因此以triotivedrive示例为参考)

我有一个托管项目,它是升级到高级版本

现在,使用我的测试帐户购买商品是可行的,但是当我在Google checkout中取消整个订单后,我的代码仍然告诉我该商品是购买的,因此授予了高级功能

以下是我在MainActivity中检查购买的方式。我没有将购买状态保存在本地的某个地方,因为我了解到,使用计费API v3,您可以根据需要查询临时购买

@Override
    protected void onStart() {
        // TODO Auto-generated method stub
        super.onStart();

        iabHelper = new IabHelper(this, Helper.getPKey());
        iabHelper.enableDebugLogging(true);

        iabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {

            @Override
            public void onIabSetupFinished(IabResult result) {
                Log.d("IAB", "SETUP FINISHED");

                if(!result.isSuccess())
                {
                    Log.d("IAB", "SETUP NOT OK");
                    return;
                }
                else
                    Log.d("IAB", "SETUP OK");

                iabHelper.queryInventoryAsync(
                    new QueryInventoryFinishedListener() {

                        @Override
                        public void onQueryInventoryFinished(IabResult result, Inventory inv) {
                            Log.d("IAB", "Query inventory finished.");
                            if (result.isFailure()) {
                                Log.d("IAB","Failed to query inventory: " + result);
                                return;
                            }

                            Log.d("IAB", "Query inventory was successful.");

                            // Do we have the premium upgrade?
                            boolean mIsPremium = inv.hasPurchase(Helper.premiumSku);
                            Purchase p = inv.getPurchase(Helper.premiumSku);
                            if(p != null)
                                Log.d("IAB PURCHASE STATE", IabHelper.getResponseDesc(p.getPurchaseState()));
                            else
                                Log.d("IAB PURCHASE STATE", "Purchase is null");

                            Log.d("IAB", "User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM"));


                        }
                    }                       

                );              
            }
        });       
    }

我一直得到getPurchaseState=0,这意味着即使在我取消订单一小时后,它还是被购买了。为什么?

如果我正确地看到示例中的参考代码是错误的,这将是应用内计费的官方参考项目的耻辱

如果purchase==null,则表示从未购买过。要得到真正的信息,你必须打电话

purchase.getPurchaseState()


purchaseState订单的购买状态。可能的值为0(已购买)、1(已取消)、2(已退款)或3(已过期,仅限订阅购买)。

步骤1。等待大约10分钟;直到您看到“取消订单”已交付。在你的谷歌钱包里

9月15日上午11:28取消订单已交付

9月15日上午11:18取消您取消了此订单。原因:客户请求取消

第二步。注销设备上的测试google帐户,然后重新登录


至少这解决了我的问题。

我知道这已经一岁了,但给出的答案/提示对我都没有帮助,所以我想我会添加我的解决方案

首先,我遇到了同样的问题。也就是说,进行了一次测试购买,取消了它,仍然收到一个指示有效购买的购买状态

我忘记的是,我最近将Google Play开发者控制台设置窗格上的“许可测试响应”字段从“正常响应”切换为“许可”

将其切换回“正常响应”后,已取消采购的采购状态正确返回


所以,在你尝试等待几天之前,你可能想检查一下,谷歌官方文档中已经给出了很好的答案。在这里复制单词

当用户取消订阅时,Google Play不会为当前计费周期提供退款。相反,它允许用户访问已取消的订阅,直到当前计费周期结束,此时它将终止订阅。例如,如果用户购买每月订阅并在该周期的第十五天取消,谷歌Poice将考虑订阅有效期至第三十天结束(或其他天,取决于月份)。
这应该可以解释一切
getPurchase()
在当前订阅周期结束之前仍将返回购买数据

我在文档(IAB API v2)中找到了以下部分,但我不确定这是否可以用于IAB API v3。但广播可能仍会被发送

"... 当Google Play从Google Wallet收到退款通知时,您的应用程序可以收到IN_APP_NOTIFY广播意图。在这种情况下,Google Play会向您的应用程序发送一条In_APP_NOTIFY消息。您的应用程序处理此消息的方式与处理来自应用程序启动的请求\u购买消息的响应的方式相同,以便最终您的应用程序收到一条购买\u状态\u更改消息,其中包含有关已退款项目的信息。退款信息包含在JSON字符串中,该字符串与购买\u状态\u更改的广播意图一起出现。此外,JSON字符串中的purchaseState字段设置为2。“


发件人:

在具有相同帐户的另一台设备上使用应用程序时,也会出现此问题。在设备重新启动之前,即使在几个小时之后,也不会收到购买的物品。如果再次尝试购买,谷歌钱包对话框会显示“物品已拥有”。iBaHelper返回的代码仍然是“用户已取消”“因为购买活动的真实响应没有返回,只是写入调试日志

else if (resultCode == Activity.RESULT_CANCELED) {
        logDebug("Purchase canceled - Response: " + getResponseDesc(responseCode));
        result = new IabResult(IABHELPER_USER_CANCELLED, "User canceled.");
        if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
    }
因此,我们不可能对这个谷歌账单对话框做出反应,因为即使对话框上写着“物品已经拥有”,我们总是会得到相同的结果

编辑:

我用这个来修正它:

else if (resultCode == Activity.RESULT_CANCELED) {
        logDebug("Purchase canceled - Response: " + getResponseDesc(responseCode));
        if(responseCode == 7) 
            result = new IabResult(BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED, "Item already owned.");
        else                                                                                             
            result = new IabResult(IABHELPER_USER_CANCELLED, "User canceled.");
        if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
    }

因此,现在如果账单对话框的响应为7,即“物品已拥有”,我会将其报告给我的听众。

在等待了大约12个小时并尝试了此处建议的所有方法后,我仍然面临同样的问题。我的诀窍是以下adb命令:

adb shell pm clear com.android.vending


您可以使用的是采购数据的
autoRenewing
字段。根据报告:

自动续费:指示订阅是否自动续费。如果为true,则订阅处于活动状态,并将在下一个计费日期自动续订如果为false,则表示用户已取消订阅


取消后,此字段会立即更新。

我注意到了完全相同的事情:

使用测试帐户进行应用内购买->使用删除访问权退款->getPurchaseState仍然会返回购买的内容(即使在重新登录和重新启动之后),因此在我的应用中不会删除对高级功能的访问

但当我在一次真正的购买中测试同样的东西时:

客户进行了真正的购买->几周后我退款->客户不再能够访问我的应用程序的高级功能

那么,这是否只是试购的问题?

我没有答案