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

如何解决Google Play非消耗型内购v5的账单交易失败错误

非消耗型内购报错排查:"Something went wrong - Your transaction can't be completed"

能显示商品价格说明BillingClient连接正常、产品ID匹配,购买失败的问题大概率出在测试配置或代码细节上,以下是具体排查点:

一、Google Play控制台配置检查

  • 测试账号权限:确认测试账号已添加到「许可测试」列表,且账号已接受Google Play发送的测试邀请邮件,状态为「已授权」。测试设备必须仅登录该授权账号,不能同时登录其他非测试账号。
  • 应用发布状态:应用必须上传到「内部测试/封闭测试/开放测试」轨道并完成发布(状态显示「已发布」,而非草稿),你使用的测试链接必须对应已发布的测试轨道。
  • 产品配置:
    • 产品ID必须和代码中PRODUCT_PREMIUM = "lifetime"完全一致(大小写敏感)
    • 产品状态必须是「激活」,不能是草稿或未激活状态

二、代码修复建议

1. 修复restorePurchases()方法的错误

当前方法重新创建了BillingClient实例,会覆盖全局连接,导致状态异常。建议复用已初始化的全局billingClient:

void restorePurchases() {
    if (billingClient.isReady()) {
        billingClient.queryPurchasesAsync(
                QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.INAPP).build(),
                (billingResult1, list) -> {
                    if (billingResult1.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                        boolean isRestored = false;
                        for (Purchase purchase : list) {
                            if (purchase.getProducts().contains(PRODUCT_PREMIUM)) {
                                tv_status.setText("Premium Restored");
                                Log.d("TAG", "Product " + PRODUCT_PREMIUM + " restored");
                                isRestored = true;
                                // 处理未确认的购买
                                if (!purchase.isAcknowledged()) {
                                    handlePurchase(purchase);
                                }
                            }
                        }
                        if (!isRestored) {
                            tv_status.setText("No purchases to restore");
                        }
                    } else {
                        Log.e("TAG", "Restore failed: " + billingResult1.getDebugMessage());
                    }
                });
    } else {
        // 客户端未就绪时重新建立连接
        establishConnection();
        // 可在连接成功后再调用restorePurchases()
    }
}

2. 完善购买状态持久化

handlePurchase()方法中仅更新了TextView,但应用重启后状态会丢失,建议将购买状态保存到SharedPreferences:

// 在handlePurchase的确认成功逻辑中添加
SharedPreferences prefs = getSharedPreferences("IAP_PREFS", MODE_PRIVATE);
prefs.edit().putBoolean("PREMIUM_PURCHASED", true).apply();

3. 处理Pending购买

当前代码未处理Pending状态的购买,建议在handlePurchase中补充判断:

void handlePurchase(Purchase purchase) {
    if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
        if (!purchase.isAcknowledged()) {
            // 确认购买逻辑
            billingClient.acknowledgePurchase(AcknowledgePurchaseParams
                    .newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .build(), billingResult -> {
                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                    // 保存购买状态、更新UI
                    SharedPreferences prefs = getSharedPreferences("IAP_PREFS", MODE_PRIVATE);
                    prefs.edit().putBoolean("PREMIUM_PURCHASED", true).apply();
                    tv_status.setText("Yay! Purchased");
                }
            });
        } else {
            // 已确认的购买,直接更新状态
            SharedPreferences prefs = getSharedPreferences("IAP_PREFS", MODE_PRIVATE);
            prefs.edit().putBoolean("PREMIUM_PURCHASED", true).apply();
            tv_status.setText("Yay! Purchased");
        }
    } else if (purchase.getPurchaseState() == Purchase.PurchaseState.PENDING) {
        // 处理Pending状态,提示用户等待交易完成
        tv_status.setText("Purchase pending, please wait");
    }
}

三、测试设备验证

  • 确保测试设备安装的是从Google Play测试链接获取的APK/AAB(或使用和上传到Play控制台一致签名的本地APK),不能使用调试签名的APK。
  • 设备必须退出所有非测试账号,仅登录授权的测试账号。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:25:22