【问题标题】:Android in-app billing - How to handle refundsAndroid 应用内结算 - 如何处理退款
【发布时间】:2020-05-11 16:28:40
【问题描述】:

我正在尝试在我的应用中实现应用内结算,除了退款之外,一切都很好。在过去的几天里,我一直在反对这一点,如果用户要求退款,似乎无法从应用程序方面知道。 我希望能够在用户获得退款后撤销对一次性托管产品(删除广告)的访问权限。 我没有使用后端,所以我依赖 Google Play API。

我尝试使用 queryPurchaseHistoryAsync 查询 Google Play API,它会返回用户最近购买的列表。这似乎不起作用,因为在要求退款后购买仍然存在(在写这篇文章之前已经等待了一天)。

这就是我所做的:

  1. 在真机上安装应用
  2. 购买应用内内容
  3. 验证应用是否解锁了内容
  4. 转到我的 Google Play 订单历史记录并为应用内商品申请退款
  5. 10 分钟后,交易被退回(完全没有我作为开发者参与)
  6. 应用仍然提供付费内容
  7. 清理 Play 商店应用数据和缓存
  8. 应用仍然提供付费内容

所以任何用户都可以购买我的应用内产品,然后立即转到他的 Google Play 页面并要求退款? 是我遗漏了一些明显的东西还是这个 API 是一场噩梦?

PurchaseState 枚举是

  public @interface PurchaseState {
    // Purchase with unknown state.
    int UNSPECIFIED_STATE = 0;
    // Purchase is completed.
    int PURCHASED = 1;
    // Purchase is waiting for payment completion.
    int PENDING = 2;
  }

我在这里没有看到任何与退款有关的内容, 在我看来,这似乎是一个非常正常的用例,所以我仍然认为我缺少一些关键信息,我该怎么做?

感谢您的帮助

【问题讨论】:

  • 我自己没有尝试过,但是当我寻找时,我发现了这些资源:stackoverflow.com/questions/42403890/…developers.google.com/android-publisher/voided-purchases(我还没有在 sdk 中找到 api)。但我不确定没有后端服务器是否能很好地工作。
  • 对我来说同样的问题,您找到解决方案了吗?谢谢
  • 是也不是,好消息是它是可能的,坏消息是不必要的复杂的完全谷歌风格。我必须创建一个 Firebase 云函数,将购买令牌传递给该函数以进行验证。该函数调用 Google Play api 来获取购买的实际状态。您可以使用 Firebase 的免费计划来完成所有这些工作。这实际上按预期工作。见medium.com/@msasikanth/…
  • 这里有同样的问题,直到现在还没有解决方案:(

标签: android in-app-billing refund


【解决方案1】:

问题

即使用户进行了退款并实际获得了退款,仍然会记录任何购买。当您(开发者/应用所有者)针对应用内商品发出退款/撤销请求时也是如此。

唯一的区别是购买的“purchaseState”。 Google 的计费库的问题在于,它们将 purchase.getPurchaseState() 调用中的“purchaseState”值屏蔽为 PENDNGPURCHASED 状态。见反编译代码:

public int getPurchaseState() {
    switch(this.zzc.optInt("purchaseState", 1)) {
    case 4:
        return 2; // PENDING
    default:
        return 1; // PURCHASED
    }
}

当您的应用内商品处于退款状态时,它的状态是 UNSPECIFIED_STATE,如上面的代码中一样被屏蔽为 PURCHASED。

简单的解决方案

要克服这个问题,只需忽略库的 purchase.getPurchaseState() 方法,而是使用您自己的未屏蔽自定义:

int getUnmaskedPurchaseState(Purchase purchase) {
    int purchaseState = purchase.getPurchaseState();
    try {
        purchaseState = new JSONObject(purchase.getOriginalJson()).optInt("purchaseState", 0);
    } catch (JSONException e) {
        e.printStackTrace();
    }

    return purchaseState;
}

硬解

Google 似乎只是在掩饰下推动您执行此解决方案。使用 Voided Purchases API 提供与用户已作废的购买相关的订单列表。 根据他们的文档...

可以通过以下方式取消购买:

  • 用户请求为其订单退款。用户取消订单。
  • 订单被退回。
  • 开发商取消或退款订单。注意:只有撤销的订单才会显示在 Voided Purchases API 中。
  • 如果开发者在未设置撤销选项的情况下退款,订单将不会显示在 API 中。
  • Google 取消订单或退款。

但是,此解决方案目前不能作为 Java android 库提供,您必须改为发出服务器请求,并使用 Google Play 开发人员 API。

【讨论】:

  • 我最终使用的和你提到的无效购买api类似
  • 不记得为什么了,但是有些关于无效购买的东西不太奏效。但是唯一的区别是我使用购买令牌查询特定的购买。我可以确认这行得通。
  • 为什么会变成这样
  • 部分回答我自己的问题;似乎当购买处于这种被退款但仍显示为已购买的奇怪状态时;用户无法再次购买。启动计费流程会导致“已拥有”。也许这是购买测试卡的异常情况?
  • @rosghub:您找到“用户无法再次购买”问题的答案了吗?我的意思是,我可以通过检查 purchaseState 是否为 0 来处理退款。但是用户将永远无法再次购买该产品...
猜你喜欢
  • 1970-01-01
  • 2018-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-14
  • 1970-01-01
  • 2020-01-06
  • 2019-08-02
相关资源
最近更新 更多