使用Qonversion API校验用户订阅状态遇问题求助
Qonversion订阅状态校验问题:购买成功但回调不触发、checkEntitlements返回null
问题现象
- 用户完成谷歌订阅后返回应用,调用
checkEntitlements无法获取权限(返回null) - 实际订阅已成功(再次订阅时谷歌提示已订阅),但
purchase方法完全不进入onSuccess回调
相关代码
Fragment定义
class PurchaseFragment : Fragment() { private var _binding: FragmentPurchaseBinding? = null private val binding get() = _binding!! private var product: QProduct? = null
展示产品逻辑
private fun displayProducts() { Qonversion.shared.offerings(object : QonversionOfferingsCallback { override fun onSuccess(offerings: QOfferings) { val mainOffering = offerings.main if (mainOffering != null && mainOffering.products.isNotEmpty()) { binding.monthlyPrice.text = mainOffering.products[0].prettyPrice product = mainOffering.products[0] } } override fun onError(error: QonversionError) { Log.d(TAG, "Error: $error") } }) }
发起购买逻辑
private fun makePurchase(product: QProduct) { Qonversion.shared.purchase( requireActivity(), product, callback = object : QonversionEntitlementsCallback { override fun onSuccess(entitlements: Map<String, QEntitlement>) { val premiumEntitlement = entitlements["premium_permisson"] if (premiumEntitlement != null && premiumEntitlement.isActive) { Log.d(TAG, "Entitlements: $premiumEntitlement") } else { Log.d(TAG, "Entitlements else: $premiumEntitlement") } } override fun onError(error: QonversionError) { // 处理错误 if (error.code === QonversionErrorCode.CanceledPurchase) { Log.d(TAG, "Canceled") } } }) }
订阅状态校验逻辑
private fun isItPremiumUser() { Qonversion.shared.checkEntitlements(object : QonversionEntitlementsCallback { override fun onSuccess(entitlements: Map<String, QEntitlement>) { val premiumEntitlement = entitlements["premium_permisson"] Log.d(TAG, "isItPremiumUser $premiumEntitlement") // 返回null if (premiumEntitlement != null && premiumEntitlement.isActive) { Log.d(TAG, "isItPremiumUser Entitlements: $premiumEntitlement") // 处理有效权限 // 可检查续订状态 // 例如检查用户是否取消订阅并提供折扣 when (premiumEntitlement.renewState) { QEntitlementRenewState.NonRenewable -> { Log.d(TAG, "NonRenewable Entitlements: $premiumEntitlement") // NonRenewable是消耗型或非消耗型内购的状态 } QEntitlementRenewState.WillRenew -> { Log.d(TAG, "WillRenew Entitlements: $premiumEntitlement") // WillRenew是自动续订订阅的状态 } QEntitlementRenewState.BillingIssue -> { Log.d(TAG, "BillingIssue Entitlements: $premiumEntitlement") // 提示用户更新支付方式 } QEntitlementRenewState.Canceled -> { Log.d(TAG, "Canceled Entitlements: $premiumEntitlement") // 用户已关闭自动续订,但订阅尚未过期 // 提示用户以优惠重新订阅 } else -> { Log.d(TAG, "else Entitlements: $premiumEntitlement") } } } } override fun onError(error: QonversionError) { // 处理错误 Log.d(TAG, "onError: $error") } }) }
解决方案
1. 核对权限ID一致性
检查代码中使用的权限ID premium_permisson 是否和Qonversion后台配置的权限ID完全一致,注意大小写、拼写错误(比如多字符、少字符)。后台配置的权限ID必须与代码调用的完全匹配,否则会返回null。
2. 确保Qonversion与谷歌订阅同步正常
Qonversion需要同步谷歌Play Billing的订阅状态,需确认:
- 已在Qonversion后台正确配置谷歌服务账号密钥(JSON文件),确保订阅状态能从谷歌同步到Qonversion
- 测试环境下(如使用谷歌测试账号购买),需开启Qonversion后台的测试模式,确保测试订阅被正确同步
3. 修复purchase回调不触发问题
purchase不进入onSuccess通常由以下原因导致:
- Activity生命周期问题:调用
purchase时传入的requireActivity()可能在购买流程中被销毁,导致回调无法触发。建议使用viewLifecycleOwner关联的上下文,或确保Activity在购买过程中保持存活。 - 未转发Activity结果:若Qonversion版本需要手动处理Activity结果,需在Fragment中重写
onActivityResult并转发给Qonversion:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) Qonversion.shared.onActivityResult(requestCode, resultCode, data) }
- 错误回调未捕获全部情况:在
purchase的onError中打印完整错误信息,排查是否有其他异常:
override fun onError(error: QonversionError) { Log.d(TAG, "Purchase error: code=${error.code}, message=${error.message}") }
4. 正确的订阅状态校验流程
不要仅依赖checkEntitlements,建议结合以下步骤:
- 购买完成后主动同步:用户从谷歌支付界面返回应用时,先调用
Qonversion.shared.syncPurchases()同步本地购买记录到Qonversion,再校验权限:
// 在onResume或购买返回后调用 Qonversion.shared.syncPurchases(object : QonversionSyncCallback { override fun onSuccess() { isItPremiumUser() // 同步完成后再校验权限 } override fun onError(error: QonversionError) { Log.d(TAG, "Sync error: $error") } })
- 开启自动同步:在Application初始化时开启Qonversion自动同步,让SDK自动处理订阅状态更新:
// Application类中初始化Qonversion Qonversion.initialize(applicationContext, "YOUR_QONVERSION_KEY", true) // 第三个参数true表示开启自动同步购买记录
5. 测试环境注意事项
使用谷歌测试账号购买订阅时:
- 测试订阅有效期通常很短(如5分钟),过期后权限会失效
- 确保Qonversion后台测试模式已开启,或测试订单被正确识别
内容的提问来源于stack exchange,提问作者burhanyaprak
相关产品推荐
相关产品推荐

