54

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

我有一个托管项目,即升级到高级版本。

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

这是我在 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,这意味着已购买,即使在我取消订单一小时后也是如此。为什么?

4

9 回答 9

19

在等待了大约 12 个小时并尝试了这里建议的所有内容后,我仍然面临同样的问题。对我来说诀窍是以下 adb 命令:

adb shell pm clear com.android.vending

于 2015-10-27T02:36:34.130 回答
8

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

首先,我遇到了同样的问题。即,进行了测试购买,取消了它,仍然收到指示有效购买的购买状态。

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

将其切换回“RESPOND_NORMALLY”后,已取消购买的购买状态已正确返回。

因此,您可能需要在尝试等待几天之前检查一下

于 2014-01-10T20:19:27.927 回答
7

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

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

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

步骤 2. 在设备上注销您的测试 google 帐户,然后重新登录。

至少这解决了我的问题。

于 2013-09-15T20:04:56.457 回答
6

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

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

所以它不可能对这个谷歌计费对话框做出反应,因为我们总是得到相同的结果 IABHELPER_USER_CANCELED,即使对话框说“项目已经拥有”。

编辑:

我用这个修复它:

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 作为“项目已拥有”,我将它报告给我的听众。

于 2014-10-31T20:26:42.767 回答
6

您可以使用的是autoRenewing购买数据的字段。根据文档

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

并且此字段在取消后立即更新。

于 2017-08-23T15:10:13.220 回答
1

如果我没看错,那么 trivialdrivesample 中的参考代码是错误的,这对于应用内计费的官方参考项目来说将是一种耻辱。

如果 purchase == null 它只是意味着它从未被购买过。要获得真实信息,您必须致电

purchase.getPurchaseState()

根据这里

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

于 2013-07-28T10:25:00.257 回答
1

谷歌官方文档中已经很好地回答了。复制这里的话。

当用户取消订阅时,Google Play 不会为当前的结算周期提供退款。相反,它允许用户在当前计费周期结束之前访问已取消的订阅,届时它会终止订阅。例如,如果用户购买了每月订阅并在周期的第 15 天取消它,Google Play 将认为该订阅在第 30 天(或其他日期,具体取决于月份)结束之前有效。

这应该可以解释一切。getPurchase()在当前订阅周期结束之前,仍将返回购买数据。

于 2014-01-10T21:51:22.160 回答
0

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

“...当 Google Play 收到来自 Google Wallet 的退款通知时,您的应用程序可以收到 IN_APP_NOTIFY 广播意图。在这种情况下,Google Play 会向您的应用程序发送 IN_APP_NOTIFY 消息。您的应用程序可以像处理来自的响应一样处理此消息应用程序发起的 REQUEST_PURCHASE 消息,以便您的应用程序最终收到 PURCHASE_STATE_CHANGED 消息,其中包含有关已退款项目的信息。退款信息包含在伴随 PURCHASE_STATE_CHANGED 广播意图的 JSON 字符串中。此外,JSON 中的 purchaseState 字段字符串设置为 2。”

来自:http: //developer.android.com/google/play/billing/v2/api.html#billing-action-notify

于 2014-09-04T08:45:38.827 回答
0

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

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

但是当我用真实的购买测试同样的东西时:

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

那么,这可能只是测试购买的问题吗?

于 2020-12-17T10:30:08.183 回答