Flutter集成RevenueCat时如何检测用户历史应用内购买记录
问题背景
- 技术栈:基于Flutter开发移动应用,集成RevenueCat实现应用内购买能力,当前已上线订阅试用功能
- 业务规则:受Apple、Google应用商店规则限制,同一个商店账号仅可享受一次订阅试用权益,即使用户在应用内注册全新账号,只要设备登录的是已经领过试用的商店账号,就无法再次领取试用
- 现有问题:
- 应用为每个用户分配独立自定义ID并同步至RevenueCat,但用户注册新账号会生成全新的自定义ID,RevenueCat默认会将新ID识别为无任何订阅记录的新用户,无法识别同个商店账号下的历史购买行为,会错误给这类用户展示试用入口
- 此前尝试使用in_app_purchase插件实现历史购买记录检测未成功,现有公开的相关参考指南大多过时,需要可落地的实现方案
可落地实现方案
方案1:直接使用RevenueCat原生能力查询商店维度历史购买(成本最低,优先推荐)
不需要额外引入其他插件,RevenueCat SDK本身会拉取当前设备登录的商店账号下所有历史购买/权益记录,和你绑定的应用内自定义用户ID无关,正确调用逻辑如下:
SDK初始化完成后,不要在用户注册/登录新账号第一时间就调用
logIn方法绑定你的自定义应用用户ID,先调用Purchases.getCustomerInfo()拉取当前账号的权益信息检查返回的
CustomerInfo对象的三个维度数据判断是否有历史试用/购买记录:- 检查
nonSubscriptionTransactions列表,只要存在对应订阅产品的交易记录,不管交易状态是已取消、已过期还是已退款,都说明该商店账号已经使用过试用资格 - 检查
allPurchasedProductIdentifiers集合,如果包含你的订阅产品ID,直接判定为已享受过试用 - 校验
originalAppUserId字段:RevenueCat会为每个首次在当前商店账号下打开App的用户生成一个绑定商店维度的匿名原始ID,这个ID不会因为后续切换自定义应用用户ID丢失历史关联,如果你之前在同个商店账号下绑定过其他应用ID,这个字段对应的历史记录里也能查到购买信息
- 检查
等校验完历史购买状态、完成UI逻辑判断后,再调用
logIn绑定当前登录的应用自定义用户ID即可,不会影响后续的正常购买流程。注意:不要在SDK初始化后立刻调用
logIn绑定自定义用户ID,这是绝大多数人用RevenueCat查不到跨账号历史记录的核心原因
方案2:in_app_purchase插件正确调用姿势(解决之前调用失败问题)
之前调用插件失败基本都是流程错误,最新稳定版插件已经支持全平台历史购买记录查询,正确步骤:
插件初始化后先调用
isAvailable()方法确认当前设备的商店服务连接正常,服务未连接时查询会直接返回空结果分平台拉取历史记录:
- Android端直接调用
queryPastPurchases()方法,拉取当前Google账号下所有历史交易记录 - iOS端监听
pastPurchases流的返回值,不要主动调用查询方法,iOS端会在服务连接成功后自动推送历史记录
- Android端直接调用
遍历返回的交易列表,只要存在对应订阅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
相关产品推荐
相关产品推荐

