diff --git a/Runtime/GuruCore/Runtime/IPM/Scripts/RequestData/AppleOrderData.cs b/Runtime/GuruCore/Runtime/IPM/Scripts/RequestData/AppleOrderData.cs index d3deb6d..55d0aac 100644 --- a/Runtime/GuruCore/Runtime/IPM/Scripts/RequestData/AppleOrderData.cs +++ b/Runtime/GuruCore/Runtime/IPM/Scripts/RequestData/AppleOrderData.cs @@ -1,13 +1,14 @@ - namespace Guru { using System; using System.Collections.Generic; + using Newtonsoft.Json; [Serializable] public class AppleOrderData { + public string guid; public int orderType; public string productId; public string bundleId; @@ -19,6 +20,7 @@ namespace Guru public AppleOrderData(int orderType, string productId, string receipt, int level) { + guid = Guid.NewGuid().ToString(); this.orderType = orderType; this.productId = productId; this.receipt = receipt; @@ -29,9 +31,21 @@ namespace Guru eventConfig = EventConfig.Build(); } + + public bool Equals(AppleOrderData other) + { + if (string.IsNullOrEmpty(guid)) guid = Guid.NewGuid().ToString(); + return guid.Equals(other.guid); + } + + + public string GetId() => productId; + public override string ToString() { return $"{nameof(orderType)}: {orderType}, {nameof(productId)}: {productId}, {nameof(bundleId)}: {bundleId}, {nameof(receipt)}: {receipt}, {nameof(country)}: {country}"; } + + public string ToJson() => JsonConvert.SerializeObject(this); } } \ No newline at end of file diff --git a/Runtime/GuruCore/Runtime/IPM/Scripts/RequestData/GoogleOrderData.cs b/Runtime/GuruCore/Runtime/IPM/Scripts/RequestData/GoogleOrderData.cs index 7aefa26..6d3acda 100644 --- a/Runtime/GuruCore/Runtime/IPM/Scripts/RequestData/GoogleOrderData.cs +++ b/Runtime/GuruCore/Runtime/IPM/Scripts/RequestData/GoogleOrderData.cs @@ -1,11 +1,14 @@ -using System; -using System.Collections.Generic; namespace Guru { + using System; + using System.Collections.Generic; + using Newtonsoft.Json; + [Serializable] public class GoogleOrderData { + public string guid; public int orderType; // 订单类型,可选值:0:IAP订单 1: 订阅订单 public string packageName; //应用包名 public string productId = ""; // 商品ID 当orderType=0时,传递该参数 @@ -13,13 +16,14 @@ namespace Guru public string token; // 应用商店里面的购买token public int level; public Dictionary userInfo; // 当前用户信息。目前包含: level: 用户属性中的"b_level"的值 - public string basePlanId; // 订阅商品的planId - public string offerId; // 订阅商品的offerId + public string basePlanId = ""; // 订阅商品的planId + public string offerId = ""; // 订阅商品的offerId public EventConfig eventConfig; // 事件打点所需信息 public GoogleOrderData(int orderType, string productId, string subscriptionId, string token, int level, string offerId = "", string basePlanId = "") { + guid = Guid.NewGuid().ToString(); this.orderType = orderType; this.packageName = GuruSettings.Instance.GameIdentifier; this.productId = productId; @@ -31,31 +35,18 @@ namespace Guru userInfo = new Dictionary { ["level"] = level }; eventConfig = EventConfig.Build(); } - - public GoogleOrderData(ProductInfo productInfo, string token, int level, - string offerId = "", string basePlanId = "") + + public bool Equals(GoogleOrderData other) { - this.orderType = productInfo.Type == "subscription" ? 1 : 0; - if (orderType == 1) - { - subscriptionId = productInfo.Id; - } - else - { - productId = productInfo.Id; - } - this.packageName = GuruSettings.Instance.GameIdentifier; - this.token = token; - this.offerId = offerId; - this.basePlanId = basePlanId; - userInfo = new Dictionary { ["level"] = level }; - eventConfig = EventConfig.Build(); + if (string.IsNullOrEmpty(guid)) guid = Guid.NewGuid().ToString(); + return guid == other.guid; } - - + public override string ToString() { return $"{nameof(orderType)}: {orderType}, {nameof(packageName)}: {packageName}, {nameof(productId)}: {productId}, {nameof(subscriptionId)}: {subscriptionId}, {nameof(token)}: {token}"; } + + public string ToJson() => JsonConvert.SerializeObject(this); } } \ No newline at end of file diff --git a/Runtime/GuruCore/Runtime/IPM/Scripts/RequestData/IAPOrderData.cs b/Runtime/GuruCore/Runtime/IPM/Scripts/RequestData/IAPOrderData.cs deleted file mode 100644 index e9666ef..0000000 --- a/Runtime/GuruCore/Runtime/IPM/Scripts/RequestData/IAPOrderData.cs +++ /dev/null @@ -1,74 +0,0 @@ -using UnityEngine; - -namespace Guru -{ - using System; - using System.Collections.Generic; - - - [Serializable] - public class IAPOrderData - { - public string platform; // 平台类型 android 或 ios - public int orderType = 0; // 订单类型,可选值:0:IAP订单 1: 订阅订单 - public string productId = ""; // 商品ID 当orderType=0时,传递该参数 - public string subscriptionId = ""; // 订阅ID // 当orderType=1时,传递该参数 - public string receipt = ""; // 应用商店里面的购买token - public int level = 0; // 用户属性中的"b_level"的值 - public string packageName = ""; // 应用包名 - public string offerId = ""; // 订阅商品的offerId (Android) - public string basePlanId = ""; // 订阅商品的planId (Android) - - public Dictionary userInfo; - public EventConfig eventConfig; - - - /// - /// 构建订单数据 - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static IAPOrderData Build(string platform, int orderType = 0, string receipt= "", int level = 0, - string productId = "", string subscriptionId = "", - string offerId = "", string basePlanId = "") - { - IAPOrderData orderData = new IAPOrderData - { - platform = platform, - orderType = orderType, - productId = productId, - subscriptionId = subscriptionId, - receipt = receipt, - level = level, - packageName = Application.identifier, - offerId = offerId, - basePlanId = basePlanId, - userInfo = new Dictionary() - { - {"level", level} - }, - eventConfig = new EventConfig() - { - firebaseAppInstanceId = IPMConfig.FIREBASE_ID, - idfa = IPMConfig.ADJUST_IDFA, - adid = IPMConfig.ADJUST_ID, - gpsAdid = IPMConfig.ADJUST_ADID, - } - }; - return orderData; - } - - - } - - - - -} \ No newline at end of file diff --git a/Runtime/GuruCore/Runtime/IPM/Scripts/RequestData/IAPOrderData.cs.meta b/Runtime/GuruCore/Runtime/IPM/Scripts/RequestData/IAPOrderData.cs.meta deleted file mode 100644 index d657a9b..0000000 --- a/Runtime/GuruCore/Runtime/IPM/Scripts/RequestData/IAPOrderData.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 9e4562ba60204b85bca8777b771c73e5 -timeCreated: 1710410036 \ No newline at end of file diff --git a/Runtime/GuruCore/Runtime/IPM/Scripts/Requests/AppleOrderRequest.cs b/Runtime/GuruCore/Runtime/IPM/Scripts/Requests/AppleOrderRequest.cs index ea3f372..8bd802f 100644 --- a/Runtime/GuruCore/Runtime/IPM/Scripts/Requests/AppleOrderRequest.cs +++ b/Runtime/GuruCore/Runtime/IPM/Scripts/Requests/AppleOrderRequest.cs @@ -1,10 +1,11 @@ -using System.Text; -using Guru.LitJson; -using UnityEngine; -using UnityEngine.Networking; + namespace Guru { + using System.Text; + using UnityEngine; + using UnityEngine.Networking; + public class AppleOrderRequest : RequestBase { public int orderType; @@ -22,6 +23,7 @@ namespace Guru productId = productId, receipt = receipt, level = level, + orderData = new AppleOrderData(orderType, productId, receipt, level), }; return request; } @@ -30,15 +32,13 @@ namespace Guru { return Build(orderData.orderType, orderData.productId, orderData.receipt, orderData.level); } - - - + protected override string RequestURL => IPMConfig.IPM_URL + "order/api/v1/orders/ios"; protected override UnityWebRequest CreateRequest() { this.Log($"send orderData:{orderData}"); var request = new UnityWebRequest(RequestURL, "POST"); - request.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(JsonMapper.ToJson(orderData))); + request.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(orderData.ToJson())); request.downloadHandler = new DownloadHandlerBuffer(); request.SetRequestHeader(IPMConfig.Header_Param_APPID, IPMConfig.IPM_X_APP_ID); request.SetRequestHeader(IPMConfig.Header_Param_UID, IPMConfig.IPM_UID); diff --git a/Runtime/GuruCore/Runtime/IPM/Scripts/Requests/GoogleOrderRequest.cs b/Runtime/GuruCore/Runtime/IPM/Scripts/Requests/GoogleOrderRequest.cs index 0aa0b40..541a0b1 100644 --- a/Runtime/GuruCore/Runtime/IPM/Scripts/Requests/GoogleOrderRequest.cs +++ b/Runtime/GuruCore/Runtime/IPM/Scripts/Requests/GoogleOrderRequest.cs @@ -28,7 +28,6 @@ namespace Guru this.subscriptionId = subscriptionId; this.token = token; this.level = level; - orderData = new GoogleOrderData(orderType, productId, subscriptionId, token, level, offerId, basePlanId); } diff --git a/Runtime/GuruIAP/Runtime/Code/IAPModel.cs b/Runtime/GuruIAP/Runtime/Code/IAPModel.cs index 3cb2193..27f5cdb 100644 --- a/Runtime/GuruIAP/Runtime/Code/IAPModel.cs +++ b/Runtime/GuruIAP/Runtime/Code/IAPModel.cs @@ -114,14 +114,38 @@ namespace Guru public void AddGoogleOrder(GoogleOrderData order) { + if (HasGoogleOrder(order)) return; googleOrders.Add(order); Save(); } - - public void RemoveGoogleOrder(GoogleOrderData order) + + public bool HasGoogleOrder(GoogleOrderData order) { - googleOrders.Remove(order); - Save(); + if(googleOrders == null || googleOrders.Count == 0) return false; + for (int i = 0; i < googleOrders.Count; i++) + { + var o = googleOrders[i]; + if (o.Equals(order)) + { + return true; + } + } + return false; + } + + public bool RemoveGoogleOrder(GoogleOrderData order) + { + for (int i = 0; i < googleOrders.Count; i++) + { + var o = googleOrders[i]; + if (o.Equals(order)) + { + googleOrders.RemoveAt(i); + Save(); + return true; + } + } + return false; } public void ClearGoogleOrders() { @@ -131,14 +155,38 @@ namespace Guru public void AddAppleOrder(AppleOrderData order) { + if (HasAppleOrder(order)) return; appleOrders.Add(order); Save(); } - public void RemoveAppleOrder(AppleOrderData order) + public bool HasAppleOrder(AppleOrderData order) { - appleOrders.Remove(order); - Save(); + if(appleOrders == null || appleOrders.Count == 0) return false; + for (int i = 0; i < appleOrders.Count; i++) + { + var o = appleOrders[i]; + if (o.Equals(order)) + { + return true; + } + } + return false; + } + + public bool RemoveAppleOrder(AppleOrderData order) + { + for (int i = 0; i < appleOrders.Count; i++) + { + var o = appleOrders[i]; + if (o.Equals(order)) + { + googleOrders.RemoveAt(i); + Save(); + return true; + } + } + return false; } public void ClearAppleOrders() @@ -147,8 +195,24 @@ namespace Guru Save(); } #endregion + + #region Params + + + public int PurchaseCount + { + get => buyCount; + set + { + buyCount = value; + Save(); + } + } + + + #endregion } diff --git a/Runtime/GuruIAP/Runtime/Code/IAPServiceBase.cs b/Runtime/GuruIAP/Runtime/Code/IAPServiceBase.cs index f42cd65..aafbb9f 100644 --- a/Runtime/GuruIAP/Runtime/Code/IAPServiceBase.cs +++ b/Runtime/GuruIAP/Runtime/Code/IAPServiceBase.cs @@ -43,8 +43,8 @@ namespace Guru /// public int PurchaseCount { - get => PlayerPrefs.GetInt(nameof(PurchaseCount), 0); - set => PlayerPrefs.SetInt(nameof(PurchaseCount), value); + get => _model.PurchaseCount; + set => _model.PurchaseCount = value; } /// @@ -714,7 +714,7 @@ namespace Guru #if UNITY_EDITOR // Editor 不做上报逻辑 -#elif UNITY_ANDROID +// #elif UNITY_ANDROID // Android 订单验证, 上报打点信息 var result = _validator.Validate(args.purchasedProduct.receipt); string productID = orderType == 0 ? args.purchasedProduct.definition.id : ""; @@ -730,16 +730,16 @@ namespace Guru ReportGoogleOrder(orderType, productID, subscriptionID, google.purchaseToken, blevel); } } -#elif UNITY_IOS +// #elif UNITY_IOS // iOS 订单验证, 上报打点信息 var jsonData = JsonMapper.ToObject(args.purchasedProduct.receipt); string receipt = jsonData["Payload"].ToString(); - if (HasReceipt(receipt)) - { - Debug.Log($"[IAP] Receipt has already reported: {receipt}"); - return; - } - AddReceipt(receipt); + // if (HasReceipt(receipt)) + // { + // Debug.Log($"[IAP] Receipt has already reported: {receipt}"); + // return; + // } + // AddReceipt(receipt); // new AppleOrderRequest(orderType, args.purchasedProduct.definition.id, receipt,blevel).Send(); ReportAppleOrder(orderType, args.purchasedProduct.definition.id, receipt,blevel); Debug.Log($"{Tag} --- Report iOS IAP Order -> orderType:{orderType} productID:{args.purchasedProduct.definition.id} blevel:{blevel}"); @@ -836,15 +836,18 @@ namespace Guru // 启动时查询 if(_orderRequests == null) _orderRequests = new Queue(20); -#if UNITY_ANDROID - + +// #if UNITY_EDITOR +// Debug.Log($"----- IAP Model init -----"); +// #elif UNITY_ANDROID + +#if UNITY_ANDROID if (_model.HasUnreportedGoogleOrder) { foreach (var o in _model.googleOrders) { ReportGoogleOrder(o); } - _model.ClearGoogleOrders(); } #elif UNITY_IOS if (_model.HasUnreportedAppleOrder) @@ -853,7 +856,6 @@ namespace Guru { ReportAppleOrder(o); } - _model.ClearAppleOrders(); } #endif @@ -861,10 +863,6 @@ namespace Guru } - - - - #endregion #region 订单上报队列 @@ -949,11 +947,14 @@ namespace Guru if (go != null) { _model.AddToken(go.token); + _model.RemoveGoogleOrder(go.orderData); } else if (ao != null) { _model.AddReceipt(ao.receipt); + _model.RemoveAppleOrder(ao.orderData); } + OnSendNextOrder(); }) .SetFailCallBack(() =>