Flutter InAppPurchase插件更新后无法访问queryPastPurchases获取历史购买
问题原因
你遇到的是Flutter官方in_app_purchase插件3.0.0及以上版本的API破坏性变更问题,旧版本的queryPastPurchases()方法已被官方移除,历史购买记录的检索逻辑做了整体调整。
正确的检索实现方式
1. 通用跨平台实现(推荐)
新版本插件统一使用restorePurchases()方法触发历史购买恢复,所有历史购买数据会通过purchaseStream流推送,不会直接通过方法返回值获取,示例代码如下:
import 'package:flutter/services.dart'; import 'package:in_app_purchase/in_app_purchase.dart'; class InAppPurchaseService { final InAppPurchase _iap = InAppPurchase.instance; late StreamSubscription<List<PurchaseDetails>> _purchaseListener; Future<void> init() async { // 第一步:先监听购买流,历史购买记录会推送至此 _purchaseListener = _iap.purchaseStream.listen((List<PurchaseDetails> purchases) { // 在这里处理所有历史购买记录,包括校验、权益发放、消耗确认等逻辑 for (final purchase in purchases) { _handleSinglePurchase(purchase); } }, onError: (Object error) { // 处理购买/恢复异常 }); } // 触发历史购买恢复 Future<void> fetchPastPurchases() async { await _iap.restorePurchases(); } void _handleSinglePurchase(PurchaseDetails purchase) { // 自定义购买记录处理逻辑 switch (purchase.status) { case PurchaseStatus.purchased: case PurchaseStatus.restored: // 校验购买凭证、发放权益 break; case PurchaseStatus.error: // 处理错误 break; case PurchaseStatus.pending: // 处理待支付订单 break; } } // 页面销毁时取消监听 void dispose() { _purchaseListener.cancel(); } }
2. 安卓平台专属扩展方法
如果你的应用在安卓端需要单独查询未消耗的消耗型商品、或者需要直接获取历史购买集合而不是通过流接收,可以使用安卓平台的扩展接口:
import 'dart:io'; import 'package:in_app_purchase_android/in_app_purchase_android.dart'; // 仅安卓平台调用 if (Platform.isAndroid) { final InAppPurchaseAndroidPlatformAddition androidAddition = _iap.getPlatformAddition<InAppPurchaseAndroidPlatformAddition>(); // 查询不同类型商品的历史购买记录 // 消耗型商品 final QueryPurchaseDetailsResponse consumableRes = await androidAddition.queryPurchases(ProductType.consumable); // 非消耗型商品 final QueryPurchaseDetailsResponse nonConsumableRes = await androidAddition.queryPurchases(ProductType.nonConsumable); // 订阅型商品 final QueryPurchaseDetailsResponse subscriptionRes = await androidAddition.queryPurchases(ProductType.subscription); // 直接从返回值获取购买记录 final List<PurchaseDetails> pastPurchases = consumableRes.pastPurchases; }
注意事项
- 调用
restorePurchases()前必须完成purchaseStream的监听,否则会丢失恢复的历史购买数据 - iOS端调用恢复接口时会唤起Apple ID登录弹窗,建议调用前给用户明确的操作提示
- 所有获取到的购买凭证建议都做服务端校验,避免客户端伪造支付请求
- 消耗型商品在确认发货后必须调用消耗接口,否则会一直存在于历史购买记录中
内容的提问来源于stack exchange,提问作者frank
相关产品推荐
相关产品推荐

