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

Flutter:如何通过in_app_purchase在登录时检测订阅是否取消

判断Flutter in_app_purchase中用户是否取消订阅的方法

要在用户登录时主动获取订阅状态(包括是否取消),你需要使用queryPastPurchases()方法——这个方法可以主动查询用户所有过往的购买/订阅记录,不需要依赖购买流程中的_listenToPurchaseUpdated回调。

核心步骤:

  • 主动调用历史查询:在用户登录完成后,调用InAppPurchase.instance.queryPastPurchases()获取历史订阅数据。
  • 解析关键字段:从返回的PurchaseDetails列表中,重点关注以下字段判断订阅状态:
    • status:如果值为PurchaseStatus.canceled,说明订阅已被苹果直接取消(比如退款),此时可立即移除专属功能。
    • isAutoRenewing:如果值为false,说明用户取消了自动续费,但当前订阅周期尚未结束——这时候需要计算订阅到期时间,只有到期后再移除功能。
    • transactionDate和subscriptionPeriod:结合这两个字段计算订阅的到期时间,判断是否已经过期。

代码示例:

Future<void> checkUserSubscriptionOnLogin() async {
  // 查询过往购买记录
  final queryResponse = await InAppPurchase.instance.queryPastPurchases();
  
  if (queryResponse.error != null) {
    // 处理查询错误,比如用户未授权应用访问购买记录
    print('查询订阅状态失败: ${queryResponse.error?.message}');
    return;
  }

  // 遍历所有过往购买记录,筛选你的订阅商品
  const targetSubscriptionId = 'your_premium_subscription_id';
  for (final purchase in queryResponse.pastPurchases) {
    if (purchase.productID == targetSubscriptionId) {
      switch (purchase.status) {
        case PurchaseStatus.canceled:
          // 订阅已被取消且立即失效,移除专属功能
          _disablePremiumFeatures();
          break;
        case PurchaseStatus.purchased:
          if (!purchase.isAutoRenewing) {
            // 用户取消了自动续费,计算到期时间
            final transactionDate = purchase.transactionDate;
            final subPeriod = purchase.productDetails?.subscriptionPeriod;
            if (transactionDate != null && subPeriod != null) {
              final expirationDate = _calculateExpiryDate(transactionDate, subPeriod);
              if (DateTime.now().isAfter(expirationDate)) {
                _disablePremiumFeatures();
              } else {
                _enablePremiumFeatures();
              }
            }
          } else {
            // 订阅正常自动续费,保留功能
            _enablePremiumFeatures();
          }
          break;
        default:
          // 其他状态(比如pending),暂时保留功能或提示用户
          break;
      }
    }
  }
}

// 计算订阅到期时间
DateTime _calculateExpiryDate(DateTime transactionDate, SubscriptionPeriod period) {
  switch (period.unit) {
    case SubscriptionPeriodUnit.day:
      return transactionDate.add(Duration(days: period.numberOfUnits));
    case SubscriptionPeriodUnit.week:
      return transactionDate.add(Duration(days: 7 * period.numberOfUnits));
    case SubscriptionPeriodUnit.month:
      // 简化处理,如需更精确可使用date_utils等第三方库
      return transactionDate.add(Duration(days: 30 * period.numberOfUnits));
    case SubscriptionPeriodUnit.year:
      return transactionDate.add(Duration(days: 365 * period.numberOfUnits));
    default:
      return transactionDate;
  }
}

void _enablePremiumFeatures() {
  // 启用订阅专属功能的逻辑
}

void _disablePremiumFeatures() {
  // 移除订阅专属功能的逻辑
}

注意事项:

  1. 权限问题:确保你的APP已经申请了访问购买记录的权限,否则queryPastPurchases()会返回错误。
  2. 状态延迟:苹果的订阅状态更新可能有短时间延迟,建议每次APP启动时都同步一次状态,而不是只在登录时检查。
  3. 自动续费取消的边界:用户取消自动续费后,当前付费周期内仍可使用功能,必须严格按到期时间判断,不能直接移除。

内容的提问来源于stack exchange,提问作者Gina B.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 21:40:22