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

Flutter内购:如何获取稳定唯一标识,防止多账户滥用权限

解决Flutter非消耗型内购多账号滥用问题的方案

针对你遇到的in_app_purchase包中PurchaseID不稳定、导致多账号可通过恢复购买滥用付费权限的问题,给你几个不用RevenueCat的可行方案:

方案1:提取原生内购API的稳定交易标识

不同平台的内购API本身提供了稳定的交易标识,不需要依赖第三方服务:

  • iOS端:非消耗型内购恢复购买时,原生SKPaymentTransaction对象的originalTransaction字段会保留首次购买的交易记录,它的transactionIdentifier是固定不变的。你可以通过PurchaseDetails的skPaymentTransaction属性拿到这个原生对象,提取originalTransaction?.transactionIdentifier作为稳定标识存到Firestore。
  • Android端:非消耗型内购的Purchase对象里,purchaseToken是唯一且永久稳定的——不管用户恢复多少次购买,这个token都不会变。从PurchaseDetails的androidPurchase属性里就能拿到这个token,直接存下来就行。

用这个稳定标识替代PurchaseID,就能保证同一个用户的购买状态在不同设备、不同恢复操作下都能被正确识别。

方案2:绑定应用商店用户ID与Firebase账号

核心思路是让一个应用商店账号只能对应一个Firebase付费账号,从根源上防止滥用:

  • iOS:如果用户用Apple ID登录,直接用ASAuthorizationAppleIDProvider获取userIdentifier(这个ID是永久绑定用户Apple账号的);如果是其他登录方式,用SKCloudServiceController请求用户的CloudKit令牌(需要配置开发者token),拿到唯一的应用商店用户标识。
  • Android:通过Google Play Services API获取当前登录的Google账号ID(比如GoogleSignIn.getLastSignedInAccount(context)?.id),或者从BillingClient的回调里提取用户的Play Store账号标识。

在Firestore建一个app_store_user_bindings集合,存储{app_store_user_id: string, firebase_uid: string}的映射。用户购买或恢复购买时,先查这个集合:如果该应用商店用户ID已经绑定了其他Firebase UID,就拒绝标记当前账号为付费;如果没绑定,就把当前Firebase UID和它绑定,并标记付费状态。

方案3:后端验证购买凭证(最安全)

放弃直接存交易ID,改为每次购买/恢复后,把购买凭证发到后端(比如Firebase Functions)验证,验证通过再标记付费:

  • iOS:从SKPaymentQueue.default().appStoreReceiptURL读取收据文件,转成base64字符串后发送到Apple的官方验证接口,验证结果里会包含原始交易ID和用户的唯一标识。
  • Android:把purchaseToken和商品ID发送到Google Play的验证接口,接口会返回该购买的合法性以及对应的用户信息。

后端验证通过后,在Firestore里给对应的Firebase UID标记付费状态,同时记录该凭证对应的应用商店用户ID。这种方式既能确保购买是真实有效的,又能通过后端逻辑严格控制一个应用商店账号只能绑定一个Firebase账号,彻底杜绝滥用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 05:27:18