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() { // 移除订阅专属功能的逻辑 }
注意事项:
- 权限问题:确保你的APP已经申请了访问购买记录的权限,否则
queryPastPurchases()会返回错误。 - 状态延迟:苹果的订阅状态更新可能有短时间延迟,建议每次APP启动时都同步一次状态,而不是只在登录时检查。
- 自动续费取消的边界:用户取消自动续费后,当前付费周期内仍可使用功能,必须严格按到期时间判断,不能直接移除。
内容的提问来源于stack exchange,提问作者Gina B.
相关产品推荐
相关产品推荐

