Unity内置IAP中如何仅在真实购买时触发营收分析?
解决Unity IAP中仅真实购买触发Fabric营收分析的问题
嘿,我来帮你搞定这个问题~ 你遇到的核心痛点是ProcessPurchase()在首次订阅和恢复购买时都会被调用,导致如果直接在这里加Fabric代码,会把恢复的情况也误统计成新购买,对吧?下面给你拆解解决方案,以及纠正代码放置的位置:
首先:如何区分「真实购买」和「恢复购买」
Unity IAP本身没有直接提供区分两者的字段,但我们可以通过两种可靠的方式来判断:
方式1:用恢复标记跟踪(简单直接)
在调用恢复购买的方法时,设置一个全局标记,ProcessPurchase()里根据这个标记判断是否是恢复场景:
private bool _isRestoringPurchases = false; // 你的恢复购买触发方法 public void TriggerRestorePurchases() { _isRestoringPurchases = true; UnityPurchasing.Instance.RestoreTransactions((success) => { _isRestoringPurchases = false; // 恢复完成后的提示逻辑,比如弹窗告知用户 }); }
方式2:用交易ID去重(更通用,覆盖自动恢复场景)
有些平台可能会自动恢复购买(比如用户重装APP后),这种情况不会走你手动调用的恢复方法,这时候跟踪已处理的交易ID更靠谱:
private HashSet<string> _processedTransactionIds = new HashSet<string>(); void Awake() { // 从本地加载之前处理过的交易ID,避免重启APP后重复统计 string savedIds = PlayerPrefs.GetString("ProcessedTransactions", ""); if (!string.IsNullOrEmpty(savedIds)) { foreach (string id in savedIds.Split(',')) { _processedTransactionIds.Add(id); } } }
然后:Fabric API的正确放置位置
不管用哪种区分方式,你都需要把Fabric的营收统计代码放在确认是首次真实购买的分支里,而不是直接放在ProcessPurchase()的开头。结合你的代码片段,修改后的示例如下:
结合恢复标记的完整代码
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) { bool validPurchase = true; // 第一步:先做你的收据验证逻辑(比如校验receipt合法性) if (/* 你的收据验证不通过 */) { validPurchase = false; } if (validPurchase) { // 第二步:判断是否是真实购买,而非恢复 if (!_isRestoringPurchases) { // 这里才是调用Fabric API的正确位置! // 比如:Fabric.Analytics.LogPurchase( // args.purchasedProduct.definition.id, // args.purchasedProduct.metadata.localizedPrice, // args.purchasedProduct.metadata.isoCurrencyCode // ); Debug.Log("已记录真实购买到Fabric"); } else { Debug.Log("恢复购买,跳过Fabric统计"); } // 第三步:处理商品逻辑(比如解锁功能、激活订阅) UnlockPremiumContent(args.purchasedProduct); } return PurchaseProcessingResult.Complete; }
结合交易ID去重的完整代码
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) { bool validPurchase = true; // 第一步:收据验证 if (/* 验证失败 */) { validPurchase = false; } if (validPurchase) { string transactionId = args.purchasedProduct.transactionID; // 第二步:判断该交易是否已经处理过 if (!_processedTransactionIds.Contains(transactionId)) { // 真实购买,调用Fabric API // Fabric.Analytics.LogPurchase(...); Debug.Log("已记录真实购买到Fabric"); // 保存交易ID到本地,避免重复统计 _processedTransactionIds.Add(transactionId); PlayerPrefs.SetString("ProcessedTransactions", string.Join(",", _processedTransactionIds)); PlayerPrefs.Save(); } else { Debug.Log("该交易已处理(恢复购买),跳过Fabric统计"); } // 第三步:处理商品逻辑 UnlockPremiumContent(args.purchasedProduct); } return PurchaseProcessingResult.Complete; }
为什么你原来的代码位置不对?
如果直接在ProcessPurchase()里不加判断就调用Fabric,会把「恢复购买」也当成「新购买」统计,导致你的营收数据虚高,无法准确反映真实的用户付费行为——毕竟恢复购买只是找回已有的权益,不是产生新的营收。
内容的提问来源于stack exchange,提问作者Tengku Fathullah
相关产品推荐
相关产品推荐

