You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flutter应用Google Play内购(IAP)正确设置测试步骤咨询及queryProductDetailsAsync响应码12问题求助

Flutter应用Google Play内购(IAP)正确设置测试步骤咨询及queryProductDetailsAsync响应码12问题求助

看到你遇到的Google Play内购问题,尤其是getSkuDetails() failed响应码12的报错,我之前踩过几乎一模一样的坑,咱们一步步拆解排查,先解决配置问题,再看代码细节。


先搞懂响应码12的本质

Google Play的响应码12本质是SKU查询时的身份验证/配置不匹配,不是代码语法错误,90%的概率是Play Console的配置和本地测试环境没对齐,咱们先从配置入手。


第一步:排查Play Console核心配置(最容易踩坑的点)

1. 应用必须发布到测试轨道,而非仅上传AAB

你提到已经上传了AAB,但如果只是上传到“草稿”或未发布到任何测试轨道,Google Play不会把内购商品和应用关联起来。必须:

  • 进入Play Console → 你的应用 → 发布 → 内部测试/封闭测试轨道
  • 上传AAB后创建版本,提交审核(内部测试审核很快,一般几分钟)
  • 审核通过后发布测试版本,获取测试链接并让你的测试账号点击加入测试计划

2. 内购商品的状态和SKU必须完全正确

  • 进入应用内商品页面,确认bronze/silver/gold都是**“激活”状态**(草稿状态的商品完全无法被查询到)
  • 核对代码里的play_product_id和控制台的SKU:大小写、拼写、空格必须完全一致(比如控制台是bronze_plan,代码里不能写成Bronze_Plan

3. 测试账号和设备的权限必须配置到位

内购测试必须用许可测试账号,不能用普通账号:

  • 进入Play Console → 应用内商品 → 测试标签
  • 点击“添加许可测试人员”,输入你的测试Google账号邮箱
  • 勾选“允许未经授权的购买测试(针对许可测试人员)”(可跳过签名匹配验证,方便debug测试)
  • 测试设备必须登录这个许可测试账号,且退出其他所有Google账号
  • 确保设备上的Google Play Store是最新版本(设置→关于Play Store→检查更新)

4. 应用签名的匹配(debug包测试必备)

如果用flutter run直接安装debug包测试,需要确保debug签名被Google Play识别:

  • 获取本地debug keystore的SHA-1,执行命令:
    # Mac/Linux
    keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
    # Windows
    keytool -list -v -keystore C:\Users\<你的用户名>\.android\debug.keystore -alias androiddebugkey -storepass android -keypass android
    
  • 将获取到的SHA-1添加到Play Console → 你的应用 → 设置 → 应用签名 → 点击“添加上传证书”(若使用Google应用签名)

第二步:代码里的潜在问题优化

1. 必须监听购买流的回调

你当前代码仅调用了buyConsumable,但未监听purchaseStream,这会导致完全收不到购买结果回调(成功/失败/待处理),即使购买流程走通也没有反馈。建议在页面的initState里添加流监听:

StreamSubscription<List<PurchaseDetails>>? _purchaseSubscription;

@override
void initState() {
  super.initState();
  // 初始化内购流监听
  final purchaseStream = InAppPurchase.instance.purchaseStream;
  _purchaseSubscription = purchaseStream.listen((purchaseDetailsList) {
    _handlePurchaseUpdates(purchaseDetailsList);
  }, onError: (err) {
    print('购买流发生错误: $err');
  });
}

void _handlePurchaseUpdates(List<PurchaseDetails> purchaseDetailsList) {
  for (var purchase in purchaseDetailsList) {
    if (purchase.status == PurchaseStatus.pending) {
      print('购买待处理,请等待');
      // 可显示加载弹窗
    } else if (purchase.status == PurchaseStatus.error) {
      print('购买失败: ${purchase.error}');
      eventBus.fire(PurchaseFailed(message: purchase.error?.message ?? '购买失败'));
    } else if (purchase.status == PurchaseStatus.purchased) {
      print('购买成功,开始消耗商品');
      // 消耗型商品必须调用consume才能再次购买
      if (purchase.productID == plan['play_product_id']) {
        InAppPurchase.instance.consumePurchase(purchase);
        eventBus.fire(PurchaseSuccess());
      }
    }
  }
}

@override
void dispose() {
  _purchaseSubscription?.cancel();
  super.dispose();
}

2. 补充AndroidManifest的权限

虽然in_app_purchase包会自动添加billing权限,但debug模式下偶尔会失效,建议手动在android/app/src/main/AndroidManifest.xml里添加:

<uses-permission android:name="com.android.vending.BILLING" />

3. 代码逻辑的小优化

purchaseProduct方法里,建议在queryProductDetails前判断productIds是否为空(防呆处理),同时优化timeout的错误提示:

// ... 其他代码
try {
  print('Getting product data');
  final ProductDetailsResponse response = await InAppPurchase.instance
      .queryProductDetails(productIds)
      .timeout(const Duration(seconds: 30), onTimeout: () {
    print('查询商品详情超时,请检查网络或配置');
    throw TimeoutException('查询商品详情超时');
  });
  // ... 后续逻辑
} on TimeoutException catch (e) {
  print(e.message);
  eventBus.fire(PurchaseFailed(message: '连接商店超时,请检查网络'));
  return 'Failed';
} catch (e) {
  print('查询商品详情发生未知错误: $e');
  eventBus.fire(PurchaseFailed(message: '查询商品信息失败'));
  return 'Failed';
}

正确的测试流程(按顺序执行)

  1. 按上述步骤配置好Play Console的所有选项,确保应用已发布到内部测试轨道、商品已激活、测试账号已添加
  2. 用测试账号点击Play Console生成的内部测试链接,加入测试计划后从Play Store安装应用(不要用flutter run直接装,Play Store安装的包是Google签名的,和控制台完全匹配)
  3. 打开应用尝试购买商品,此时应能正常查询到SKU并发起购买

最后再排查几个容易忽略的点

  • 不要用模拟器测试内购:Google Play模拟器的内购支持极差,必须用物理设备
  • 测试设备必须有稳定外网,能正常访问Google Play服务
  • 若仍报错,尝试用release模式编译安装(flutter run --release),debug模式的签名偶尔会有兼容问题

按照这个流程排查,应该能解决你遇到的响应码12和查询超时问题,如果还有问题,可以补充Play Console的配置截图或更详细的Logcat日志,我再帮你分析。

火山引擎 最新活动