fix:1、删除部分不用的资源代码。2、a面修复bug

This commit is contained in:
barry
2026-04-28 18:42:00 +08:00
parent 70d45d4705
commit cc12dffbaa
417 changed files with 36736 additions and 40575 deletions
-8
View File
@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: e75e79cc47ddbb8409cf3ea5f29211ce
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
-3
View File
@@ -1,3 +0,0 @@
# ApplePay
2025 年 05 月 24 日 V1.0.0 提交初始版本 applepay 模块,该模块功能依赖通用模块,网络模块和数据模块,请一起拉取
-7
View File
@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: f92f9691c788c414a82e03722722293e
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
-3
View File
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 10ce64fc727c4edeb97e73ad29ef5eab
timeCreated: 1747906541
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: f2da583c874f4b13acc3eb54eaf5a428
timeCreated: 1747996053
@@ -1,43 +0,0 @@
using Newtonsoft.Json;
namespace SGModule.ApplePay
{
public class ApplePayData
{
[JsonProperty("innerOrderId")]
public string innerOrderId;
[JsonProperty("amount")]
public int amount;
[JsonProperty("sku")]
public string sku;
[JsonProperty("currency")]
public string currency = "USD";
[JsonProperty("shopName")]
public string shopName;
[JsonProperty("type")]
public string type;
}
public class AppleCheckData
{
[JsonProperty("signedPayload")]
public string signedPayload;
[JsonProperty("innerOrderId")]
public string innerOrderId;
}
public class AppleSubscribeData
{
[JsonProperty("signedPayload")]
public string signedPayload;
[JsonProperty("sku")]
public string sku;
[JsonProperty("currency")]
public string currency;
[JsonProperty("amount")]
public int amount;
[JsonProperty("expires_time")]
public long expires_time;
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 9dcbc72e1537449aaea5b71d67e7bf85
timeCreated: 1747996070
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 69666ded8fdc4244a0d43d25f7831bca
timeCreated: 1747906570
@@ -1,18 +0,0 @@
namespace SGModule.ApplePay
{
public enum ApplePayBackType
{
/// <summary>
///创建支付订单
/// </summary>
Create,
/// <summary>
///验证支付订单
/// </summary>
Check,
/// <summary>
///取消支付订单
/// </summary>
Cancel,
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: e83ae38d5d0e4880836c55d708e7083c
timeCreated: 1747995062
@@ -1,905 +0,0 @@
using SGModule.Common.Base;
using System;
using System.Collections.Generic;
using RedHotRoast;
using SGModule.NetKit;
#if UNITY_IOS && UNITY_IAP
using System.Collections;
using DG.Tweening;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Purchasing;
namespace SGModule.ApplePay
{
public class ApplePayManager : SingletonMonoBehaviour<ApplePayManager>, IDetailedStoreListener
{
private IStoreController _storeController;
private static IExtensionProvider _extensionProvider;
private static IAppleExtensions _appleExtension;
private Action<string> _failedCallback;
private Action<ApplePayBackType, AppleResponseData> _successCallback;
private Dictionary<string, (string id, string type)> _products = new Dictionary<string, (string, string)>();
private ApplePayData _payData;
private string _packageName;
private float _lastPayAttemptTime;
private Dictionary<string, string> _innerData = new();
public void SendDebugToServer(string error, string stackTrace)
{
ErrorLogKit.Send("debug", error, stackTrace, SuperApplication.Instance.attribution);
}
private Dictionary<string, ProductConfig> _productConfigs = new Dictionary<string, ProductConfig>();
/// <summary>
/// 通过 ProductConfig 数组初始化商品
/// </summary>
public void InitProduct(List<ProductConfig> configs, string packageName, Action<ApplePayBackType, AppleResponseData> successCallback)
{
var module = StandardPurchasingModule.Instance();
ConfigurationBuilder builder = ConfigurationBuilder.Instance(module);
_successCallback = successCallback;
_packageName = packageName;
SendDebugToServer("[Apple pay] InitProduct 开始------", Environment.StackTrace);
try
{
foreach (var config in configs)
{
Debug.Log($"[Apple pay] InitProduct ------{config.sku} , {config.type} ");
if (Enum.TryParse<UnityEngine.Purchasing.ProductType>(config.type, true, out var productType))
{
_productConfigs.Add(config.sku, config);
builder.AddProduct(config.sku, productType);
}
else
{
SendDebugToServer($"无法解析 ProductType: {config.type}", Environment.StackTrace);
Debug.LogError($"无法解析 ProductType: {config.type}");
// 可根据需要处理默认类型或跳过该商品
}
}
SendDebugToServer("[Apple pay] InitProduct 结束------", Environment.StackTrace);
UnityPurchasing.Initialize(this, builder);
}
catch (Exception e)
{
SendDebugToServer($" 初始化商品 失败 InitProduct: {e.Message}", Environment.StackTrace);
Console.WriteLine(e);
throw;
}
Debug.Log($"[Apple pay] InitProduct -----2 ");
}
private void SetPayData(string sku)
{
var payData = GetPayData(sku);
_payData = payData;
}
private ApplePayData GetPayData(string sku)
{
if (_productConfigs.TryGetValue(sku, out var data))
{
Debug.Log($"[Apple pay] InitProduct ------{data.sku} , {data.type} ");
return new ApplePayData
{
sku = sku,
currency = "USD",
amount = (int)Math.Round(data.price * 100),
};
}
Debug.LogError($" set _payData error------_payData is null ");
return null;
}
private Coroutine _payDataCheckCoroutine;
/// <summary>
/// 启动_payData超时检测协程
/// </summary>
private void StartPayDataTimeoutCheck()
{
if (_payDataCheckCoroutine != null)
{
StopCoroutine(_payDataCheckCoroutine);
}
_payDataCheckCoroutine = StartCoroutine(PayDataTimeoutCheck());
}
/// <summary>
/// 检测_payData是否超时的协程
/// </summary>
private IEnumerator PayDataTimeoutCheck()
{
float startTime = Time.time;
float timeout = 60f; // 1分钟超时
while (Time.time - startTime < timeout)
{
// 如果_payData已经为null,停止检测
if (_payData == null)
{
yield break;
}
yield return null;
}
// 1分钟后检查,如果_payData仍然不为null,则设为null
if (_payData != null)
{
_innerData = null;
_payData = null;
Debug.Log("[Apple Pay] _payData超时,已自动设为null");
}
}
/// <summary>
/// 购买接口
/// </summary>
/// <param name="payData">购买需要的字段存放</param>
/// <param name="successCallback">成功回调(ApplePayBackType为订单返回的类型:具体看 ApplePayBackType 枚举),作用:用来打点</param>
/// <param name="failedCallback">失败回调 string为失败原因)</param>
public void Purchase(string sku, Action<ApplePayBackType, AppleResponseData> successCallback, Action<string> failedCallback)
{
Debug.Log($"[Apple Pay] Purchase: {JsonConvert.SerializeObject(_payData)}");
SendDebugToServer("[Apple pay] 购买 Purchase ------", Environment.StackTrace);
if (Time.time - _lastPayAttemptTime < 5)
{
failedCallback?.Invoke("Clicks are too frequent");
return;
}
_lastPayAttemptTime = Time.time;
Debug.Log($"[Apple Pay] Purchase-00---------{JsonConvert.SerializeObject(_payData)}");
if (_payData != null)
{
if (_payData.sku.Contains("sub"))//假如是订阅直接清理
{
_payData = null;
}
else
{
// 启动超时检测
StartPayDataTimeoutCheck();
return;
}
}
Debug.Log($"[Apple Pay] Purchase-1---------");
if (!IsInitialized())
{
failedCallback?.Invoke("Not Initialized");
return;
}
Debug.Log($"[Apple Pay] Purchase-2---------");
var product = _storeController.products.WithID(sku);
if (product == null || !product.availableToPurchase)
{
failedCallback?.Invoke("Either is not found or is not available for purchase");
return;
}
_successCallback = successCallback;
_failedCallback = failedCallback;
SetPayData(sku);
_storeController.InitiatePurchase(product);
Debug.Log($"[Apple Pay] Purchase-3---------");
if (_payData != null)
{
var payData = new ApplePayData
{
sku = sku,
currency = "USD",
amount = _payData.amount,
};
ApplePayNet.ApplePayCreate<ApplePayData>(payData, (response) =>
{
Debug.Log($"[Apple Pay] Purchase-4---------");
if (response.IsSuccess)
{
_successCallback?.Invoke(ApplePayBackType.Create, null);
if (_innerData == null) _innerData = new();
Debug.Log($"[Apple pay] Purchase--5-innerOrderId-------{response.Data.innerOrderId}");
if (_payData != null && response.Data.innerOrderId != null)
{
Debug.Log($"[Apple pay] Purchase-555555-innerOrderId");
_payData.innerOrderId = response.Data.innerOrderId;
_innerData[response.Data.innerOrderId] = sku;
SaveInnerIdData(_innerData);
}
}
// if (_payData != null) _payData.innerOrderId = response.Data.innerOrderId;
SendDebugToServer($"[Apple Pay] Purchase-5-------创建内部ID innerOrderId--{_payData.innerOrderId}", Environment.StackTrace);
Debug.Log($"[Apple Pay] Purchase-5-------innerOrderId--{_payData.innerOrderId}");
if (payData.sku.Contains("sub") && DataMgr.VipLevel.Value >= 1)
{
// PlayerPrefs.SetInt("need_getvip", 1);
DOVirtual.DelayedCall(10, () =>
{
GetVipHistory();
}).SetLoops(3);
}
});
}
}
public static void GetVipHistory()
{
// if (PlayerPrefs.GetInt("need_getvip", 1) == 0) return;
// PlayerPrefs.DeleteAll();
string orig_tx_id = PlayerPrefs.GetString("orig_tx_id", "");
HistoryObject obj_ = new HistoryObject() { id = orig_tx_id };
if (string.IsNullOrEmpty(orig_tx_id))
{
ApplePayNet.ApplePaySubscriptionHistory<List<SubscriptionList>>((response) =>
{
// Debug.Log(JsonConvert.SerializeObject(response.Data));
string tx_id_ = null;
for (int i = 0; i < response.Data.Count; i++)
{
PlayerPrefs.SetString("orig_tx_id", response.Data[i].orig_tx_id);
tx_id_ = response.Data[i].orig_tx_id;
}
if (!string.IsNullOrEmpty(tx_id_))
{
obj_.id = tx_id_;
SubscriptionCheck(obj_);
}
});
return;
}
else
{
SubscriptionCheck(obj_);
}
}
public static void SubscriptionCheck(HistoryObject obj_)
{
ApplePayNet.ApplePaySubscriptionCheck<SubscriptionList>(obj_, (response) =>
{
int vip_level = -1;
long end_time = 0;
if (response != null && response.Data != null)
{
Debug.Log(JsonConvert.SerializeObject(response.Data));
if (response.Data.renew_time > end_time)
{
end_time = response.Data.renew_time;
if (response.Data.renew_sku == PurchasingManager.GetPaySku(PayType.yearly_subscription))
{
vip_level = 3;
}
else if (response.Data.renew_sku == PurchasingManager.GetPaySku(PayType.monthly_subscription))
{
vip_level = 2;
}
else if (response.Data.renew_sku == PurchasingManager.GetPaySku(PayType.weekly_subscription))
{
vip_level = 1;
}
DataMgr.VipExpirationTime.Value = end_time;
if (DataMgr.VipLevel.Value != vip_level)
{
DataMgr.VipLevel.Value = vip_level;
GameDispatcher.Instance.Dispatch(GameMsg.BuyVip);
}
}
}
});
}
/// <summary>
/// IOS恢复内购
/// 会在删除应用后,第一次安装是自动恢复
/// </summary>
/// <param name="restoreCallback">恢复回调</param>
public void AppleRestore(Action<bool, string> restoreCallback)
{
if (!IsInitialized())
{
Debug.LogWarning("[ApplePay] IAppleExtensions 未初始化");
return;
}
Debug.Log("[ApplePay] 用户手动恢复购买");
_appleExtension.RestoreTransactions((success, error) =>
{
if (success)
{
Debug.Log("[Apple Pay] Restore Transactions 成功");
// 这里会触发 ProcessPurchase 回调
restoreCallback(true, error);
}
else
{
Debug.LogError($"[Apple Pay] Restore Transactions 失败: {error}");
// 可以提示用户重试
}
});
}
#region
private Dictionary<string, Product> _pendingProducts = new Dictionary<string, Product>();
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs purchaseEvent)
{
SendDebugToServer($"[Apple pay] 购买成功回调 Purchase ---{JsonConvert.SerializeObject(purchaseEvent.purchasedProduct)}---", Environment.StackTrace);
var product = purchaseEvent.purchasedProduct;
var productType = product.definition.type;
var sku = product.definition.id;
var receipt = product.receipt;
Debug.Log(
$" ProcessPurchase 1 Purchase: {JsonConvert.SerializeObject(purchaseEvent.purchasedProduct)}");
Debug.Log(
$" ProcessPurchase 1 receipt: {receipt}");
if (purchaseEvent is not { purchasedProduct: not null })
{
Debug.LogError("[Apple Pay] ProcessPurchase 2 : purchaseEvent 或 purchasedProduct 为 null");
return PurchaseProcessingResult.Complete;
}
Debug.Log($"购买商品类型: {productType}, SKU: {sku}");
if (productType == ProductType.NonConsumable)
{
Debug.Log(
$" 识别到非消耗性商品 ----{DataMgr.ApplePayTransactionID.Value.Contains(product.transactionID)}");
var innerdata = GetInnerIdData();
if (innerdata == null) // 重启情况
{
Debug.Log("innerdata----" + innerdata);
_successCallback(ApplePayBackType.Check, new AppleResponseData()
{
sku = sku
});
DataMgr.ApplePayTransactionID.Value.Add(product.transactionID);
return PurchaseProcessingResult.Complete;
}
Debug.Log("innerdata---2-");
if (DataMgr.ApplePayTransactionID.Value.Contains(product.transactionID))
{
return PurchaseProcessingResult.Complete;
}
DataMgr.ApplePayTransactionID.Value.Add(product.transactionID);
}
if (DataMgr.clearAllOrder.Value)
{
_innerData = null;
_payData = null;
// 保存更新后的数据
SaveApplePayData(null);
SaveInnerIdData(null);
return PurchaseProcessingResult.Complete;
}
string txId = product.transactionID;
_pendingProducts[txId] = product; // ✅ 安全暂存
if (productType == ProductType.Subscription)
{
SendDebugToServer($"[Apple pay] 购买商品类型 Purchase ---{productType}-{sku}--", Environment.StackTrace);
// 服务器验证
UploadReceiptForValidation(sku, product.transactionID, isSuccess =>
{
if (isSuccess)
{
var product_temp = FindPendingProductByTransactionId(purchaseEvent.purchasedProduct.transactionID);
// 验证成功后的逻辑
// 验证成功,完成购买
_storeController.ConfirmPendingPurchase(product_temp);
}
});
return PurchaseProcessingResult.Pending;
}
// 普通商品直接处理
HandlePurchaseSuccess(purchaseEvent, isSuccess =>
{
if (isSuccess)
{
var product_temp = FindPendingProductByTransactionId(purchaseEvent.purchasedProduct.transactionID);
var productType = product_temp.definition.type;
Debug.Log(
$"ConfirmPendingPurchase : {purchaseEvent.purchasedProduct.transactionID}, sku: {product_temp.definition.id}");
// 验证成功,完成购买
_storeController.ConfirmPendingPurchase(product_temp);
}
});
return PurchaseProcessingResult.Pending;
}
private Product FindPendingProductByTransactionId(string txId)
{
_pendingProducts.TryGetValue(txId, out var product);
_pendingProducts.Remove(txId); // ✅ 用完即删,避免内存泄漏
return product;
}
/// <summary>
/// 支付测试代码
/// </summary>
/// <param name="type"></param>
/// <param name="sku"></param>
/// <param name="transactionID"></param>
public void ApplePayTest(ProductType type, string sku, string transactionID, Action<ApplePayBackType, AppleResponseData> successCallback)
{
SetPayData(sku);
Debug.Log($"[ApplePay] 测试支付 type: {type}, sku: {sku}, transactionID: {transactionID}");
_successCallback = successCallback;
if (type == ProductType.Subscription)
{
// 服务器验证
UploadReceiptForValidation(sku, transactionID, isSuccess =>
{
if (isSuccess)
{
Debug.Log("订阅商品验证成功");
}
});
return;
}
if (type == ProductType.NonConsumable)
{
Debug.Log(
$" 识别到非消耗性商品 ----{DataMgr.ApplePayTransactionID.Value.Contains(transactionID)}");
if (DataMgr.ApplePayTransactionID.Value.Contains(transactionID))
{
return;
}
DataMgr.ApplePayTransactionID.Value.Add(transactionID);
}
// 普通商品直接处理
// HandlePurchaseSuccess(transactionID, isSuccess =>
// {
// if (isSuccess)
// {
// Debug.Log("普通商品验证成功");
// }
// }, true);
}
//服务器验证
private void UploadReceiptForValidation(string sku, string transactionID, Action<bool> onValidationComplete)
{
Debug.Log("识别到订阅商品,准备进行订阅验证");
SendDebugToServer($"[Apple pay] 识别到订阅商品,准备进行订阅验证", Environment.StackTrace);
var productConfig = GetPayData(sku);
if (productConfig != null)
{
Debug.Log($"订阅商品ID: {sku} transactionID: {transactionID} _payData.amount: {productConfig.amount}");
SendDebugToServer($"订阅商品ID: {sku} transactionID: {transactionID} _payData.amount: {productConfig.amount}", Environment.StackTrace);
ApplePayNet.AppleSubscribeCheck<AppleSubscribeData>(
transactionID,
sku,
productConfig.amount,
_packageName,
response =>
{
bool isSuccess = response.IsSuccess;
// 在这里返回验证结果
onValidationComplete?.Invoke(isSuccess);
_payData = null;
if (isSuccess)
{
Debug.Log("订阅验证成功");
SendDebugToServer($"订阅验证成功", Environment.StackTrace);
_successCallback?.Invoke(ApplePayBackType.Check, new AppleResponseData()
{
expires_time = response.Data.expires_time,
sku = sku
});
}
else
{
Debug.LogWarning("[Apple Pay] 订阅验证失败");
}
});
}
}
/// <summary>
/// 支付成功后的本地处理(订阅和普通商品共用)
/// </summary>
private void HandlePurchaseSuccess(PurchaseEventArgs purchaseEvent, Action<bool> onValidationComplete, bool isTest = false)
{
var payDataJson = GetApplePayData();
Debug.Log($" HandlePurchaseSuccess payDataJson: {JsonConvert.SerializeObject(payDataJson)}");
var statusDictionary = JsonConvert.DeserializeObject<Dictionary<string, ApplePayData>>(payDataJson)
?? new Dictionary<string, ApplePayData>();
string transactionID = purchaseEvent.purchasedProduct.transactionID;
string sku = purchaseEvent.purchasedProduct.definition.id;
Debug.Log($"[Apple pay] 购买成功: transactionID: {transactionID} sku: {sku}");
// var receiptObj = JObject.Parse(purchaseEvent.purchasedProduct.receipt);
// var payload = JObject.Parse((string)receiptObj["Payload"]);
// var jsonData = JObject.Parse((string)payload["json"]);
SendDebugToServer($"普通商品 HandlePurchaseSuccess: {transactionID}", Environment.StackTrace);
if (!statusDictionary.ContainsKey(transactionID))
{
Debug.Log($"记录新交易 transactionID: {transactionID}");
Debug.Log($"-----_payData: {JsonConvert.SerializeObject(_payData)}");
if (_payData == null || string.IsNullOrWhiteSpace(_payData.innerOrderId))
{
Debug.Log("[Apple pay] _payData 为空或 innerOrderId 无效");
var innerdata = GetInnerIdData();
var isFind = false;
Debug.Log($" HandlePurchaseSuccess innerdata: {JsonConvert.SerializeObject(innerdata)}");
if (innerdata != null)
{
foreach (var item in innerdata)
{
Debug.Log(
$" HandlePurchaseSuccess item: {item.Key} {item.Value} jsonData productId=={sku}");
if (item.Value == sku)
{
SetPayData(purchaseEvent.purchasedProduct.definition.id);
_payData.innerOrderId = item.Key;
// _payData = new()
// {
// innerOrderId = item.Key,
// };
isFind = true;
break;
}
}
}
if (!isFind)
{
Debug.LogWarning("[Apple pay] 内部订单ID 无效");
onValidationComplete?.Invoke(false);
return;
}
}
statusDictionary.Add(transactionID, _payData);
SaveApplePayData(statusDictionary);
_innerData = null;
_payData = null;
}
if (statusDictionary.TryGetValue(transactionID, out var cValue))
{
if (!string.IsNullOrWhiteSpace(cValue.innerOrderId) || isTest)
{
ApplePaySuccess(transactionID, onValidationComplete);
}
}
}
private void SaveApplePayData(Dictionary<string, ApplePayData> payData)
{
// 保存更新后的数据
string json = JsonConvert.SerializeObject(payData);
PlayerPrefs.SetString("SGModule_apple_pay_data", json);
}
private string GetApplePayData()
{
string json = PlayerPrefs.GetString("SGModule_apple_pay_data", "");
// GetString if (json == "")
// {
// json = DataWrapper.ApplePayData;
// }
return json;
}
private void SaveInnerIdData(Dictionary<string, string> innerData)
{
// 保存更新后的数据
string json = JsonConvert.SerializeObject(innerData);
Debug.Log($"[Inner save Data] ==: {json}");
PlayerPrefs.SetString("SGModule_inner_order_id", json);
}
private Dictionary<string, string> GetInnerIdData()
{
string json = PlayerPrefs.GetString("SGModule_inner_order_id", "");
Debug.Log($"[Inner get Data] ==: {json}");
return JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
}
private Queue<(string transactionID, Action<bool> onValidationComplete)> _pendingRequests = new Queue<(string, Action<bool>)>();
private bool _isProcessing = false; // 标记是否正在处理中
private HashSet<string> _processedOrPendingTx = new HashSet<string>();
private void ApplePaySuccess(string transactionID, Action<bool> onValidationComplete)
{
// 入队前去重
if (_processedOrPendingTx.Contains(transactionID))
{
Debug.LogWarning($"Duplicate TX ignored: {transactionID}");
onValidationComplete?.Invoke(false);
return;
}
_processedOrPendingTx.Add(transactionID);
Debug.Log($"[ApplePaySuccess] Received transaction: {transactionID}");
_pendingRequests.Enqueue((transactionID, onValidationComplete));
TryProcessNext();
}
private void TryProcessNext()
{
if (_isProcessing || _pendingRequests.Count == 0)
return;
var (txId, callback) = _pendingRequests.Dequeue();
_isProcessing = true;
Debug.Log("apple 支付 StartCoroutine------" + txId);
StartCoroutine(ProcessPayData(txId, callback));
}
private IEnumerator ProcessPayData(string orderId, Action<bool> onValidationComplete)
{
// 发起请求
ApplePayRequest(orderId, onValidationComplete);
yield return null; // 等待本次请求完成
}
private void ApplePayRequest(string transactionID, Action<bool> onValidationComplete)
{
var payDataJson = GetApplePayData();
Debug.Log($"ApplePayRequest 1 payDataJson: {JsonConvert.SerializeObject(payDataJson)}");
SendDebugToServer($"验单 普通商品: {transactionID}", Environment.StackTrace);
var statusDictionary = JsonConvert.DeserializeObject<Dictionary<string, ApplePayData>>(payDataJson);
if (statusDictionary.ContainsKey(transactionID))
{
var data = statusDictionary[transactionID];
Debug.Log($"ApplePayRequest 2 transactionID: {transactionID}, innerOrderId:{data.innerOrderId}");
ApplePayNet.ApplePayCheck<ApplePayData>(transactionID, data.innerOrderId, _packageName, (response) =>
{
Debug.Log(
$"ApplePayRequest 3 response.IsSuccess: {JsonConvert.SerializeObject(response)}");
_isProcessing = false;
TryProcessNext();
if (response.IsSuccess || response.Code == 1026 || (response.Code == 1007 && data.sku == PurchasingManager.GetPaySku(PayType.buy_one)))
{
onValidationComplete?.Invoke(true);
_processedOrPendingTx.Remove(transactionID);
_successCallback(ApplePayBackType.Check, new AppleResponseData()
{
sku = data.sku
});
var innerdata = GetInnerIdData();
innerdata.Remove(data.innerOrderId);
SaveInnerIdData(innerdata);
statusDictionary.Remove(transactionID);
// 保存更新后的数据
SaveApplePayData(statusDictionary);
_innerData = null;
_payData = null;
}
else if (response.Code == 1007)
{
GameHelper.ShowTips("no_network", true);
onValidationComplete?.Invoke(true);
}
else
{
onValidationComplete?.Invoke(response.IsSuccess);
}
if (!new List<int>() { 1021, 1027, 1028 }.Contains(response.Code))
{
}
else
{
statusDictionary.Remove(transactionID);
// 保存更新后的数据
SaveApplePayData(statusDictionary);
var innerdata = GetInnerIdData();
innerdata.Remove(data.innerOrderId);
SaveInnerIdData(innerdata);
}
});
}
}
#endregion
#region
private bool IsInitialized()
{
Debug.Log("[barry] check IsInitialized======:");
return _storeController != null && _extensionProvider != null;
}
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
_storeController = controller;
_extensionProvider = extensions;
_appleExtension = extensions.GetExtension<IAppleExtensions>();
GetVipHistory();
}
public void OnInitializeFailed(InitializationFailureReason error)
{
Debug.Log("[barry] OnInitializeFailed1 Reason:" + error);
// throw new NotImplementedException();
}
public void OnInitializeFailed(InitializationFailureReason error, string message)
{
Debug.Log("[barry] OnInitializeFailed2 Reason:" + error);
Debug.Log("[barry] OnInitializeFailed2 message:" + message);
// throw new NotImplementedException();
}
#endregion
#region
public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
{
Debug.Log(" OnPurchaseFailed===1==:");
HandleOnPurchaseFail(failureReason);
}
public void OnPurchaseFailed(Product product, PurchaseFailureDescription failureDescription)
{
Debug.Log("OnPurchaseFailed===2==:");
HandleOnPurchaseFail(failureDescription.reason);
}
private void HandleOnPurchaseFail(PurchaseFailureReason failureReason)
{
Debug.Log($" HandleOnPurchaseFail 1 ");
if (_payData == null) return;
GameHelper.ShowTips("purchase_fail", true);
Debug.Log($" HandleOnPurchaseFail 2 ");
ApplePayNet.ApplePayCancel<ApplePayData>(_payData, (response) =>
{
string msg = ToFriendlyString(failureReason);
Debug.Log("[barry] HandleOnPurchaseFail:" + response.IsSuccess + " reason: " + msg);
if (!_payData.sku.Contains(".sub"))
{
var innerdata = GetInnerIdData();
Debug.Log(
$"[Apple pay] HandleOnPurchaseFail----- _payData.innerOrderId: {_payData.innerOrderId}");
innerdata.Remove(_payData.innerOrderId);
SaveInnerIdData(innerdata);
}
_failedCallback?.Invoke(msg);
_payData = null;
_innerData = null;
_successCallback?.Invoke(ApplePayBackType.Cancel, null);
});
}
private static string ToFriendlyString(PurchaseFailureReason reason)
{
Debug.Log($"ToFriendlyString 1 reason==={reason}");
return reason switch
{
PurchaseFailureReason.ProductUnavailable => "商品不可用",
PurchaseFailureReason.PurchasingUnavailable => "购买功能不可用",
PurchaseFailureReason.ExistingPurchasePending => "已有未完成的购买",
PurchaseFailureReason.SignatureInvalid => "签名验证失败",
PurchaseFailureReason.UserCancelled => "用户取消",
PurchaseFailureReason.PaymentDeclined => "支付被拒绝",
PurchaseFailureReason.DuplicateTransaction => "重复的交易ID",
PurchaseFailureReason.Unknown => "未知错误",
_ => $"未识别的错误: {(int)reason}"
};
}
#endregion
}
}
#else
namespace SGModule.ApplePay {
public class ApplePayManager: SingletonMonoBehaviour<ApplePayManager>{
public void StartPay() {
}
public string GetApplePayName(string key)
{
return "";
}
public void Purchase(ApplePayData payData, Action<ApplePayBackType> successCallback,
Action<string> failedCallback) {
var msg = "Apple Pay: Purchase Failed, No plugin is installed.";
Log.Info("[Apple IOS]",msg);
failedCallback?.Invoke(msg);
}
public void AppleRestore(Action<bool, string> restoreCallback)
{
}
public void InitProduct(List<ProductConfig>configs, string packageName)
{
}
}
}
#endif
public class AppleResponseData
{
[JsonProperty("expires_time")]
public long expires_time;
[JsonProperty("sku")]
public string sku;
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 8478e5310ad64f23a3805cd8a3fa024f
timeCreated: 1747907338
@@ -1,95 +0,0 @@
using SGModule.Common.Helper;
using SGModule.Net;
using UnityEngine.Events;
namespace SGModule.ApplePay
{
public static class ApplePayNet
{
#region IOSPay
/// <summary>
/// ios支付创建订单
/// </summary>
/// <param name="data"></param>
/// <param name="onCompleted"></param>
public static void ApplePayCreate<T>(ApplePayData data, UnityAction<ResponseData<T>> onCompleted = null)
{
NetKit.NetKit.Instance.Post<T>("shop/applePayCreate", data,
response => { onCompleted?.Invoke(response); });
}
/// <summary>
/// ios支付取消订单
/// </summary>
/// <param name="data"></param>
/// <param name="onCompleted"></param>
public static void ApplePayCancel<T>(ApplePayData data, UnityAction<ResponseData<T>> onCompleted = null)
{
NetKit.NetKit.Instance.Post<T>("shop/applePayCancel", data,
response => { onCompleted?.Invoke(response); });
}
public static void ApplePaySubscriptionHistory<T>(UnityAction<ResponseData<T>> onCompleted = null)
{
NetKit.NetKit.Instance.Post<T>("shop/subscribeHistory", null,
response => { onCompleted?.Invoke(response); });
}
public static void ApplePaySubscriptionCheck<T>(HistoryObject obj,UnityAction<ResponseData<T>> onCompleted = null)
{
NetKit.NetKit.Instance.Post<T>("shop/subscribeCheck", obj,
response => { onCompleted?.Invoke(response); });
}
/// <summary>
/// ios支付验证订单
/// </summary>
/// <param name="transactionID">apple支付返回的订单id</param>
/// <param name="innerOrderId">内部订单id,创建订单时返回的</param>
/// <param name="key">包名</param>
/// <param name="onCompleted">回调</param>
public static void ApplePayCheck<T>(string transactionID, string innerOrderId,
string key, UnityAction<ResponseData<T>> onCompleted = null)
{
var test = new AppleCheckData
{
signedPayload = Common.Helper.Cryptor.Encrypt(transactionID, key),
innerOrderId = innerOrderId
};
NetKit.NetKit.Instance.Post<T>("shop/applePayCheck", test,
response => { onCompleted?.Invoke(response); });
}
/// <summary>
/// ios支付订阅
/// </summary>
/// <param name="transactionID">apple支付返回的订单id</param>
/// <param name="sku">商品id</param>
/// <param name="amount">价格</param>
/// <param name="key">包名</param>
/// <param name="onCompleted">回调</param>
public static void AppleSubscribeCheck<T>(string transactionID, string sku, int amount,
string key, UnityAction<ResponseData<T>> onCompleted = null)
{
var test = new AppleSubscribeData
{
signedPayload = Common.Helper.Cryptor.Encrypt(transactionID, key),
sku = sku,
amount = amount,
currency = "USD"
};
Log.Info("[Apple pay]", $" AppleSubscribeCheck 开始...{sku}");
NetKit.NetKit.Instance.Post<T>(
"shop/appleSubscribe",
test,
response =>
{
Log.Info("[Apple pay]", $"AppleSubscribeCheck 结束...{response.IsSuccess}");
onCompleted?.Invoke(response);
});
}
#endregion
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 760f78942ee949a9af90bc8ac6710be7
timeCreated: 1747996461
@@ -1,22 +0,0 @@
#if UNITY_IOS && UNITY_IAP
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Purchasing;
namespace SGModule.ApplePay
{
[System.Serializable]
public class ProductConfig
{
[JsonProperty("name")]
public string name;
[JsonProperty("sku")]
public string sku;
[JsonProperty("price")]
public float price;
[JsonProperty("type")]
public string type;
}
}
#endif
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: bab80a35d16a48e6856d995e175b82d3
timeCreated: 1747911023
@@ -1,2 +1,11 @@
fileFormatVersion: 2
guid: 121d8e1769529b440bc85f03a485ec10
guid: 121d8e1769529b440bc85f03a485ec10
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -13,7 +13,7 @@ namespace SGModule.Common.Helper {
public static readonly ModuleLogger DataStorage = new("DataStorage");
public static readonly ModuleLogger IAP = new("IAP");
private static bool IsEnabled => ConfigManager.GameConfig?.enabledLog ?? false;
private static bool IsEnabled => true;//ConfigManager.GameConfig?.enabledLog ?? false;
public static void Info(string label, string msg, bool showStack = true) {
if (IsEnabled) {
@@ -1,2 +1,11 @@
fileFormatVersion: 2
guid: acd6a7aa2034443549cb53d6ae963143
guid: acd6a7aa2034443549cb53d6ae963143
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -104,6 +104,32 @@ namespace SGModule.NetKit {
public LoginModel LoginModel => _loginModel;
//
// public LoginModel LoginModel {
// get {
// if (_loginModel == null) {
// _loginModel = new LoginModel {
// CdnURL = string.Empty,
// Country = string.Empty,
// DebugLog = true,
// Enwp = 0,
// ExpiresAt = 0,
// InviteCode = string.Empty,
// IsMagic = false,
// LastLoginTime = 0,
// LoginTime = 0,
// NewPlayer = false,
// PlayData = string.Empty,
// PlayDataVer = 0,
// RegTime = 0,
// Setting = string.Empty,
// Token = string.Empty,
// Uid = 0
// };
// }
// return _loginModel;
// }
// }
public bool LoginSuccess => _loginSuccess;