Android Can';在退款后,不要在Google Play上重新购买应用内计费项目

Android Can';在退款后,不要在Google Play上重新购买应用内计费项目,android,in-app-billing,Android,In App Billing,我在我的应用中实现了应用内计费,现在正在测试它对退款的处理 我用一个测试帐户购买了我的应用程序管理的应用程序内计费项目,并将其退款。我的应用程序收到了预期的退款广播,并且在恢复交易时看到该项目已被退款,因此到目前为止一切都很好 我的问题是,我不能重新购买该项目来测试其他场景。 当我试图购买该物品时,Google Play界面出现并显示一条错误消息,上面写着“你已经拥有了该物品”,有两个按钮“OK”和“Details”。 如果我按details,Google Play就会崩溃,我会返回我的应用程序

我在我的应用中实现了应用内计费,现在正在测试它对退款的处理

我用一个测试帐户购买了我的应用程序管理的应用程序内计费项目,并将其退款。我的应用程序收到了预期的退款广播,并且在恢复交易时看到该项目已被退款,因此到目前为止一切都很好

我的问题是,我不能重新购买该项目来测试其他场景。 当我试图购买该物品时,Google Play界面出现并显示一条错误消息,上面写着“你已经拥有了该物品”,有两个按钮“OK”和“Details”。 如果我按details,Google Play就会崩溃,我会返回我的应用程序

有没有人有过类似的经历?
如果用户以前退款过,是否禁止用户购买应用内项目?

我问过谷歌这个问题,他们告诉我,如果以前退款过,就不可能在谷歌Play上重新购买应用内计费项目。 但当我24小时后再次尝试购买时,购买成功了


因此,看起来可以重新购买,但必须经过一段时间的延迟。

我也看到了同样的问题。GP崩溃和一切

除了等待几个小时之外,你可能还想打开“谷歌游戏”应用程序信息,清除缓存和数据。这为我解决了问题。GP似乎将购买信息缓存在设备上,只检查谷歌的服务器,很少(如果有的话)查看退款信息

更新:
您可能还想终止Google Play进程,因为它似乎也将购买信息保存在内存中。

我知道这是一个老问题,但我一直在寻找同一问题的答案,并最终得出了自己的结论。谷歌没有详细说明,但我相信他们希望你根据自己的逻辑决定如何处理取消和退款的购买。要记住的另一点是,耗材和非耗材管理产品之间基本上没有区别。所有托管产品均为耗材

对我来说,当用户取消购买时,或者如果我决定给用户退款,我希望发生的是1)用户收到退款,2)用户无法访问付费功能,3)用户可以选择再次购买该功能(如果他们选择)

我所做的是使用应用内计费API在后端服务器上检查购买的purchaseState。如果返回的purchaseState为1(已取消)或2(已退款),我将在我的应用程序中消费购买。谷歌处理第1项,把钱还给用户。我的应用程序中的逻辑处理2,锁定对付费功能的访问。消费购买手柄3,用户可以选择再次购买该功能

它的基本要点是,当购买被发送到后端服务器进行验证时,我检查购买状态。如果购买状态为1或2,我将向我的应用程序返回相应的代码。当我的应用程序收到指示购买被取消或退款的代码时,我的应用程序将使用该购买

我使用PHP版本的API,因此获取购买状态的简化代码是:

$purchases = $service->purchases_products->get($packageName, $productId, $purchaseToken);

$purchaseState = $purchases->getPurchaseState();

if($purchaseState === 1){
        $serverResponseCode = 3;
    }

    if($purchaseState === 2){
        $serverResponseCode = 4;
    }
…然后在我的应用程序中,我检查服务器响应代码

if(serverResponseCode == 3 || serverResponseCode ==4 ){
     lockFeatures();
     ConsumeParams params = ConsumeParams.newBuilder().setPurchaseToken(purchase.getPurchaseToken()).build();
     billingClient.consumeAsync(params, listener);
}

我希望这能帮助其他人找到这个问题的答案。

以防有人需要android而不是kotlin代码。斯密蒂写下的所有解释:

启动应用程序时,您必须检查queryPurchases并查找退款项目。 就像这样:

if (purchase.getPurchaseState() != Purchase.PurchaseState.UNSPECIFIED_STATE)
{
     handleConsumablePurchasesAsync(purchasesList);
     return false;
}
而不是你消费这个物品。 斯密特是个天才

private void handleConsumablePurchasesAsync(List<Purchase> consumables) {
    Log.d(TAG, "handleConsumablePurchasesAsync");
    for (Purchase purchase : consumables) {
        ConsumeParams params = ConsumeParams.newBuilder()
                .setPurchaseToken(purchase.getPurchaseToken())
                .build();

        billingClient.consumeAsync(params, (billingResult, purchaseToken) -> {
            if (billingResult.getResponseCode() == OK) {
                Log.d(TAG, "Consumed the old purchase that hasn't already been acknowledged");
            } else {
                Log.d(TAG, "Error consume the old purchase that hasn't already been acknowledged -> %s" + String.valueOf(billingResult.getResponseCode()));
            }
        });
    }
}
private void handleConsumablePurchasesAsync(列出耗材){
Log.d(标签“handleConsumablePurchasesAsync”);
用于(采购:耗材){
consumerparams params=consumerparams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
ConsumeAncy(参数,(billingResult,purchaseToken)->{
如果(billingResult.getResponseCode()==OK){
Log.d(标记“消费了尚未确认的旧购买”);
}否则{
Log.d(标记“错误消费尚未确认的旧购买->%s”+String.valueOf(billingResult.getResponseCode());
}
});
}
}

我注意到,通过检查退款页面上的
删除权利
字段,您将能够完全重新购买产品,而无需按照已接受答案的建议等待


只是澄清一下:当您说“它在恢复交易时看到商品已退款”时,您的意思是当您调用InAppBillingService的getPurchases()方法时,返回的捆绑包在其响应\u INAPP\u商品\u列表中不再有SKU,就好像从未购买过商品一样?或者你指的是其他的东西,比如一个肯定的通知(除了IN_APP_NOTIFY广播),表明具体退款已经发生?应用内付费示例应用程序不处理退款方案。你知道一个这样的例子吗?TIA.我的意思是,当我发送恢复请求时,项目不再列在已购买项目列表中。就像一开始就没人买过一样。然而,这是指应用内计费API的第2版。该示例使用API的版本3。