Flutter Android端无法获取已购买的非消耗型IAP商品
解决Android非消耗型内购历史购买记录无法获取的问题
针对你遇到的无法获取历史购买记录的问题,可通过以下几个关键修改和检查来解决:
1. 应用启动时自动触发购买恢复
当前代码仅在点击"Restore purchases"按钮时才会恢复购买记录,导致应用启动时无法自动获取历史购买。修改initStoreInfo方法,在成功初始化商品信息后自动调用恢复购买:
Future<void> initStoreInfo() async { final bool isAvailable = await _inAppPurchase.isAvailable(); if (!isAvailable) { setState(() { _isAvailable = isAvailable; _products = <ProductDetails>[]; _purchases = <PurchaseDetails>[]; _notFoundIds = <String>[]; _purchasePending = false; _loading = false; }); return; } final ProductDetailsResponse productDetailResponse = await _inAppPurchase.queryProductDetails(_kProductIds.toSet()); if (productDetailResponse.error != null) { setState(() { _queryProductError = productDetailResponse.error!.message; _isAvailable = isAvailable; _products = productDetailResponse.productDetails; _purchases = <PurchaseDetails>[]; _notFoundIds = productDetailResponse.notFoundIDs; _purchasePending = false; _loading = false; }); return; } if (productDetailResponse.productDetails.isEmpty) { setState(() { _queryProductError = null; _isAvailable = isAvailable; _products = productDetailResponse.productDetails; _purchases = <PurchaseDetails>[]; _notFoundIds = productDetailResponse.notFoundIDs; _purchasePending = false; _loading = false; }); return; } setState(() { _isAvailable = isAvailable; _products = productDetailResponse.productDetails; _notFoundIds = productDetailResponse.notFoundIDs; _purchasePending = false; _loading = false; }); // 添加这行:应用启动时自动恢复购买记录 await _inAppPurchase.restorePurchases(); }
2. 避免重复添加已恢复的购买记录
恢复购买时,可能会重复返回相同的购买记录,修改deliverProduct方法,确保不会重复添加:
Future<void> deliverProduct(PurchaseDetails purchaseDetails) async { setState(() { // 检查是否已存在该购买记录,避免重复添加 bool exists = _purchases.any((p) => p.productID == purchaseDetails.productID && (p.status == PurchaseStatus.purchased || p.status == PurchaseStatus.restored)); if (!exists) { _purchases.add(purchaseDetails); } _purchasePending = false; }); }
3. 检查Google Play控制台配置
- 确保你的非消耗型商品已发布到测试轨道(封闭/开放/内部测试),未发布的商品无法被测试设备获取。
- 将测试设备使用的Google账号添加到许可测试用户列表中。
- 测试设备需登录该测试账号,且已安装对应测试轨道的应用版本。
4. 验证购买恢复的处理逻辑
当前代码中_listenToPurchaseUpdated方法已正确处理PurchaseStatus.restored状态,但需确保:
- 调用
completePurchase后,购买状态被正确标记为已完成。 _verifyPurchase方法在正式环境中需实现服务器端凭证验证,测试阶段可暂时返回true。
内容的提问来源于stack exchange,提问作者Adel Merioua
相关产品推荐
相关产品推荐

