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

Flutter in_app_purchase: ^3.1.4正式版内购功能异常求助

非消耗型内购正式版失效排查与修复

代码层面核心问题

你的代码在测试环境正常但正式环境失效,核心是几个关键逻辑缺失:

  1. 未处理Pending状态购买
    正式支付流程中,部分场景(如用户身份验证、支付渠道延迟)会让购买处于PurchaseStatus.pending状态,当前代码完全遗漏该分支,导致购买完成后状态无法同步。

  2. 未调用completePurchase
    非消耗型商品购买成功后,必须调用purchase.completePurchase()告知应用商店购买已处理完成,否则商店会在每次APP启动时重复推送该购买记录,甚至阻塞后续购买流程。

  3. 仅依赖本地缓存判断购买状态
    只靠SharedPreferences保存状态,用户清除APP数据或换设备后会丢失购买记录,正式环境必须主动查询历史购买记录验证用户购买状态。

  4. 商品加载无错误反馈
    _loadProducts方法未处理response.error或商品加载为空的情况,正式环境若商品配置错误(如ID不匹配、未激活),无法快速定位问题。

正式发布环境必查项

除代码外,需确认商店后台配置:

  • 商品状态:Google Play/App Store后台商品必须处于已激活状态,测试阶段的草稿/未激活商品正式版无法访问。
  • 签名与ID匹配:Android正式签名的SHA-1需在Google Play后台配置;iOS的Bundle ID、签名证书必须与后台一致。
  • 地区与定价:商品是否在目标用户所在地区上架,正式环境的地区限制会导致商品加载失败。
  • 购买账号:正式版(非TestFlight/内部测试)中,iOS需用沙盒测试账号,Android需用Google Play授权的测试账号,不能用普通真实账号测试(除非真实支付)。

修复后的关键代码示例

1. 完善购买状态处理逻辑

void _handlePurchaseUpdates(List<PurchaseDetails> purchases) {
  for (PurchaseDetails purchase in purchases) {
    switch (purchase.status) {
      case PurchaseStatus.purchased:
        // 必须调用completePurchase告知商店
        if (purchase.pendingCompletePurchase) {
          InAppPurchase.instance.completePurchase(purchase);
        }
        _savePurchaseStatus(true);
        setState(() {
          _isPurchased = true;
        });
        break;
      case PurchaseStatus.pending:
        // 处理支付中状态,比如显示提示
        setState(() {
          // 可添加loading状态或文本提示
        });
        break;
      case PurchaseStatus.error:
        // 打印错误信息方便排查
        print('购买错误: ${purchase.error?.message}');
        break;
      case PurchaseStatus.canceled:
        // 可添加取消购买的提示逻辑
        break;
    }
  }
}

2. 添加历史购买记录查询

在_checkPurchaseStatus中补充查询商店历史购买,替代单一本地缓存依赖:

Future<void> _checkPurchaseStatus() async {
  // 先查本地缓存
  SharedPreferences prefs = await SharedPreferences.getInstance();
  bool? localPurchased = prefs.getBool('isPurchased');

  // 查询商店历史购买记录
  QueryPurchaseDetailsResponse purchaseResponse =
      await InAppPurchase.instance.queryPastPurchases();
  
  for (PurchaseDetails purchase in purchaseResponse.pastPurchases) {
    if (purchase.productID == 'urdubible' && purchase.status == PurchaseStatus.purchased) {
      _savePurchaseStatus(true);
      setState(() {
        _isPurchased = true;
      });
      return;
    }
  }

  // 无历史记录时用本地缓存
  if (localPurchased != null && localPurchased) {
    setState(() {
      _isPurchased = true;
    });
  }
}

3. 完善商品加载的错误处理

Future<void> _loadProducts() async {
  ProductDetailsResponse response =
      await InAppPurchase.instance.queryProductDetails(_productIds);
  
  if (response.error != null) {
    print('商品加载错误: ${response.error?.message}');
    return;
  }

  if (response.productDetails.isEmpty) {
    print('未找到对应商品,请检查商品ID和后台配置');
    return;
  }

  setState(() {
    _products = response.productDetails;
  });
}

内容的提问来源于stack exchange,提问作者joshua

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 03:36:31