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

Flutter集成RevenueCat时如何检测用户历史应用内购买记录

问题背景
  • 技术栈:基于Flutter开发移动应用,集成RevenueCat实现应用内购买能力,当前已上线订阅试用功能
  • 业务规则:受Apple、Google应用商店规则限制,同一个商店账号仅可享受一次订阅试用权益,即使用户在应用内注册全新账号,只要设备登录的是已经领过试用的商店账号,就无法再次领取试用
  • 现有问题:
    • 应用为每个用户分配独立自定义ID并同步至RevenueCat,但用户注册新账号会生成全新的自定义ID,RevenueCat默认会将新ID识别为无任何订阅记录的新用户,无法识别同个商店账号下的历史购买行为,会错误给这类用户展示试用入口
    • 此前尝试使用in_app_purchase插件实现历史购买记录检测未成功,现有公开的相关参考指南大多过时,需要可落地的实现方案
可落地实现方案

方案1:直接使用RevenueCat原生能力查询商店维度历史购买(成本最低,优先推荐)

不需要额外引入其他插件,RevenueCat SDK本身会拉取当前设备登录的商店账号下所有历史购买/权益记录,和你绑定的应用内自定义用户ID无关,正确调用逻辑如下:

  1. SDK初始化完成后,不要在用户注册/登录新账号第一时间就调用logIn方法绑定你的自定义应用用户ID,先调用Purchases.getCustomerInfo()拉取当前账号的权益信息

  2. 检查返回的CustomerInfo对象的三个维度数据判断是否有历史试用/购买记录:

    • 检查nonSubscriptionTransactions列表,只要存在对应订阅产品的交易记录,不管交易状态是已取消、已过期还是已退款,都说明该商店账号已经使用过试用资格
    • 检查allPurchasedProductIdentifiers集合,如果包含你的订阅产品ID,直接判定为已享受过试用
    • 校验originalAppUserId字段:RevenueCat会为每个首次在当前商店账号下打开App的用户生成一个绑定商店维度的匿名原始ID,这个ID不会因为后续切换自定义应用用户ID丢失历史关联,如果你之前在同个商店账号下绑定过其他应用ID,这个字段对应的历史记录里也能查到购买信息
  3. 等校验完历史购买状态、完成UI逻辑判断后,再调用logIn绑定当前登录的应用自定义用户ID即可,不会影响后续的正常购买流程。

    注意:不要在SDK初始化后立刻调用logIn绑定自定义用户ID,这是绝大多数人用RevenueCat查不到跨账号历史记录的核心原因

方案2:in_app_purchase插件正确调用姿势(解决之前调用失败问题)

之前调用插件失败基本都是流程错误,最新稳定版插件已经支持全平台历史购买记录查询,正确步骤:

  1. 插件初始化后先调用isAvailable()方法确认当前设备的商店服务连接正常,服务未连接时查询会直接返回空结果

  2. 分平台拉取历史记录:

    • Android端直接调用queryPastPurchases()方法,拉取当前Google账号下所有历史交易记录
    • iOS端监听pastPurchases流的返回值,不要主动调用查询方法,iOS端会在服务连接成功后自动推送历史记录
  3. 遍历返回的交易列表,只要存在对应订阅SKU的交易记录,不管交易状态是什么,都判定为已享受过试用,直接隐藏试用入口即可。

    基础调用代码示例:

    final InAppPurchase iapInstance = InAppPurchase.instance;
    final bool serviceAvailable = await iapInstance.isAvailable();
    bool hasUsedTrial = false;
    if (serviceAvailable) {
      // Android端查询逻辑
      if (Platform.isAndroid) {
        final QueryPurchaseDetailsResponse res = await iapInstance.queryPastPurchases();
        hasUsedTrial = res.pastPurchases.any(
          (purchase) => purchase.productID == kSubscriptionProductId
        );
      }
      // iOS端监听逻辑
      if (Platform.isIOS) {
        iapInstance.pastPurchases.listen((purchaseList) {
          hasUsedTrial = purchaseList.any(
            (purchase) => purchase.productID == kSubscriptionProductId
          );
        });
      }
    }
    

    注意iOS端需要提前在App Store Connect的订阅配置页开启「跨用户共享购买记录」开关,否则无法拉取同个Apple ID下的历史订阅记录。

方案3:服务端校验兜底(防前端篡改)

如果对安全性要求高,可以加一层服务端校验避免前端逻辑被破解绕过:

  • 客户端在查询到商店侧的交易凭证、交易ID后,上传到自有服务端
  • 服务端分别对接Google Play Developer API、App Store Server API,校验凭证对应的账号是否存在历史订阅/试用记录
  • 服务端将校验结果返回给前端,前端根据结果决定是否展示试用入口。
避坑提示
  • 不要等绑定完自定义应用用户ID再拉取购买记录,会导致商店维度的匿名历史记录被覆盖,出现查询结果不准的问题
  • 不要仅依赖自有用户库存储的购买记录做判断,用户可以随意注册新的应用账号,但商店账号维度的购买记录由平台侧存储,是唯一可信的判断依据
  • 不要参考2023年之前的in_app_purchase相关教程,旧版本插件确实存在Android端历史记录查询不全、iOS端无流返回的问题,升级到最新稳定版即可正常使用,不需要额外申请平台特殊权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:00:57