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

Flutter中如何通过in_app_purchase检测用户手动取消订阅?

Flutter in_app_purchase 订阅取消状态检测问题解决

当前代码的问题原因

  1. queryProductDetails的作用:这个接口仅用于查询应用内商品的配置信息(如价格、名称),和用户的订阅状态完全无关。只要你配置的商品ID存在,无论用户是否订阅、是否取消订阅,它都会返回数据,所以取消订阅后有输出是正常现象。
  2. purchaseStream的触发逻辑:这个流只在用户完成购买、恢复购买、申请退款等主动交易操作时才会推送事件。用户手动在App Store/Google Play后台取消订阅属于平台侧操作,不会主动触发该流的回调,因此无法通过它获知取消事件。

解决方案

1. 定期查询历史订单获取订阅状态

通过 queryPastPurchases 接口查询用户历史购买记录,解析其中的订阅状态字段:

Future<void> checkUserSubscriptionStatus() async {
  // 查询历史购买记录
  final QueryPurchaseDetailsResponse purchaseResponse = 
      await InAppPurchase.instance.queryPastPurchases();
  
  if (purchaseResponse.error != null) {
    // 处理查询错误(如网络问题)
    print("查询订阅状态失败: ${purchaseResponse.error!.message}");
    return;
  }

  // 遍历订单,定位目标订阅商品
  const targetSubscriptionId = "你的订阅商品ID";
  for (final PurchaseDetails purchase in purchaseResponse.pastPurchases) {
    if (purchase.productID != targetSubscriptionId) continue;

    // 判断订阅状态
    if (purchase.subscriptionStatus == SubscriptionStatus.canceled) {
      // 订阅已取消(Android 实时更新,iOS 需等待当前周期结束)
      print("订阅已取消");
      // 更新本地UI或状态
    } else if (!purchase.isAutoRenewing) {
      // iOS 中用户取消自动续费时,订阅仍有效到周期结束,此时isAutoRenewing为false
      print("订阅将在当前周期结束后终止");
    } else if (purchase.expiryDate != null && purchase.expiryDate!.isBefore(DateTime.now())) {
      // 订阅已过期
      print("订阅已过期");
    } else {
      // 订阅处于活跃状态
      print("订阅正常活跃");
    }
  }
}

2. 结合应用前后台切换触发查询

在应用从后台回到前台时自动调用查询方法,确保用户每次打开App都能获取最新状态:

// 在StatefulWidget的initState中注册监听
@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addObserver(this);
}

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  super.didChangeAppLifecycleState(state);
  if (state == AppLifecycleState.resumed) {
    // 应用回到前台时查询订阅状态
    checkUserSubscriptionStatus();
  }
}

@override
void dispose() {
  WidgetsBinding.instance.removeObserver(this);
  super.dispose();
}

3. 平台服务器通知(实时性最优)

若需要实时获知订阅取消事件,需依赖平台的服务器通知能力:

  • iOS:配置App Store Server-to-Server通知,后端接收取消事件后同步给App
  • Android:配置Google Play Real-Time Developer Notifications,后端接收后同步给App
    这种方式需要后端配合,是实时获取状态变化的最优方案。

注意事项

  • iOS 中,用户取消自动续费后,订阅会保持活跃至当前付费周期结束,只有到期后subscriptionStatus才会变为canceled,但isAutoRenewing会立即变为false,可通过此字段提前判断用户是否取消续费。
  • Android 中,用户取消订阅后,subscriptionStatus会立即更新为canceled,同时isAutoRenewing为false。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:42:42