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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 21:48:30