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

如何在Jetpack Compose安卓应用中检查内购状态并处理退款降级

无后端退款后自动降级Premium权限的实现方案

核心思路

无需依赖后端,直接通过Google Billing Library主动查询用户的有效购买记录,用官方返回的状态覆盖本地偏好值,确保权限状态与Google Play后台完全同步。

具体实现步骤

1. 新增已购商品校验方法

在MainActivity2中添加专门的查询逻辑,校验用户当前是否拥有有效的Premium购买:

private fun queryValidPurchases() {
    // 先判断Billing Client是否就绪,未就绪则先建立连接
    if (!billingClient.isReady) {
        startBillingConnection(object : BillingClientStateListener {
            override fun onBillingSetupFinished(billingResult: BillingResult) {
                if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
                    performPurchaseQuery()
                }
            }

            override fun onBillingServiceDisconnected() {
                // 可添加重试逻辑,或提示用户检查网络
            }
        })
        return
    }
    performPurchaseQuery()
}

private fun performPurchaseQuery() {
    val queryParams = QueryPurchasesParams.newBuilder()
        .setProductType(BillingClient.ProductType.INAPP)
        .build()

    billingClient.queryPurchasesAsync(queryParams) { billingResult, purchases ->
        if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
            // 筛选有效购买:包含目标商品ID、已完成购买、已确认
            val hasValidPremium = purchases.any { purchase ->
                purchase.products.contains(productId) &&
                        purchase.purchaseState == Purchase.PurchaseState.PURCHASED &&
                        purchase.isAcknowledged
            }
            // 更新本地偏好状态
            lifecycleScope.launch {
                userPreferencesRepository.changePremiumStatus(hasValidPremium)
            }
        } else {
            // 查询失败时默认降级,或保留本地状态(根据需求调整)
            lifecycleScope.launch {
                userPreferencesRepository.changePremiumStatus(false)
            }
        }
    }
}

2. 在关键节点触发校验

将校验逻辑放在应用启动、后台切前台的时机,确保每次用户使用应用时都同步状态:

  • 修改startBillingConnection的回调,启动时自动校验:
override fun onBillingSetupFinished(billingResult: BillingResult) {
    if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
        queryValidPurchases() // 启动时同步购买状态
    }
}
  • 重写onResume方法,后台恢复时再次校验:
override fun onResume() {
    super.onResume()
    if (billingClient.isReady) {
        queryValidPurchases()
    } else {
        startBillingConnection()
    }
}

3. 完善一次性内购的确认逻辑

一次性内购必须调用acknowledgePurchase完成确认,否则Google Play会在3天后自动退款。补充handlePurchase方法:

private fun handlePurchase(purchase: Purchase) {
    if (!purchase.isAcknowledged) {
        val acknowledgeParams = AcknowledgePurchaseParams.newBuilder()
            .setPurchaseToken(purchase.purchaseToken)
            .build()
        billingClient.acknowledgePurchase(acknowledgeParams) { billingResult ->
            if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
                Toast.makeText(this, "Welcome to Groovy Premium!", Toast.LENGTH_SHORT).show()
                lifecycleScope.launch {
                    userPreferencesRepository.changePremiumStatus(true)
                }
            } else {
                Toast.makeText(this, "Purchase confirmation failed", Toast.LENGTH_SHORT).show()
            }
        }
    } else {
        Toast.makeText(this, "Welcome to Groovy Premium!", Toast.LENGTH_SHORT).show()
        lifecycleScope.launch {
            userPreferencesRepository.changePremiumStatus(true)
        }
    }
}

4. 退款后的自动降级逻辑

当用户退款后,Google Play会将该购买标记为无效,queryValidPurchases查询时会返回空的有效购买列表,此时本地偏好会自动被设为false,实现权限降级。

额外优化建议

  • 添加"恢复购买"按钮:在应用设置页提供按钮,点击时触发queryValidPurchases,让用户主动同步状态;
  • 限制查询频率:可添加时间戳判断,比如1小时内仅查询一次,减少不必要的网络请求;
  • 权限前置校验:用户访问Premium功能前,先触发一次queryValidPurchases,避免本地状态延迟。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 02:22:13