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

Flutter Android端in_app_purchase异常:购买成功却触发错误事件

Android端in_app_purchase购买状态异常排查与解答

针对你遇到的问题——Google Play已确认购买完成,但app收到PurchaseStatus.error且未触发后端验证,以下是具体分析:

已完成的Google Play购买会以PurchaseStatus.error进入purchaseStream吗?

会,触发场景主要有这些:

  • 业务逻辑未捕获异常:如果_handlePurchased内部(比如收据解析、后端请求)抛出未处理的异常,插件会将该购买标记为error状态回传。
  • Play服务通信异常:购买完成后,Play服务向app同步凭证时出现数据损坏、超时,插件无法解析有效信息,会将状态设为error。
  • 插件版本bug:你使用的in_app_purchase_android: 0.4.0+10存在已知的状态同步问题,部分场景下会错误将已完成的购买标记为error。

事件在到达处理函数前丢失的可能原因

  • 订阅状态异常:如果purchaseStream的订阅在购买过程中被意外取消或重建,会导致中间事件丢失。
  • 后台状态干扰:即使你做了生命周期防护,若用户在购买完成时快速从Play商店切回app,插件可能无法及时捕获事件。
  • pending状态未跟踪:购买流程中出现短暂pending状态但未被app记录,后续purchased状态事件可能被插件遗漏。

针对你的代码的关键修复点

  1. 修复case穿透的严重bug
    你的代码中PurchaseStatus.purchased/restored分支没有break,执行完_handlePurchased后会直接进入canceled分支,调用_iap.completePurchase并返回IAPResult.cancelled——这正是你看到错误提示的直接原因!必须添加break:

    switch (purchase.status) {
      case PurchaseStatus.purchased:
      case PurchaseStatus.restored:
        _handlePurchased(purchase);
        break; // 必须添加,阻止穿透到canceled分支
      case PurchaseStatus.canceled:
        _iap.completePurchase(purchase);
        _resolvePending(IAPResult.cancelled);
        break;
      case PurchaseStatus.error:
        _iap.completePurchase(purchase);
        _resolvePending(IAPResult.storeError);
        break;
      case PurchaseStatus.pending:
        break;
    }
    
  2. 排查_pendingProductId不匹配问题
    在_onPurchaseUpdate开头添加日志,打印purchase.productID和_pendingProductId的具体值,确认是否存在购买事件到达时_pendingProductId为null的情况。常见原因是:

    • 发起购买后_pendingProductId未被正确赋值。
    • 页面重建(如配置变更)导致_pendingProductId被重置。
  3. 给_handlePurchased添加异常捕获
    如果_handlePurchased内部抛出异常,会导致后续逻辑中断,甚至被插件标记为error。建议包裹try-catch:

    case PurchaseStatus.purchased:
    case PurchaseStatus.restored:
      try {
        await _handlePurchased(purchase); // 假设是异步方法
        _iap.completePurchase(purchase);
        _resolvePending(IAPResult.success);
      } catch (e) {
        _iap.completePurchase(purchase);
        _resolvePending(IAPResult.storeError);
      }
      break;
    
  4. 调整completePurchase调用时机
    对于已购买的订单,建议在后端验证成功后再调用_iap.completePurchase,确保Play收到确认信号,避免出现“已拥有该商品”的提示。

额外优化建议

  • 升级in_app_purchase_android到最新稳定版,修复已知的状态同步bug。
  • 在app启动时调用_iap.restorePurchases(),自动恢复未确认的购买订单。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 01:33:10