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

应用内购买:如何校验已恢复订阅的有效性?

如何判断恢复的订阅是否有效且未被取消?

恢复订阅时返回已取消的记录是正常行为——restorePurchases()会拉取用户所有历史购买记录,包括已取消或过期的订阅,仅靠PurchaseStatus.restored无法判断当前有效性。你可以通过以下方式处理:


1. 利用购买记录的内置字段判断有效性

每个PurchaseDetails对象包含两个关键字段,可直接辅助判断:

  • isAutoRenewing:如果值为true,说明订阅处于活跃状态且会自动续期;如果为false,要么用户主动取消了自动续期,要么订阅已过期。
  • purchaseDate + subscriptionPeriod:结合购买时间和订阅周期,计算出订阅到期时间,和当前时间对比,判断是否仍在有效期内。

2. 解决pendingCompletePurchase始终为true的问题

对所有状态为restored的购买记录,无论是否有效,都调用completePurchase()完成本地流程,确保客户端状态和平台同步。部分已取消的订阅可能因平台状态延迟导致pending状态残留,重复调用通常能解决。

3. 服务器验证(权威方案)

将恢复得到的purchaseToken发送到你的后端服务器,调用对应平台的官方验证API(Google Play Developer API 或 App Store Server API),获取最准确的订阅状态。客户端本地判断仅作辅助,服务器验证才能避免篡改和状态不同步问题。


修改后的代码示例

Future<void> initializeProAccountPurchase(context) async {
    available = await IAPService.checkIAPAvailability();

    if (available) {
      final restoredPurchases = await IAPService.restorePurchases().onError((error, stackTrace) {
          print("error restore");
          print(error.userInfo);
          return [];
        });

      for (var purchase in restoredPurchases) {
        if (purchase.status == PurchaseStatus.restored) {
          // 先完成本地购买流程
          await IAPService.completePurchase(purchase);

          bool isActive = false;
          // 先判断自动续期状态
          if (purchase.isAutoRenewing) {
            isActive = true;
          } else {
            // 计算到期时间判断是否仍在有效期
            final purchaseDate = purchase.purchaseDate;
            final subPeriod = purchase.subscriptionPeriod;
            if (purchaseDate != null && subPeriod != null) {
              final expiryDate = purchaseDate.add(subPeriod.duration);
              isActive = expiryDate.isAfter(DateTime.now());
            }
          }

          if (isActive) {
            // 处理有效订阅逻辑
            await getProAccountDetails({'subs_item_purchase', 'pro_account'});
          } else {
            // 忽略已取消/过期订阅
            print("已取消/过期订阅: ${purchase.productID}");
          }
        }
      }
    }
  }

注意事项

  • subscriptionPeriod和purchaseDate可能为null,需做好非空判断,不同平台的字段返回逻辑有差异。
  • 服务器验证是生产环境的必要步骤,客户端本地判断仅适合快速展示临时状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 21:00:48