Flutter Android端in_app_purchases库获取历史购买记录问题
核心问题排查
你的代码存在两个核心错误:
- 未主动调用
InAppPurchase.restorePurchases()触发历史购买记录的推送逻辑,官方明确该方法是历史记录查询的唯一触发入口,不会自动返回数据 - 直接对
purchaseStream调用toList()无效,该流是持续存活的长驻流,只有当流主动关闭时才会聚合返回所有元素,而内购流默认不会主动终止
正确实现方案
实现逻辑
- 先注册
purchaseStream的监听,提前接收后续恢复的购买数据 - 调用
restorePurchases()触发历史记录回传 - 在监听回调中筛选状态为
PurchaseStatus.restored的记录,存入自定义集合中
示例代码
import 'package:in_app_purchase/in_app_purchase.dart'; // 定义存储历史购买记录的集合 List<PurchaseDetails> pastPurchases = []; // 1. 先监听购买流 final StreamSubscription<List<PurchaseDetails>> subscription = InAppPurchase.instance.purchaseStream.listen((List<PurchaseDetails> purchaseDetailsList) async { for (final purchaseDetails in purchaseDetailsList) { // 筛选恢复的历史购买记录 if (purchaseDetails.status == PurchaseStatus.restored) { pastPurchases.add(purchaseDetails); // 恢复的购买也需要调用完成接口,避免iOS端残留订单 if (purchaseDetails.pendingCompletePurchase) { await InAppPurchase.instance.completePurchase(purchaseDetails); } } // 原有实时购买的其他状态(成功、失败、取消等)处理逻辑保留即可 } }); // 2. 主动触发历史购买记录恢复 await InAppPurchase.instance.restorePurchases(); // 此时pastPurchases中即为完整的历史购买记录集合 print(pastPurchases); // 页面销毁/不需要监听时记得取消订阅,避免内存泄漏 // subscription.cancel();
注意事项
- 安卓端调用
restorePurchases()时可传入可选参数applicationUserName,对应你下单时传入的用户标识,可精准匹配对应用户的购买记录 - 确保你测试的账号已经在对应应用商店(App Store/Google Play)完成过真实购买,沙箱环境的测试购买记录也支持恢复
- 重复购买触发的已购提示是应用商店侧的校验逻辑,和你本地代码是否能拿到历史记录无关,属于正常现象
内容的提问来源于stack exchange,提问作者Dani
相关产品推荐
相关产品推荐

