8

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

我使用测试帐户购买了我的应用的托管应用内结算项目并退款。我的应用程序按预期收到了退款广播,它在恢复交易时看到该项目已退款,所以到目前为止一切都很好。

我的问题是我无法重新购买该物品来测试其他场景。当我尝试购买该商品时,Google Play 界面出现并显示一条错误消息,提示“您已经拥有该商品”。带有 2 个按钮“确定”和“详细信息”。如果我按详细信息,Google Play 会崩溃,然后我会返回我的应用程序。

有没有人有类似的经历?如果用户之前已退款,是否禁止用户购买应用内商品?

4

5 回答 5

6

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

除了等待几个小时之外,您可能还需要打开“Google Play”应用信息并清除缓存和清除数据。这为我解决了。看来 GP 会在设备上缓存购买信息,并且很少(如果有的话)检查 Google 的服务器以获取退款信息。

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

于 2013-02-21T03:45:09.817 回答
4

我向 Google 询问了这个问题,他们告诉我,如果之前已退款,则无法在 Google Play 上重新购买应用内结算项目。但是当我在大约 24 小时后再次尝试购买时,购买通过了......

所以看起来有可能重新购买,但要经过一段时间的延迟。

于 2012-10-23T02:11:01.970 回答
4

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

对我来说,当用户取消购买,或者我决定给用户退款时,我想要发生的事情是 1)用户收到退款,2)用户无法访问付费功能,3)用户可以选择再次购买该功能。

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

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

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

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

我希望这可以帮助其他人寻找这个问题的答案。

于 2019-05-25T05:20:49.143 回答
2

如果有人需要 android 而不是 kotlin 代码。smitty 写的所有解释:

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

if (purchase.getPurchaseState() != Purchase.PurchaseState.UNSPECIFIED_STATE)
{
     handleConsumablePurchasesAsync(purchasesList);
     return false;
}

比你消费这个项目。smitty1 是天才

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()));
            }
        });
    }
}
于 2020-02-12T13:58:35.537 回答
1

我注意到,通过检查Remove Entitlements退款页面上的字段,您将能够直接重新购买产品,而无需按照接受的答案的建议等待。

退款后删除权利

于 2021-05-21T19:34:03.727 回答