You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Play Billing Library v1.0过期订阅逻辑处理咨询

处理订阅过期的逻辑方案(针对Play Billing Library v1.0)

你现在只在启动页通过queryPurchases检查当前有效的订阅,但订阅过期后这个方法就不会返回对应记录了,得从启动页状态校验和实时订阅状态监听两个维度完善逻辑,具体来说:

1. 启动页完善订阅状态校验

首先,Purchase对象自带getExpirationTime()方法,能拿到订阅的过期时间戳(毫秒级),我们可以用它判断订阅是否在有效期内。另外,订阅过期后queryPurchases不会返回该记录,这时候得通过queryPurchaseHistoryAsync查询历史订阅,确认用户是否曾订阅过但现已过期,从而调整权益状态。

修改后的代码示例:

if (billingResponse == BillingClient.BillingResponse.OK) {
    // 先查询当前有效的订阅
    Purchase.PurchasesResult activeResult = mBillingClient.queryPurchases(BillingClient.SkuType.SUBS);
    if (activeResult.getPurchasesList().size() > 0) {
        Purchase activePurchase = activeResult.getPurchasesList().get(0);
        // 双重保险:避免缓存或异常导致的误判
        long currentTime = System.currentTimeMillis();
        if (activePurchase.getExpirationTime() > currentTime) {
            if (activePurchase.getSku().equals(constant.sku_subscription_weekly)) {
                premium = 2;
            }
        } else {
            // 订阅已过期,重置权益为普通用户状态
            premium = 0; 
        }
    } else {
        // 无有效订阅,查询历史记录确认是否曾订阅过
        mBillingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.SUBS, new PurchaseHistoryResponseListener() {
            @Override
            public void onPurchaseHistoryResponse(int responseCode, List<Purchase> purchasesList) {
                if (responseCode == BillingClient.BillingResponse.OK && purchasesList.size() > 0) {
                    Purchase historyPurchase = purchasesList.get(0);
                    if (historyPurchase.getSku().equals(constant.sku_subscription_weekly)) {
                        long currentTime = System.currentTimeMillis();
                        if (historyPurchase.getExpirationTime() <= currentTime) {
                            // 用户曾订阅但已过期,重置权益
                            premium = 0;
                            // 这里可以同步更新UI,比如隐藏付费功能入口
                        }
                    }
                } else {
                    // 用户从未订阅过,保持普通状态
                    premium = 0;
                }
            }
        });
    }
}

2. 监听实时订阅状态变化

用户的订阅可能在APP运行期间过期(比如自动续费失败、手动取消),光靠启动页检查不够,得注册PurchasesUpdatedListener监听状态变化,及时更新权益:

// 初始化BillingClient时绑定监听
mBillingClient = BillingClient.newBuilder(context).setListener(new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(int responseCode, List<Purchase> purchases) {
        if (responseCode == BillingClient.BillingResponse.OK && purchases != null) {
            // 处理购买/续费成功的情况
            for (Purchase purchase : purchases) {
                if (purchase.getSku().equals(constant.sku_subscription_weekly)) {
                    long currentTime = System.currentTimeMillis();
                    premium = purchase.getExpirationTime() > currentTime ? 2 : 0;
                    // 同步更新UI或本地存储
                }
            }
        } else if (responseCode == BillingClient.BillingResponse.USER_CANCELED) {
            // 用户主动取消订阅,结合历史记录重置权益
            // 这里可以调用queryPurchaseHistoryAsync再次确认状态
        }
        // 其他错误情况根据业务需求处理
    }
}).build();

3. 注意宽限期的特殊处理

部分订阅在支付失败后会进入宽限期,这段时间用户仍能享受权益,直到宽限期结束才彻底过期。getExpirationTime()返回的就是宽限期结束时间,所以咱们的判断逻辑无需额外修改,直接用这个时间和当前时间对比即可。

4. 本地存储状态(可选但推荐)

建议把用户的订阅状态(比如premium值、过期时间)存在SharedPreferences或本地数据库里,APP启动时先读取本地状态,再通过BillingClient校验更新,既提升启动速度,也能避免网络问题导致的状态异常。

内容的提问来源于stack exchange,提问作者Khushi Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:49:25