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

购买iap_lifetime内购包后VIP身份无法验证,请求排查代码问题

问题分析:内购“iap_lifetime”购买后未被识别为VIP

用户集成了以下检查VIP状态的代码,用户购买永久内购包“iap_lifetime”后,系统未识别其VIP身份。已在购买回调中调用acknowledgePurchase方法,不确定是否为代码问题。

确认购买的代码实现

val acknowledgeParams =
    AcknowledgePurchaseParams.newBuilder().setPurchaseToken(purchase.purchaseToken)
        .build()

client.acknowledgePurchase(acknowledgeParams) { billingResult: BillingResult ->
    runOnUiThread {
        processingPurchaseTokens.remove(purchase.purchaseToken)
        if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
            val productId = purchase.products.firstOrNull() ?: ""
            AdAnalyticsHelper.trackIapRevenue(purchase, productDetailsMap[productId])
        } else {
            showToast("Acknowledge failed: ${billingResult.debugMessage}")
        }
        finalizeVipActivation(grant)
    }
}

检查VIP状态的代码实现

fun checkSubscription() {
    try {
        val billingClient = BillingClient.newBuilder(this)
            .enablePendingPurchases()
            .setListener { _, _ -> }
            .build()

        billingClient.startConnection(object : BillingClientStateListener {

            override fun onBillingServiceDisconnected() {
            }

            override fun onBillingSetupFinished(billingResult: BillingResult) {
                if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
                    VipManager.setVip(false)
                    return
                }
                // Check SUBS
                billingClient.queryPurchasesAsync(
                    QueryPurchasesParams.newBuilder()
                        .setProductType(BillingClient.ProductType.SUBS)
                        .build()
                ) { subsResult, subsList ->
                    var isVip = false
                    if (subsResult.responseCode == BillingClient.BillingResponseCode.OK) {
                        isVip = subsList.any { purchase ->
                            purchase.purchaseState == Purchase.PurchaseState.PURCHASED &&
                                    purchase.products.isNotEmpty()
                        }
                    }

                    if (!isVip) {
                        billingClient.queryPurchasesAsync(
                            QueryPurchasesParams.newBuilder()
                                .setProductType(BillingClient.ProductType.INAPP)
                                .build()
                        ) { inAppResult, inAppList ->
                            if (inAppResult.responseCode == BillingClient.BillingResponseCode.OK) {
                                isVip = inAppList.any { purchase ->
                                    purchase.purchaseState == Purchase.PurchaseState.PURCHASED &&
                                            purchase.products.contains("iap_lifetime")
                                }
                            }
                            VipManager.setVip(isVip)
                        }
                    } else {
                        VipManager.setVip(true)
                    }
                }
            }
        })
    } catch (_: Exception) {
    }
}

可能的问题点及修复建议

1. 确认购买后的VIP状态更新逻辑缺失

当前代码在确认购买成功后调用了finalizeVipActivation(grant),但未明确该方法是否会直接将用户标记为VIP。建议:

  • 在acknowledgePurchase成功回调中,当productId为“iap_lifetime”时,直接调用VipManager.setVip(true),无需依赖后续的checkSubscription查询,避免查询延迟或失败导致的状态不更新。
  • 检查grant参数是否正确传递了VIP激活的标识,确保finalizeVipActivation方法逻辑正确。

2. checkSubscription方法的异常处理不合理

方法中捕获所有异常但未做任何处理,若BillingClient连接、查询过程中出现异常,会导致VipManager.setVip无法执行,VIP状态停留在之前的错误值。建议:

  • 在catch块中添加默认处理,比如VipManager.setVip(false),同时可添加日志记录异常信息,方便排查问题。

3. 内购查询未处理未确认的购买

Google Play中,购买成功但未确认的订单,purchaseState仍为Purchase.PurchaseState.PURCHASED,但长期未确认会被自动退款。当前查询逻辑未检查购买是否已确认,可能导致状态判断混乱。建议:

  • 在INAPP购买的判断条件中,增加purchase.isAcknowledged检查,确保只将已确认的“iap_lifetime”购买标记为VIP:
    isVip = inAppList.any { purchase ->
        purchase.purchaseState == Purchase.PurchaseState.PURCHASED &&
                purchase.isAcknowledged &&
                purchase.products.contains("iap_lifetime")
    }
    

4. 检查ProductId的匹配准确性

确认代码中使用的“iap_lifetime”与Google Play Console中配置的内购商品ID完全一致,注意大小写、拼写错误,这是常见的排查点。

5. BillingClient实例管理优化

每次调用checkSubscription都新建BillingClient实例,虽然功能正常,但可能增加连接开销。建议复用全局的BillingClient实例,避免重复创建和连接。

内容的提问来源于stack exchange,提问作者Hải Đào Ngọc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:10:56