Flutter/Dart如何判断应用是Google Play的付费版还是免费版?
Android 端一次性购买版本判断方案
针对同一套代码实现免费/付费版的需求,推荐以下几种无需后端、无需登录的方案:
方案1:包名区分(最简单高效)
编译时为免费版和付费版配置不同包名(比如com.yourapp.free和com.yourapp.paid),启动时直接读取当前应用包名判断:
val packageName = context.packageName val isPaidVersion = packageName == "com.yourapp.paid"
- 优势:零网络请求,启动速度快,实现成本极低
- 注意:需在Google Play后台分别上传两个包名的应用版本
方案2:Install Referrer API验证购买来源
一次性付费版的用户从Play Store付费商品页下载,可通过Install Referrer API获取安装来源参数判断:
- 添加依赖:
implementation "com.android.installreferrer:installreferrer:2.2"
- 核心代码:
val referrerClient = InstallReferrerClient.newBuilder(context).build() referrerClient.startConnection(object : InstallReferrerStateListener { override fun onInstallReferrerSetupFinished(responseCode: Int) { when (responseCode) { InstallReferrerClient.InstallReferrerResponse.OK -> { val referrer = referrerClient.installReferrer.installReferrer // 付费版的安装来源会包含Google Play配置的付费标识,比如"utm_medium=paid" val isPaidVersion = referrer.contains("utm_medium=paid") referrerClient.endConnection() } // 处理服务连接失败等异常情况 } } override fun onInstallReferrerServiceDisconnected() { // 可添加重试逻辑 } })
- 优势:无需维护多个包名,依赖Play官方服务可靠性高
- 注意:需确保付费版商品链接配置了正确的UTM参数
方案3:签名信息验证
为免费/付费版配置不同签名密钥,启动时读取应用签名哈希值对比:
fun isPaidVersion(context: Context): Boolean { val packageInfo = context.packageManager.getPackageInfo( context.packageName, PackageManager.GET_SIGNATURES ) val paidSignatureHash = "你的付费版签名哈希值" return packageInfo.signatures.any { it.toCharsString().hashCode().toString() == paidSignatureHash } }
- 优势:无需网络,安全性高,避免包名被篡改的风险
- 注意:需妥善保管两个签名密钥,避免丢失
iOS 端方案验证与修正建议
你提到的verifyReceipt接口方案仅适用于应用内购场景,对一次性购买的付费应用不适用,具体问题和修正方案如下:
原方案问题点
- 一次性购买的付费应用与免费应用的收据
in_app列表均为空,无法通过该字段区分版本 verifyReceipt接口要求POST请求(而非GET),且正式环境需使用https://buy.itunes.apple.com/verifyReceipt,沙箱地址仅用于内购测试
正确的iOS一次性购买版本区分方案
和Android一致,通过Bundle ID区分是最可靠的方式:
编译时为两个版本配置不同Bundle ID(比如com.yourapp.free和com.yourapp.paid),启动时读取判断:
let bundleId = Bundle.main.bundleIdentifier let isPaidVersion = bundleId == "com.yourapp.paid"
通用建议
无论Android还是iOS,推荐使用**构建变体(Build Variants)**实现同一代码多版本:
- Android:在Gradle中配置productFlavors,自动替换包名、资源、编译参数
- iOS:在Xcode中配置Target和Scheme,实现版本差异化编译
内容的提问来源于stack exchange,提问作者Anjos
相关产品推荐
相关产品推荐

