Android应用程序结算(订单取消后,购买状态保持“已购买”状态)

笛里谁知壮士心,沙头空照征人骨。这篇文章主要讲述Android应用程序结算:订单取消后,购买状态保持“已购买”状态相关的知识,希望能为你提供帮助。
我目前正在测试我的InApp计费机制(使用InApp Billing版本3 API,因此将TrivialDrive示例作为参考)。
我有一个托管项目,即升级到高级版本。
现在,使用我的测试帐户购买该项目是有效的,但是当我之后在Google结帐中取消整个订单时,我的代码仍然告诉我该项目已购买,因此授予高级功能。
以下是我在MainActivity中检查购买的方法。我不会在某处本地保存购买状态,因为据我所知,使用billing 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,这意味着购买,即使我取消订单后一小时。为什么?
答案在等了大约12个小时并尝试了这里建议的所有内容之后,我仍然面临同样的问题。对我来说诀窍是以下adb命令:
adb shell pm clear com.android.vending
另一答案我知道这已经有一年了,但没有提供的答案/提示对我有帮助,所以我想我会添加我的解决方案。
首先,我遇到了同样的问题。即,进行测试购买,取消测试,仍然收到表示有效购买的购买状态。
我忘记的是,我最近将Google Play开发者控制台设置面板上的“许可证测试响应”字段从“RESPOND_NORMALLY”切换为“许可”
将其切换回“RESPOND_NORMALLY”后,已正确返回已取消购买的购买状态。
所以,在尝试等待几天之前,您可能需要检查一下
另一答案步骤1.等待大约10分钟; 直到您看到“已取消的订单”已交付。在你的谷歌钱包。
9月15日上午11:28取消订单已下达。
9月15日上午11:18取消您取消了此订单。原因:客户要求取消。
步骤2.在设备上注销您的测试Google帐户,然后重新登录。
至少那解决了我的问题。
另一答案在具有相同帐户的其他设备上使用该应用程序时也会出现此问题。在设备重新启动之前,即使在数小时后,也不会收到购买的商品。如果再次尝试购买,则谷歌钱包对话框会显示“已拥有商品”。来自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,因为“项目已经拥有”,我会将其报告给我的听众。
另一答案您可以使用的是购买数据的autoRenewing字段。根据documentation:
autoRenewing:表示订阅是否自动续订。如果为true,则订阅处于活动状态,并将在下一个结算日期自动续订。如果为false,则表示用户已取消订阅。
此字段在取消后立即更新。
另一答案如果我看到trivialdrivesample中的参考代码是错误的,这对于应用程序计费的官方参考项目来说是一个耻辱。
如果购买== null,则仅表示从未购买过。要获得您必须致电的真实信息
purchase.getPurchaseState()

根据here
purchaseState订单的购买状态。可能的值为0(已购买),1(已取消),2(已退款)或3(已过期,仅限订阅购买)。
另一答案Google官方文档已经很好地回答了这个问题。在这里复制单词。
当用户取消订阅时,Google Play不会为当前结算周期提供退款。相反,它允许用户访问已取消的订阅,直到当前结算周期结束,此时它终止订阅。例如,如果用户购买了每月订阅并在周期的第15天取消订阅,则Google Play会认为订阅有效,直到第30天结束(或其他日期,具体取决于月份)。
这应该解释一切。 getPurchase()仍会将购买数据返回到当前订阅周期结束。
另一答案我在文档(IAB API v2)中找到了以下部分,但我不确定这是否可以用于IAB API v3。广播可能仍然会被发送。
“...当Google Play收到Google电子钱包的退款通知时,您的应用程序可以收到IN_APP_NOTIFY广播意图。在这种情况下,Google Play会向您的应用程序发送IN_APP_NOTIFY消息。您的应用程序可以处理此消息的方式与处理来自应用程序启动的REQUEST_PURCHASE消息,以便最终您的应用程序收到PURCHASE_STATE_CHANGED消息,其中包含有关已退款项目的信息。退款信息包含在PURCHASE_STATE_CHANGED广播意图附带的JSON字符串中。此外,JSON中的purchaseState字段string设置为2.“
【Android应用程序结算(订单取消后,购买状态保持“已购买”状态)】来自:http://developer.android.com/google/play/billing/v2/api.html#billing-action-notify

    推荐阅读