+ Opt IAPService OrderData, add orderId, payedDate, productId to tch001 EVENT.
							parent
							
								
									6ef4d0cdec
								
							
						
					
					
						commit
						5a52fc0987
					
				| 
						 | 
					@ -314,9 +314,13 @@ namespace Guru
 | 
				
			||||||
	    /// 每发生一次iap收入,触发一次该事件,value值为本次iap的收入值;
 | 
						    /// 每发生一次iap收入,触发一次该事件,value值为本次iap的收入值;
 | 
				
			||||||
	    /// </summary>
 | 
						    /// </summary>
 | 
				
			||||||
	    /// <param name="value">中台返回地收入值</param>
 | 
						    /// <param name="value">中台返回地收入值</param>
 | 
				
			||||||
	    public static void Tch001IAPRev(double value)
 | 
						    /// <param name="productId"></param>
 | 
				
			||||||
 | 
						    /// <param name="orderId"></param>
 | 
				
			||||||
 | 
						    /// <param name="orderType"></param>
 | 
				
			||||||
 | 
						    /// <param name="timestamp"></param>
 | 
				
			||||||
 | 
						    public static void Tch001IAPRev(double value, string productId, string orderId, string orderType, string timestamp)
 | 
				
			||||||
	    {
 | 
						    {
 | 
				
			||||||
		    TchRevEvent(EventTchAdRev001Impression, IAPPlatform, value);
 | 
							    TchRevEvent(EventTchAdRev001Impression, IAPPlatform, value, orderType, productId, orderId, timestamp);
 | 
				
			||||||
		    
 | 
							    
 | 
				
			||||||
		    if(EnableTch02Event) return; // 如果使用了太极02 则不做FB上报
 | 
							    if(EnableTch02Event) return; // 如果使用了太极02 则不做FB上报
 | 
				
			||||||
		    FBPurchase(value, USD, "iap", IAPPlatform);
 | 
							    FBPurchase(value, USD, "iap", IAPPlatform);
 | 
				
			||||||
| 
						 | 
					@ -327,6 +331,11 @@ namespace Guru
 | 
				
			||||||
	    /// 发生一次iap收入,触发一次该事件,value值为本次iap的收入值;
 | 
						    /// 发生一次iap收入,触发一次该事件,value值为本次iap的收入值;
 | 
				
			||||||
	    /// </summary>
 | 
						    /// </summary>
 | 
				
			||||||
	    /// <param name="value"></param>
 | 
						    /// <param name="value"></param>
 | 
				
			||||||
 | 
						    /// <param name="productId"></param>
 | 
				
			||||||
 | 
						    /// <param name="orderId"></param>
 | 
				
			||||||
 | 
						    /// <param name="orderType"></param>
 | 
				
			||||||
 | 
						    /// <param name="timestamp"></param>
 | 
				
			||||||
 | 
						    // public static void Tch02IAPRev(double value, string productId, string orderId, string orderType, string timestamp)
 | 
				
			||||||
	    public static void Tch02IAPRev(double value)
 | 
						    public static void Tch02IAPRev(double value)
 | 
				
			||||||
	    {
 | 
						    {
 | 
				
			||||||
		    if (!EnableTch02Event) return;
 | 
							    if (!EnableTch02Event) return;
 | 
				
			||||||
| 
						 | 
					@ -378,16 +387,31 @@ namespace Guru
 | 
				
			||||||
	    /// <param name="evtName"></param>
 | 
						    /// <param name="evtName"></param>
 | 
				
			||||||
	    /// <param name="platform"></param>
 | 
						    /// <param name="platform"></param>
 | 
				
			||||||
	    /// <param name="value"></param>
 | 
						    /// <param name="value"></param>
 | 
				
			||||||
	    private static void TchRevEvent(string evtName, string platform, double value)
 | 
						    /// <param name="orderType"></param>
 | 
				
			||||||
 | 
						    /// <param name="productId"></param>
 | 
				
			||||||
 | 
						    /// <param name="orderId"></param>
 | 
				
			||||||
 | 
						    /// <param name="timestamp"></param>
 | 
				
			||||||
 | 
						    private static void TchRevEvent(string evtName, string platform, double value, 
 | 
				
			||||||
 | 
							    string orderType = "", string productId = "", string orderId = "", string timestamp = "")
 | 
				
			||||||
	    {
 | 
						    {
 | 
				
			||||||
		    LogEvent(evtName, new Dictionary<string, dynamic>()
 | 
							    var data = new Dictionary<string, dynamic>()
 | 
				
			||||||
		    {
 | 
							    {
 | 
				
			||||||
			    { ParameterAdPlatform, platform },
 | 
								    { ParameterAdPlatform, platform },
 | 
				
			||||||
			    { ParameterCurrency, USD },
 | 
								    { ParameterCurrency, USD },
 | 
				
			||||||
			    { ParameterValue, value },
 | 
								    { ParameterValue, value },
 | 
				
			||||||
		    });
 | 
							    };
 | 
				
			||||||
 | 
							    
 | 
				
			||||||
 | 
							    //--------- Extra data for IAP receipt ---------------
 | 
				
			||||||
 | 
							    if(!string.IsNullOrEmpty(orderType)) data.Add("order_type", orderType);
 | 
				
			||||||
 | 
							    if(!string.IsNullOrEmpty(productId)) data.Add("product_id", productId);
 | 
				
			||||||
 | 
							    if(!string.IsNullOrEmpty(orderId)) data.Add("order_id", orderId);
 | 
				
			||||||
 | 
							    if(!string.IsNullOrEmpty(timestamp)) data.Add("payed_date", timestamp);
 | 
				
			||||||
 | 
							    //--------- Extra data for IAP receipt ---------------
 | 
				
			||||||
 | 
							    
 | 
				
			||||||
 | 
							    LogEvent(evtName, data);
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	    
 | 
						    
 | 
				
			||||||
 | 
						    
 | 
				
			||||||
	    /// <summary>
 | 
						    /// <summary>
 | 
				
			||||||
	    /// Facebook 支付上报
 | 
						    /// Facebook 支付上报
 | 
				
			||||||
	    /// </summary>
 | 
						    /// </summary>
 | 
				
			||||||
| 
						 | 
					@ -528,7 +552,7 @@ namespace Guru
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// 新用户首次 IAP 付费成功上报 (仅限应用内付费商品,不包含订阅等其它情况)【买量打点】
 | 
							/// 新用户首次 IAP 付费成功上报 (仅限应用内付费商品,不包含订阅等其它情况)【买量打点】
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		/// <param name="itemName">product_id 商品ID</param>
 | 
							/// <param name="itemName">productId 商品ID</param>
 | 
				
			||||||
		/// <param name="value">付费总金额</param>
 | 
							/// <param name="value">付费总金额</param>
 | 
				
			||||||
		/// <param name="currency">币种</param>
 | 
							/// <param name="currency">币种</param>
 | 
				
			||||||
		public static void FirstIAP(string itemName, double value, string currency)
 | 
							public static void FirstIAP(string itemName, double value, string currency)
 | 
				
			||||||
| 
						 | 
					@ -545,7 +569,7 @@ namespace Guru
 | 
				
			||||||
		/// 商品购买成功上报【买量打点】
 | 
							/// 商品购买成功上报【买量打点】
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		/// <param name="productName">商品名称(商品ID一样)</param>
 | 
							/// <param name="productName">商品名称(商品ID一样)</param>
 | 
				
			||||||
		/// <param name="itemName">product_id 商品ID</param>
 | 
							/// <param name="itemName">productId 商品ID</param>
 | 
				
			||||||
		/// <param name="value">付费总金额</param>
 | 
							/// <param name="value">付费总金额</param>
 | 
				
			||||||
		/// <param name="currency">币种</param>
 | 
							/// <param name="currency">币种</param>
 | 
				
			||||||
		public static void ProductIAP(string productName, string itemName, double value, string currency)
 | 
							public static void ProductIAP(string productName, string itemName, double value, string currency)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,12 @@ namespace Guru
 | 
				
			||||||
            return dateTime.Ticks / TICK_TO_MILLISECOND - STAMP_1970_1_1;
 | 
					            return dateTime.Ticks / TICK_TO_MILLISECOND - STAMP_1970_1_1;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        public static string GetTimeStampString(DateTime dateTime)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return GetTimeStamp(dateTime).ToString();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 时间戳转日期
 | 
					        /// 时间戳转日期
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,49 +1,44 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using PlasticPipe.PlasticProtocol.Messages;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Guru
 | 
					namespace Guru
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    using System;
 | 
					    using System;
 | 
				
			||||||
    using System.Collections.Generic;
 | 
					    using System.Collections.Generic;
 | 
				
			||||||
    using Newtonsoft.Json;
 | 
					    using Newtonsoft.Json;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// 该数据用于向服务端发送对应的消息
 | 
				
			||||||
 | 
					    /// 同时兼具缓存用户数据
 | 
				
			||||||
 | 
					    /// 详见 <a>https://github.com/castbox/backend-dev/blob/main/saas/%E4%B8%AD%E5%8F%B0%E6%9C%8D%E5%8A%A1%E6%8E%A5%E5%85%A5%E6%89%8B%E5%86%8C.md#553apple-store%E8%AE%A2%E5%8D%95%E4%B8%8A%E6%8A%A5</a>
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
    [Serializable]
 | 
					    [Serializable]
 | 
				
			||||||
    public class AppleOrderData
 | 
					    public class AppleOrderData : BaseOrderData
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public string guid;
 | 
					 | 
				
			||||||
        public int orderType;
 | 
					 | 
				
			||||||
        public string productId;
 | 
					 | 
				
			||||||
        public string bundleId;
 | 
					 | 
				
			||||||
        public string receipt;
 | 
					 | 
				
			||||||
        public string country;
 | 
					 | 
				
			||||||
        public int level;
 | 
					 | 
				
			||||||
        public Dictionary<string, object> userInfo;
 | 
					 | 
				
			||||||
        public EventConfig eventConfig;
 | 
					 | 
				
			||||||
       
 | 
					       
 | 
				
			||||||
        public AppleOrderData(int orderType, string productId, string receipt, int level)
 | 
					        public string bundleId; //应用包名
 | 
				
			||||||
 | 
					        public string receipt; // Apple Store返回的Receipt数据
 | 
				
			||||||
 | 
					        public string country; // 用户商店的国家2字大写代码
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public AppleOrderData(int orderType, string productId, string receipt, string orderId, 
 | 
				
			||||||
 | 
					            string date, int level, string offerId = "", string basePlanId = "") : base(orderType, productId, orderId, date, level, offerId, basePlanId)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            guid = Guid.NewGuid().ToString();
 | 
					 | 
				
			||||||
            this.orderType = orderType;
 | 
					 | 
				
			||||||
            this.productId = productId;
 | 
					 | 
				
			||||||
            this.receipt = receipt;
 | 
					            this.receipt = receipt;
 | 
				
			||||||
            this.level = level;
 | 
					 | 
				
			||||||
            bundleId = GuruSettings.Instance.GameIdentifier;
 | 
					            bundleId = GuruSettings.Instance.GameIdentifier;
 | 
				
			||||||
            country = IPMConfig.IPM_COUNTRY_CODE;
 | 
					            country = IPMConfig.IPM_COUNTRY_CODE;
 | 
				
			||||||
            userInfo = new Dictionary<string, object> { ["level"] = level };
 | 
					 | 
				
			||||||
            eventConfig = EventConfig.Build();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        public bool Equals(AppleOrderData other)
 | 
					        public bool Equals(AppleOrderData other)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (string.IsNullOrEmpty(guid)) guid = Guid.NewGuid().ToString();
 | 
					            if (string.IsNullOrEmpty(guid)) guid = GetGuid();
 | 
				
			||||||
            return guid.Equals(other.guid);
 | 
					            return guid.Equals(other.guid);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        public string GetId() => productId;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        public override string ToString()
 | 
					        public override string ToString()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return $"{nameof(orderType)}: {orderType}, {nameof(productId)}: {productId}, {nameof(bundleId)}: {bundleId}, {nameof(receipt)}: {receipt}, {nameof(country)}: {country}";
 | 
					            return "AppleOrderData: " + base.ToString() + $", {nameof(bundleId)}: {bundleId}, {nameof(receipt)}: {receipt}, {nameof(country)}: {country}";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public string ToJson() => JsonConvert.SerializeObject(this);
 | 
					        public string ToJson() => JsonConvert.SerializeObject(this);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,59 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Guru
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    using System;
 | 
				
			||||||
 | 
					    using System.Collections.Generic;
 | 
				
			||||||
 | 
					    using Newtonsoft.Json;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    public class BaseOrderData
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        [JsonIgnore]
 | 
				
			||||||
 | 
					        public string guid; // 唯一标识
 | 
				
			||||||
 | 
					        public string productId; // 商品ID 当orderType=0时,传递该参数
 | 
				
			||||||
 | 
					        [JsonIgnore]
 | 
				
			||||||
 | 
					        public int level; // 关卡 ID
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public int orderType; // 订单类型,可选值:0:IAP 订单 1:SUB 订阅订单
 | 
				
			||||||
 | 
					        public Dictionary<string, object> userInfo; // 当前用户信息。目前包含: level: 用户属性中的"b_level"的值
 | 
				
			||||||
 | 
					        public EventConfig eventConfig; // 	事件打点所需信息
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        //---- Offer Data -------
 | 
				
			||||||
 | 
					        [JsonIgnore]
 | 
				
			||||||
 | 
					        public string orderId; // 订单的 OrderID
 | 
				
			||||||
 | 
					        [JsonIgnore]
 | 
				
			||||||
 | 
					        public string payedDate; // 支付时间 (13位时间戳)
 | 
				
			||||||
 | 
					        public string basePlanId; // 订阅商品的planId
 | 
				
			||||||
 | 
					        public string offerId; // 订阅商品的offerId
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public BaseOrderData(int orderType, string productId, string orderId, 
 | 
				
			||||||
 | 
					            string payedDate, int level, string offerId = "", string basePlanId = "")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            guid = GetGuid();
 | 
				
			||||||
 | 
					            this.orderType = orderType;
 | 
				
			||||||
 | 
					            this.productId = productId;
 | 
				
			||||||
 | 
					            this.orderId = orderId;
 | 
				
			||||||
 | 
					            this.payedDate = payedDate;
 | 
				
			||||||
 | 
					            this.basePlanId = basePlanId;
 | 
				
			||||||
 | 
					            this.offerId = offerId;
 | 
				
			||||||
 | 
					            this.level = level;
 | 
				
			||||||
 | 
					            userInfo = new Dictionary<string, object> { ["level"] = level };
 | 
				
			||||||
 | 
					            eventConfig = EventConfig.Build();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected string GetGuid() => Guid.NewGuid().ToString();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public string OrderType() => orderType == 0 ? "IAP" : "SUB";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override string ToString()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return $"{nameof(orderType)}: {orderType}, {nameof(productId)}: {productId}, {nameof(orderId)}: {orderId}, {nameof(payedDate)}: {payedDate}";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,3 @@
 | 
				
			||||||
 | 
					fileFormatVersion: 2
 | 
				
			||||||
 | 
					guid: e576b9cd108047ec91aac82aa9aca5c6
 | 
				
			||||||
 | 
					timeCreated: 1715252456
 | 
				
			||||||
| 
						 | 
					@ -5,35 +5,30 @@ namespace Guru
 | 
				
			||||||
    using System.Collections.Generic;
 | 
					    using System.Collections.Generic;
 | 
				
			||||||
    using Newtonsoft.Json;
 | 
					    using Newtonsoft.Json;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// 该数据用于向服务端发送对应的消息
 | 
				
			||||||
 | 
					    /// 同时兼具缓存用户数据
 | 
				
			||||||
 | 
					    /// 详见 <a>https://github.com/castbox/backend-dev/blob/main/saas/%E4%B8%AD%E5%8F%B0%E6%9C%8D%E5%8A%A1%E6%8E%A5%E5%85%A5%E6%89%8B%E5%86%8C.md#552google%E8%AE%A2%E5%8D%95%E4%B8%8A%E6%8A%A5</a>
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
    [Serializable]
 | 
					    [Serializable]
 | 
				
			||||||
    public class GoogleOrderData
 | 
					    public class GoogleOrderData : BaseOrderData
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public string guid;
 | 
					        private string _productId;
 | 
				
			||||||
        public int orderType;   // 订单类型,可选值:0:IAP订单 1: 订阅订单
 | 
					        public string subscriptionId; // 订阅道具名称
 | 
				
			||||||
        public string packageName; //应用包名 
 | 
					        public string packageName; //应用包名 
 | 
				
			||||||
        public string productId = ""; // 商品ID 当orderType=0时,传递该参数
 | 
					 | 
				
			||||||
        public string subscriptionId = ""; // 订阅ID // 当orderType=1时,传递该参数
 | 
					 | 
				
			||||||
        public string token;  // 应用商店里面的购买token
 | 
					        public string token;  // 应用商店里面的购买token
 | 
				
			||||||
        public int level;
 | 
					 | 
				
			||||||
        public Dictionary<string, object> userInfo; // 当前用户信息。目前包含: level: 用户属性中的"b_level"的值
 | 
					 | 
				
			||||||
        public string basePlanId = ""; // 订阅商品的planId
 | 
					 | 
				
			||||||
        public string offerId = ""; // 订阅商品的offerId
 | 
					 | 
				
			||||||
        public EventConfig eventConfig; // 	事件打点所需信息
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        public GoogleOrderData(int orderType, string productId, string subscriptionId, string token, int level, 
 | 
					        public GoogleOrderData(int orderType, string productId, string token, string orderId, 
 | 
				
			||||||
            string offerId = "", string basePlanId = "")
 | 
					            string date, int level, string offerId = "", string basePlanId = "") : base(orderType, productId, orderId, date, level, offerId, basePlanId)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            guid = Guid.NewGuid().ToString();
 | 
					            _productId = productId;
 | 
				
			||||||
            this.orderType = orderType;
 | 
					 | 
				
			||||||
            this.packageName = GuruSettings.Instance.GameIdentifier;
 | 
					            this.packageName = GuruSettings.Instance.GameIdentifier;
 | 
				
			||||||
            this.productId = productId;
 | 
					 | 
				
			||||||
            this.subscriptionId = subscriptionId;
 | 
					 | 
				
			||||||
            this.token = token;
 | 
					            this.token = token;
 | 
				
			||||||
            this.offerId = offerId;
 | 
					            if (orderType == 1)
 | 
				
			||||||
            this.basePlanId = basePlanId;
 | 
					            {
 | 
				
			||||||
            this.level = level;
 | 
					                this.subscriptionId = productId;
 | 
				
			||||||
            userInfo = new Dictionary<string, object> { ["level"] = level };
 | 
					                this.productId = "";
 | 
				
			||||||
            eventConfig = EventConfig.Build();
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public bool Equals(GoogleOrderData other)
 | 
					        public bool Equals(GoogleOrderData other)
 | 
				
			||||||
| 
						 | 
					@ -42,11 +37,13 @@ namespace Guru
 | 
				
			||||||
            return guid == other.guid;
 | 
					            return guid == other.guid;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        public string ToJson() => JsonConvert.SerializeObject(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string RealProductId => _productId;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        public override string ToString()
 | 
					        public override string ToString()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return $"{nameof(orderType)}: {orderType}, {nameof(packageName)}: {packageName}, {nameof(productId)}: {productId}, {nameof(subscriptionId)}: {subscriptionId}, {nameof(token)}: {token}";
 | 
					            return "GoogleOrderData: " + base.ToString() + $",{nameof(subscriptionId)}: {subscriptionId}, {nameof(packageName)}: {packageName}, {nameof(token)}: {token}";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        public string ToJson() => JsonConvert.SerializeObject(this);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -13,26 +13,29 @@ namespace Guru
 | 
				
			||||||
        public int orderType;
 | 
					        public int orderType;
 | 
				
			||||||
        public string productId;
 | 
					        public string productId;
 | 
				
			||||||
        public string receipt;
 | 
					        public string receipt;
 | 
				
			||||||
        public int level;
 | 
					 | 
				
			||||||
        public AppleOrderData orderData;
 | 
					        public AppleOrderData orderData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public AppleOrderRequest(){}
 | 
					        public AppleOrderRequest(){}
 | 
				
			||||||
        public static AppleOrderRequest Build(int orderType, string productId, string receipt, int level)
 | 
					        public static AppleOrderRequest Build(int orderType, string productId, string receipt, string orderId, string date, int level)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var request = new AppleOrderRequest()
 | 
					            var request = new AppleOrderRequest()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                orderType = orderType,
 | 
					                orderType = orderType,
 | 
				
			||||||
                productId = productId,
 | 
					                productId = productId,
 | 
				
			||||||
                receipt = receipt,
 | 
					                receipt = receipt,
 | 
				
			||||||
                level = level,
 | 
					                orderData = new AppleOrderData(orderType, productId, receipt, orderId, date, level),
 | 
				
			||||||
                orderData = new AppleOrderData(orderType, productId, receipt, level),
 | 
					 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            return request;
 | 
					            return request;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static AppleOrderRequest Build(AppleOrderData orderData)
 | 
					        public static AppleOrderRequest Build(AppleOrderData orderData)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return Build(orderData.orderType, orderData.productId, orderData.receipt, orderData.level);
 | 
					            return Build(orderData.orderType, 
 | 
				
			||||||
 | 
					                orderData.productId, 
 | 
				
			||||||
 | 
					                orderData.receipt,
 | 
				
			||||||
 | 
					                orderData.orderId,
 | 
				
			||||||
 | 
					                orderData.payedDate,
 | 
				
			||||||
 | 
					                orderData.level);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        protected override string RequestURL => IPMConfig.IPM_URL + "order/api/v1/orders/ios";
 | 
					        protected override string RequestURL => IPMConfig.IPM_URL + "order/api/v1/orders/ios";
 | 
				
			||||||
| 
						 | 
					@ -57,18 +60,12 @@ namespace Guru
 | 
				
			||||||
                if (responseData != null && responseData.data != null)
 | 
					                if (responseData != null && responseData.data != null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    double usdPrice = responseData.data.usdPrice;
 | 
					                    double usdPrice = responseData.data.usdPrice;
 | 
				
			||||||
                    Analytics.Tch001IAPRev(usdPrice);
 | 
					                    
 | 
				
			||||||
 | 
					                    Analytics.Tch001IAPRev(usdPrice, productId, orderData.orderId, orderData.OrderType(), orderData.payedDate);
 | 
				
			||||||
                    Analytics.Tch02IAPRev(usdPrice);
 | 
					                    Analytics.Tch02IAPRev(usdPrice);
 | 
				
			||||||
                    if (orderType == 0)
 | 
					                    
 | 
				
			||||||
                    {
 | 
					                    AdjustService.TrackSubPurchase(usdPrice, productId);
 | 
				
			||||||
                        AdjustService.TrackIAPPurchase(usdPrice, productId);
 | 
					                    Analytics.SubPurchase(usdPrice, productId);
 | 
				
			||||||
                        Analytics.IAPPurchase(usdPrice, productId);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    else if (orderType == 1)
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        AdjustService.TrackSubPurchase(usdPrice, productId);
 | 
					 | 
				
			||||||
                        Analytics.SubPurchase(usdPrice, productId);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch (Exception ex)
 | 
					            catch (Exception ex)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,44 +1,31 @@
 | 
				
			||||||
using System;
 | 
					 | 
				
			||||||
using System.Text;
 | 
					 | 
				
			||||||
using Guru.LitJson;
 | 
					 | 
				
			||||||
using UnityEngine;
 | 
					 | 
				
			||||||
using UnityEngine.Networking;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Guru
 | 
					namespace Guru
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    using System;
 | 
				
			||||||
 | 
					    using System.Text;
 | 
				
			||||||
 | 
					    using UnityEngine;
 | 
				
			||||||
 | 
					    using UnityEngine.Networking;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    public class GoogleOrderRequest : RequestBase
 | 
					    public class GoogleOrderRequest : RequestBase
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public int orderType; // 订单类型,可选值:0:IAP订单 1: 订阅订单
 | 
					 | 
				
			||||||
        public string productId;
 | 
					 | 
				
			||||||
        public string subscriptionId;
 | 
					 | 
				
			||||||
        public string token;
 | 
					        public string token;
 | 
				
			||||||
        public string packageName;
 | 
					 | 
				
			||||||
        public int level;
 | 
					 | 
				
			||||||
        public string basePlanId;
 | 
					 | 
				
			||||||
        public string offerId;
 | 
					 | 
				
			||||||
        public GoogleOrderData orderData;
 | 
					        public GoogleOrderData orderData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public GoogleOrderRequest(){}
 | 
					        public GoogleOrderRequest(){}
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        public GoogleOrderRequest(int orderType, string productId, string subscriptionId, 
 | 
					        public GoogleOrderRequest(int orderType, string productId, string subscriptionId, string token, string orderId, 
 | 
				
			||||||
            string token, int level, string offerId = "",  string basePlanId = "")
 | 
					            string date, int level, string offerId = "",  string basePlanId = "")
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            this.orderType = orderType;
 | 
					 | 
				
			||||||
            this.packageName = Application.identifier;
 | 
					 | 
				
			||||||
            this.productId = productId;
 | 
					 | 
				
			||||||
            this.subscriptionId = subscriptionId;
 | 
					 | 
				
			||||||
            this.token = token;
 | 
					            this.token = token;
 | 
				
			||||||
            this.level = level;
 | 
					            orderData = new GoogleOrderData(orderType, productId, token, orderId, date, level, offerId, basePlanId);
 | 
				
			||||||
            orderData = new GoogleOrderData(orderType, productId, subscriptionId, token, level, offerId, basePlanId);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        protected override string RequestURL => IPMConfig.IPM_URL + "order/api/v1/orders/android";
 | 
					        protected override string RequestURL => IPMConfig.IPM_URL + "order/api/v1/orders/android";
 | 
				
			||||||
        protected override UnityWebRequest CreateRequest()
 | 
					        protected override UnityWebRequest CreateRequest()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            GoogleOrderData googleOrderData = orderData;
 | 
					            this.Log($"send orderData:{orderData}"); 
 | 
				
			||||||
            this.Log($"send orderData:{googleOrderData}"); 
 | 
					 | 
				
			||||||
            var request = new UnityWebRequest(RequestURL, "POST");
 | 
					            var request = new UnityWebRequest(RequestURL, "POST");
 | 
				
			||||||
            request.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(JsonMapper.ToJson(googleOrderData)));
 | 
					            request.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(orderData.ToJson()));
 | 
				
			||||||
            request.downloadHandler = new DownloadHandlerBuffer();
 | 
					            request.downloadHandler = new DownloadHandlerBuffer();
 | 
				
			||||||
            request.SetRequestHeader(IPMConfig.Header_Param_ContentType, IPMConfig.Header_Value_ContentType);
 | 
					            request.SetRequestHeader(IPMConfig.Header_Param_ContentType, IPMConfig.Header_Value_ContentType);
 | 
				
			||||||
            request.SetRequestHeader(IPMConfig.Header_Param_APPID, IPMConfig.IPM_X_APP_ID);
 | 
					            request.SetRequestHeader(IPMConfig.Header_Param_APPID, IPMConfig.IPM_X_APP_ID);
 | 
				
			||||||
| 
						 | 
					@ -56,24 +43,15 @@ namespace Guru
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    // Analytics.Tch001IAPRev(responseData.data.usdPrice);
 | 
					                    // Analytics.Tch001IAPRev(responseData.data.usdPrice);
 | 
				
			||||||
                    double usdPrice = responseData.data.usdPrice;
 | 
					                    double usdPrice = responseData.data.usdPrice;
 | 
				
			||||||
                    Analytics.Tch001IAPRev(usdPrice);
 | 
					                    string productId = orderData.RealProductId;
 | 
				
			||||||
                    Analytics.Tch02IAPRev(usdPrice);
 | 
					 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    string pid = "";
 | 
					                    Analytics.Tch001IAPRev(usdPrice, productId, orderData.orderId, orderData.OrderType(), orderData.payedDate); // TCH 001
 | 
				
			||||||
 | 
					                    // Analytics.Tch02IAPRev(usdPrice, productId, orderId, orderTypeString, timestamp);
 | 
				
			||||||
 | 
					                    Analytics.Tch02IAPRev(usdPrice); // TCH 020
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    if (!string.IsNullOrEmpty(productId))
 | 
					                    // Adjust Track IAP Purchase
 | 
				
			||||||
                    {
 | 
					                    AdjustService.TrackIAPPurchase(usdPrice, productId); // 上报 IAP 支付事件
 | 
				
			||||||
                        pid = productId;
 | 
					                    Analytics.IAPPurchase(usdPrice, productId);
 | 
				
			||||||
                        AdjustService.TrackIAPPurchase(usdPrice, productId); // 上报 IAP 支付事件
 | 
					 | 
				
			||||||
                        Analytics.IAPPurchase(usdPrice, pid);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (!string.IsNullOrEmpty(subscriptionId))
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        pid = subscriptionId;
 | 
					 | 
				
			||||||
                        AdjustService.TrackSubPurchase(usdPrice, productId); // 上报 订阅 支付事件
 | 
					 | 
				
			||||||
                        Analytics.SubPurchase(usdPrice, productId);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch (Exception ex)
 | 
					            catch (Exception ex)
 | 
				
			||||||
| 
						 | 
					@ -83,18 +61,13 @@ namespace Guru
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        public static GoogleOrderRequest Build(int orderType, string productId, string subscriptionId, 
 | 
					        public static GoogleOrderRequest Build(int orderType, string productId,
 | 
				
			||||||
            string token, int level, string offerId = "",  string basePlanId = "")
 | 
					            string token, string orderId, string date, int level, string offerId = "",  string basePlanId = "")
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var request = new GoogleOrderRequest()
 | 
					            var request = new GoogleOrderRequest()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                orderData = new GoogleOrderData(orderType, productId, subscriptionId, token, level, offerId, basePlanId),
 | 
					                orderData = new GoogleOrderData(orderType, productId, token, orderId, date, level, offerId, basePlanId),
 | 
				
			||||||
                orderType = orderType,
 | 
					 | 
				
			||||||
                packageName = Application.identifier,
 | 
					 | 
				
			||||||
                productId = productId,
 | 
					 | 
				
			||||||
                subscriptionId = subscriptionId,
 | 
					 | 
				
			||||||
                token = token,
 | 
					                token = token,
 | 
				
			||||||
                level = level,
 | 
					 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            return request;
 | 
					            return request;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -104,12 +77,7 @@ namespace Guru
 | 
				
			||||||
            var request = new GoogleOrderRequest()
 | 
					            var request = new GoogleOrderRequest()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                orderData = data,
 | 
					                orderData = data,
 | 
				
			||||||
                orderType = data.orderType,
 | 
					 | 
				
			||||||
                packageName = data.packageName,
 | 
					 | 
				
			||||||
                productId = data.productId,
 | 
					 | 
				
			||||||
                subscriptionId = data.subscriptionId,
 | 
					 | 
				
			||||||
                token = data.token,
 | 
					                token = data.token,
 | 
				
			||||||
                level = data.level,
 | 
					 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            return request;
 | 
					            return request;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -130,6 +130,7 @@ namespace Guru
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 带有校验器的初始化
 | 
					        /// 带有校验器的初始化
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="userId"></param>
 | 
				
			||||||
        /// <param name="googlePublicKey"></param>
 | 
					        /// <param name="googlePublicKey"></param>
 | 
				
			||||||
        /// <param name="appleRootCert"></param>
 | 
					        /// <param name="appleRootCert"></param>
 | 
				
			||||||
        /// <param name="showLog"></param>
 | 
					        /// <param name="showLog"></param>
 | 
				
			||||||
| 
						 | 
					@ -213,12 +214,12 @@ namespace Guru
 | 
				
			||||||
        /// <exception cref="NotImplementedException"></exception>
 | 
					        /// <exception cref="NotImplementedException"></exception>
 | 
				
			||||||
        public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
 | 
					        public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LogI($"--- IAP Initialized Success");
 | 
					 | 
				
			||||||
            _storeController = controller;
 | 
					            _storeController = controller;
 | 
				
			||||||
            _storeExtensionProvider = extensions;
 | 
					            _storeExtensionProvider = extensions;
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (string.IsNullOrEmpty(_userId)) _userId = IPMConfig.IPM_UID;
 | 
					            if (string.IsNullOrEmpty(_userId)) _userId = IPMConfig.IPM_UID;
 | 
				
			||||||
         
 | 
					         
 | 
				
			||||||
 | 
					            LogI($"--- IAP Initialized Success. With UID: {_userId}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if UNITY_IOS
 | 
					#if UNITY_IOS
 | 
				
			||||||
            _appleExtensions = extensions.GetExtension<IAppleExtensions>();
 | 
					            _appleExtensions = extensions.GetExtension<IAppleExtensions>();
 | 
				
			||||||
            _appleExtensions.SetApplicationUsername(_userId);  // SetUp UID
 | 
					            _appleExtensions.SetApplicationUsername(_userId);  // SetUp UID
 | 
				
			||||||
| 
						 | 
					@ -712,70 +713,88 @@ namespace Guru
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 支付结果上报
 | 
					        /// 支付结果上报
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        protected virtual void ReportPurchaseResult(PurchaseEventArgs args)
 | 
					        protected virtual bool ReportPurchaseResult(PurchaseEventArgs args)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            int blevel = GetBLevel();
 | 
					            // 验证器判定
 | 
				
			||||||
            int orderType = args.purchasedProduct.definition.type == ProductType.Subscription ? 1 : 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Debug.Log($"############ ReportPurchaseResult: _validator:{_validator }");
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if (_validator == null)
 | 
					            if (_validator == null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // Debug.Log($"############ --- Validator is null");
 | 
					                // Debug.Log($"############ --- Validator is null");
 | 
				
			||||||
                LogE($"{Tag} --- Validator is null. Report Order failed.");
 | 
					                LogE($"{Tag} --- Validator is null. Report Order failed.");
 | 
				
			||||||
                Analytics.LogCrashlytics(new Exception($"IAPService can not report order because Validator is null!"));
 | 
					                Analytics.LogCrashlytics(new Exception($"IAPService can not report order because Validator is null!"));
 | 
				
			||||||
                return;
 | 
					                return false;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            int level = GetBLevel();
 | 
				
			||||||
            try
 | 
					            int orderType = args.purchasedProduct.definition.type == ProductType.Subscription ? 1 : 0;
 | 
				
			||||||
            {
 | 
					            string productId = args.purchasedProduct.definition.id;
 | 
				
			||||||
                // ----- 支付后的b_level上报逻辑 
 | 
					            string appleReceiptString = "";
 | 
				
			||||||
                LogI($"--- Report b_level:[{blevel}] with product id:{args.purchasedProduct.definition.id} ");
 | 
					            // ----- 支付后的b_level上报逻辑 
 | 
				
			||||||
 | 
					            LogI($"--- Report b_level:[{level}] with product id:{args.purchasedProduct.definition.id} ");
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
#if UNITY_EDITOR
 | 
					#if UNITY_EDITOR
 | 
				
			||||||
                // Editor 不做上报逻辑
 | 
					            // // Editor 不做上报逻辑
 | 
				
			||||||
#elif UNITY_ANDROID
 | 
					            LogI($"--- Editor Validate Success. But Editor can't report order.");
 | 
				
			||||||
                // Android 订单验证, 上报打点信息
 | 
					            return true;
 | 
				
			||||||
                var result = _validator.Validate(args.purchasedProduct.receipt);
 | 
					 | 
				
			||||||
                string productID = orderType == 0 ? args.purchasedProduct.definition.id : "";
 | 
					 | 
				
			||||||
                string subscriptionID = orderType == 1 ? args.purchasedProduct.definition.id : "";
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                LogI($"{Tag} --- Report Android IAP Order -> orderType:{orderType}  productID:{productID}  blevel:{blevel}");
 | 
					 | 
				
			||||||
                foreach (var productReceipt in result)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    if (productReceipt is GooglePlayReceipt google)
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        Debug.Log($"{Tag} --- Report Android IAP Order -> orderType:{orderType}  productID:{productID}  blevel:{blevel}");
 | 
					 | 
				
			||||||
                        // new GoogleOrderRequest(orderType, productID, subscriptionID, google.purchaseToken, blevel).SetTimeOut(5).Send();
 | 
					 | 
				
			||||||
                        ReportGoogleOrder(orderType, productID, subscriptionID, google.purchaseToken, blevel);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
#elif UNITY_IOS
 | 
					 | 
				
			||||||
                // iOS 订单验证, 上报打点信息
 | 
					 | 
				
			||||||
                var jsonData = JsonConvert.DeserializeObject<JObject>(args.purchasedProduct.receipt);
 | 
					 | 
				
			||||||
                if (jsonData.TryGetValue("Payload", out var receipt))
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    ReportAppleOrder(orderType, args.purchasedProduct.definition.id, receipt.ToString(),blevel);
 | 
					 | 
				
			||||||
                    Debug.Log($"{Tag} --- Report iOS IAP Order -> orderType:{orderType}  productID:{args.purchasedProduct.definition.id}  blevel:{blevel}");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                // string receipt = jsonData["Payload"].ToString();
 | 
					 | 
				
			||||||
                // if (HasReceipt(receipt))
 | 
					 | 
				
			||||||
                // {
 | 
					 | 
				
			||||||
                //     Debug.Log($"[IAP] Receipt has already reported: {receipt}");
 | 
					 | 
				
			||||||
                //     return;
 | 
					 | 
				
			||||||
                // }
 | 
					 | 
				
			||||||
                // AddReceipt(receipt);
 | 
					 | 
				
			||||||
                // new AppleOrderRequest(orderType, args.purchasedProduct.definition.id, receipt,blevel).Send();
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
            }
 | 
					            
 | 
				
			||||||
            catch (Exception e)
 | 
					            IPurchaseReceipt[] allReceipts = null;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                LogE($" [IAPManager.RevenueUpload] got Exception: {e.Message}");
 | 
					#if UNITY_IOS
 | 
				
			||||||
                Analytics.LogCrashlytics(new Exception($"[IAP] Unity report purchase data with b_level={blevel} got error: {e.Message}"));
 | 
					                // ---- iOS 订单验证, 上报打点信息 ----
 | 
				
			||||||
 | 
					                var jsonData = JsonConvert.DeserializeObject<JObject>(args.purchasedProduct.receipt);
 | 
				
			||||||
 | 
					                if (jsonData != null && jsonData.TryGetValue("Payload", out var recp))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    appleReceiptString = recp.ToString();
 | 
				
			||||||
 | 
					                    LogI($"--- [{productId}] iOS receipt: {appleReceiptString}");      
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					                allReceipts = _validator.Validate(args.purchasedProduct.receipt);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                // ---- Android 订单验证, 上报打点信息 ---- 
 | 
				
			||||||
 | 
					                string offerId = "";
 | 
				
			||||||
 | 
					                string basePlanId = "";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                foreach (var receipt in allReceipts)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (receipt == null) continue;
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    if (receipt is GooglePlayReceipt googleReceipt)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        ReportGoogleOrder(orderType, 
 | 
				
			||||||
 | 
					                            googleReceipt.productID,
 | 
				
			||||||
 | 
					                            googleReceipt.purchaseToken,
 | 
				
			||||||
 | 
					                            googleReceipt.orderID,
 | 
				
			||||||
 | 
					                            googleReceipt.purchaseDate, 
 | 
				
			||||||
 | 
					                            level, offerId,  basePlanId);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else if (receipt is AppleInAppPurchaseReceipt appleReceipt)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        ReportAppleOrder(orderType, 
 | 
				
			||||||
 | 
					                            appleReceipt.productID,
 | 
				
			||||||
 | 
					                            appleReceiptString,
 | 
				
			||||||
 | 
					                            appleReceipt.transactionID,
 | 
				
			||||||
 | 
					                            appleReceipt.purchaseDate, level);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        string exmsg = $"--- [{productId}] :: Unknown Receipt Type: {receipt.GetType()} can't report order.";
 | 
				
			||||||
 | 
					                        Analytics.LogCrashlytics(exmsg);
 | 
				
			||||||
 | 
					                        LogE(exmsg);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                LogE($" [IAPManager.RevenueUpload] got Exception: {ex.Message}");
 | 
				
			||||||
 | 
					                Analytics.LogCrashlytics(new Exception($"[IAP] Unity report purchase data with b_level={level} got error: {ex.Message}"));
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            LogI("--- All Receipt is valid ---");
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
| 
						 | 
					@ -912,13 +931,16 @@ namespace Guru
 | 
				
			||||||
        /// <param name="productId"></param>
 | 
					        /// <param name="productId"></param>
 | 
				
			||||||
        /// <param name="subscriptionId"></param>
 | 
					        /// <param name="subscriptionId"></param>
 | 
				
			||||||
        /// <param name="token"></param>
 | 
					        /// <param name="token"></param>
 | 
				
			||||||
 | 
					        /// <param name="date"></param>
 | 
				
			||||||
        /// <param name="level"></param>
 | 
					        /// <param name="level"></param>
 | 
				
			||||||
        /// <param name="offerId"></param>
 | 
					        /// <param name="offerId"></param>
 | 
				
			||||||
        /// <param name="basePlanId"></param>
 | 
					        /// <param name="basePlanId"></param>
 | 
				
			||||||
        private void ReportGoogleOrder(int orderType, string productId, string subscriptionId, string token, int level,
 | 
					        /// <param name="orderId"></param>
 | 
				
			||||||
            string offerId = "", string basePlanId = "")
 | 
					        private void ReportGoogleOrder(int orderType, string productId, string token, 
 | 
				
			||||||
 | 
					            string orderId, DateTime date, int level, string offerId = "", string basePlanId = "")
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var request = GoogleOrderRequest.Build(orderType, productId, subscriptionId, token, level, offerId, basePlanId);
 | 
					            var payedDate = TimeUtil.GetTimeStampString(date);
 | 
				
			||||||
 | 
					            var request = GoogleOrderRequest.Build(orderType, productId, token, orderId, payedDate, level, offerId, basePlanId);
 | 
				
			||||||
            ReportNextOrder(request);
 | 
					            ReportNextOrder(request);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        private void ReportGoogleOrder(GoogleOrderData data)
 | 
					        private void ReportGoogleOrder(GoogleOrderData data)
 | 
				
			||||||
| 
						 | 
					@ -927,9 +949,22 @@ namespace Guru
 | 
				
			||||||
            ReportNextOrder(request);
 | 
					            ReportNextOrder(request);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        private void ReportAppleOrder(int orderType, string productId, string receipt, int level)
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 上报 Apple Order Request
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="orderType"></param>
 | 
				
			||||||
 | 
					        /// <param name="productId"></param>
 | 
				
			||||||
 | 
					        /// <param name="receipt"></param>
 | 
				
			||||||
 | 
					        /// <param name="orderId"></param>
 | 
				
			||||||
 | 
					        /// <param name="date"></param>
 | 
				
			||||||
 | 
					        /// <param name="level"></param>
 | 
				
			||||||
 | 
					        /// <param name="offerId"></param>
 | 
				
			||||||
 | 
					        /// <param name="basePlanId"></param>
 | 
				
			||||||
 | 
					        private void ReportAppleOrder(int orderType, string productId, string receipt, 
 | 
				
			||||||
 | 
					            string orderId, DateTime date,int level, string offerId = "", string basePlanId = "")
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var request = AppleOrderRequest.Build(orderType, productId, receipt, level);
 | 
					            var payedDate = TimeUtil.GetTimeStampString(date);
 | 
				
			||||||
 | 
					            var request = AppleOrderRequest.Build(orderType, productId, receipt, orderId, payedDate, level);
 | 
				
			||||||
            ReportNextOrder(request);
 | 
					            ReportNextOrder(request);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
| 
						 | 
					@ -968,26 +1003,26 @@ namespace Guru
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                GoogleOrderRequest go = request as GoogleOrderRequest;
 | 
					                GoogleOrderRequest googleReq = request as GoogleOrderRequest;
 | 
				
			||||||
                AppleOrderRequest ao = request as AppleOrderRequest;
 | 
					                AppleOrderRequest appReq = request as AppleOrderRequest;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
                if (go != null)
 | 
					                if (googleReq != null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (_model.IsTokenExists(go.token))
 | 
					                    if (_model.IsTokenExists(googleReq.token))
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        OnSendNextOrder(); // 跳过上报过的 Google 订单
 | 
					                        OnSendNextOrder(); // 跳过上报过的 Google 订单
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    _model.AddGoogleOrder(go.orderData); // 缓存当前 orderData 等待上报后再消除 
 | 
					                    _model.AddGoogleOrder(googleReq.orderData); // 缓存当前 orderData 等待上报后再消除 
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if( ao != null)
 | 
					                else if( appReq != null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (_model.IsReceiptExist(ao.receipt))
 | 
					                    if (_model.IsReceiptExist(appReq.receipt))
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        OnSendNextOrder(); // 跳过上报过的 Apple 订单
 | 
					                        OnSendNextOrder(); // 跳过上报过的 Apple 订单
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    _model.AddAppleOrder(ao.orderData); // 缓存当前 orderData 等待上报后再消除 
 | 
					                    _model.AddAppleOrder(appReq.orderData); // 缓存当前 orderData 等待上报后再消除 
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                request.SetTimeOut(OrderRequestTimeout)
 | 
					                request.SetTimeOut(OrderRequestTimeout)
 | 
				
			||||||
| 
						 | 
					@ -995,28 +1030,28 @@ namespace Guru
 | 
				
			||||||
                    .SetSuccessCallBack(() =>
 | 
					                    .SetSuccessCallBack(() =>
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        //---------------- Success ------------------------
 | 
					                        //---------------- Success ------------------------
 | 
				
			||||||
                        if (go != null)
 | 
					                        if (googleReq != null)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            _model.AddToken(go.token); // 记录当前的 Google 订单
 | 
					                            _model.AddToken(googleReq.token); // 记录当前的 Google 订单
 | 
				
			||||||
                            _model.RemoveGoogleOrder(go.orderData); // 成功后清除缓存 orderData
 | 
					                            _model.RemoveGoogleOrder(googleReq.orderData); // 成功后清除缓存 orderData
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        else if (ao != null)
 | 
					                        else if (appReq != null)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            _model.AddReceipt(ao.receipt); // 记录当前的 Apple 订单
 | 
					                            _model.AddReceipt(appReq.receipt); // 记录当前的 Apple 订单
 | 
				
			||||||
                            _model.RemoveAppleOrder(ao.orderData); // 成功后清除缓存 orderData
 | 
					                            _model.RemoveAppleOrder(appReq.orderData); // 成功后清除缓存 orderData
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        OnSendNextOrder(); // NEXT Order
 | 
					                        OnSendNextOrder(); // NEXT Order
 | 
				
			||||||
                    })
 | 
					                    })
 | 
				
			||||||
                    .SetFailCallBack(() =>
 | 
					                    .SetFailCallBack(() =>
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        //---------------- Fail ------------------------
 | 
					                        //---------------- Fail ------------------------
 | 
				
			||||||
                        if (go != null)
 | 
					                        if (googleReq != null)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            ReportGoogleOrderLost(go.orderData); // 上报 Google 订单缺失打点
 | 
					                            ReportGoogleOrderLost(googleReq.orderData); // 上报 Google 订单缺失打点
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        else if (ao != null)
 | 
					                        else if (appReq != null)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            ReportAppleOrderLost(ao.orderData);  // 上报 Apple 订单缺失打点
 | 
					                            ReportAppleOrderLost(appReq.orderData);  // 上报 Apple 订单缺失打点
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        OnSendNextOrder(); // NEXT Order
 | 
					                        OnSendNextOrder(); // NEXT Order
 | 
				
			||||||
                    })
 | 
					                    })
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,7 @@
 | 
				
			||||||
  "description": "Guru SDK core for Unity developers",
 | 
					  "description": "Guru SDK core for Unity developers",
 | 
				
			||||||
  "unity": "2021.3",
 | 
					  "unity": "2021.3",
 | 
				
			||||||
  "author":{
 | 
					  "author":{
 | 
				
			||||||
    "name": "Guru Games"
 | 
					    "name": "Guru Game"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "license": "MIT",
 | 
					  "license": "MIT",
 | 
				
			||||||
  "category": ["game","tool","development", "Guru"],
 | 
					  "category": ["game","tool","development", "Guru"],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue