SDK_UnityMoney/Assets/Script/SDKManager/Purchase/IAPOrderManager.cs

396 lines
19 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#if UNITY_PURCHASE
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using UnityEngine;
namespace WZ
{
public class IAPOrderManager : D_MonoSingleton<IAPOrderManager>
{
private static string _purchaseOrderMap = "PurchaseOrderMap";
private List<int> NotRetryCode = new List<int> { 0, 430, 900, 901, 902, 903, 904, 905 };
private Dictionary<string, int> mRepeatCountDic;
#region
public void VerifyPurchase(IAPDataConfig args)
{
LoggerUtils.Debug("[iap] Start VerifyPurchase orderid:" + args.info["order_id"] + "status:" + args.state);
if (args.state == IAPDataStateType.def)
{
// 记录订单处理次数处理5次还是失败就不处理了
if (mRepeatCountDic.ContainsKey(args.info["order_id"]))
{
mRepeatCountDic[args.info["order_id"]] = mRepeatCountDic[args.info["order_id"]] + 1;
}
else
{
mRepeatCountDic.Add(args.info["order_id"], 1);
}
// 开始处理,设置正在处理的状态
RefreshOrderStatue(args, IAPDataStateType.deal);
args.info.TryGetValue("mGameExtraParam", out var gameExtraParam);
if (string.IsNullOrEmpty(gameExtraParam))
{
gameExtraParam = IAPPurchaseManager.Instance._gameExtraParam;
}
LoggerUtils.Debug("[iap] IAP VerifyPurchase start");
var requestArgs = args.info.ToDictionary(kv => kv.Key, kv => (object)kv.Value);
ServerMgr.Instance.VerifyPurchase(requestArgs, (code, msg, data) =>
{
RefreshOrderStatue(args, IAPDataStateType.def);
LoggerUtils.Debug("IAP VerifyPurchase CODE:" + code + " illegal:" + data.illegal_order + " env:" + data.environment);
LoggerUtils.Debug("IAP VerifyPurchase msg:" + msg);
if ((code == 0 || code == 430) && data.illegal_order == 0)
{
// 将订阅商品信息存储到本地
if (!IAPPurchaseManager.Instance._productArgs.ContainsKey(args.info["product_id"].ToString()) && args.info["product_type"].ToString().Equals("Subscription"))
{
IAPPurchaseManager.Instance._productArgs.Add(args.info["product_id"].ToString(), requestArgs);
}
else if (IAPPurchaseManager.Instance._productArgs.ContainsKey(args.info["product_id"].ToString()) && args.info["product_type"].ToString().Equals("Subscription"))
{
IAPPurchaseManager.Instance._productArgs[args.info["product_id"].ToString()] = requestArgs;
}
RushSDKManager.Instance.OnPurchaseComplete?.Invoke(new PurchaseInfo(
productName: args.info["product_name"],
productID: args.info["product_id"],
orderID: args.info["order_id"],
currency: args.info["currency"],
price: args.info["price"],
gameExtra: gameExtraParam,
failReason: "",
orderAlreadyExists: code == 430,
purchaseResult: code == 0,
resultType: IAPResultType.PurchasingSuccess,
productType: args.info["product_type"]
));
LogVerifySuccessOrder(args, data.environment, gameExtraParam, code == 430);
}
else
{
// 不需要重试的错误码
if (!NotRetryCode.Contains(code))
{
SaveVerifyFailOrderId(args);
}
// 主动删除过期订单
if (!string.IsNullOrEmpty(data.illegal_msg) && args.info["product_type"].ToString().Equals("Subscription"))
{
if (data.illegal_msg.Contains("product expired"))
{
RemoveVerifySuccessOrder(args.info["product_id"]);
}
}
if (code == -1)
{
RushSDKManager.Instance.OnPurchaseComplete?.Invoke(new PurchaseInfo(
productName: args.info["product_name"],
productID: args.info["product_id"],
orderID: args.info["order_id"],
currency: args.info["currency"],
price: args.info["price"],
gameExtra: gameExtraParam,
failReason: "",
orderAlreadyExists: code == 430,
purchaseResult: false,
resultType: IAPResultType.NULL,
productType: args.info["product_type"]
));
}
else
{
RushSDKManager.Instance.OnPurchaseComplete?.Invoke(new PurchaseInfo(
productName: args.info["product_name"],
productID: args.info["product_id"],
orderID: args.info["order_id"],
currency: args.info["currency"],
price: args.info["price"],
gameExtra: gameExtraParam,
failReason: "",
orderAlreadyExists: code == 430,
purchaseResult: false,
resultType: code == 430 ? IAPResultType.PurchasingSuccess : IAPResultType.ServerAuthenticationFailed,
productType: args.info["product_type"]
));
}
// msg 包含 illegal_order_0 说明是正常的缓存订单上报
// 卸载重装后,一次性商品
if (msg.Contains("illegal_order_0"))
{
LogVerifySuccessOrder(args, msg.Contains("sandbox") ? "sandbox" : "production", gameExtraParam, code == 430);
}
else
{
LogVerifyFailOrder(args, gameExtraParam, $"Purchase service code : {code} msg : {msg} dataMsg:{data.illegal_msg} illegal_order:{data.illegal_order} environment:{(msg.Contains("sandbox") ? "sandbox" : "production")}");
}
}
});
}
}
private void LogVerifySuccessOrder(IAPDataConfig _productInfo, string _enviroment, string _gameExtraParam, bool _orderAlreadyExists)
{
IAPEvent.LogPurchaseSuccess(new PurchaseInfo(
productName: _productInfo.info["product_name"],
productID: _productInfo.info["product_id"],
orderID: _productInfo.info["order_id"],
currency: _productInfo.info["currency"],
price: _productInfo.info["price"],
gameExtra: _gameExtraParam,
failReason: "",
orderAlreadyExists: _orderAlreadyExists,
purchaseResult: !_orderAlreadyExists,
resultType: IAPResultType.NULL,
productType: _productInfo.info["product_type"]
), _enviroment);
}
private void LogVerifyFailOrder(IAPDataConfig _productInfo, string _gameExtraParam, string _errInfo)
{
IAPEvent.LogPurchaseFail(new PurchaseInfo(
productName: _productInfo.info["product_name"],
productID: _productInfo.info["product_id"],
orderID: _productInfo.info["order_id"],
currency: _productInfo.info["currency"],
price: _productInfo.info["price"],
gameExtra: _gameExtraParam,
failReason: _errInfo,
orderAlreadyExists: false,
purchaseResult: false,
resultType: IAPResultType.NULL,
productType: _productInfo.info["product_type"]
));
}
#endregion
#region
private void RefreshOrderStatue(IAPDataConfig _productInfo, IAPDataStateType state)
{
if (ES3.KeyExists("FailOrderCacheData"))
{
List<IAPDataConfig> list = ES3.Load(_purchaseOrderMap) as List<IAPDataConfig>;
var value = _productInfo.info["order_id"];
var want = list.Find(e => e.info.ContainsValue(value));
if (want != null)
{
want.state = state;
ES3.Save(_purchaseOrderMap, list);
}
}
}
#endregion
#region
public void SaveOrder(IAPDataConfig _productInfo)
{
if (ES3.KeyExists(_purchaseOrderMap))
{
List<IAPDataConfig> list = ES3.Load(_purchaseOrderMap) as List<IAPDataConfig>;
var want = list.Find(e => e.info.ContainsValue(_productInfo.info["order_id"]));
if (want == null)
{
list.Add(_productInfo);
ES3.Save(_purchaseOrderMap, list);
IAPEvent.LogSaveOrderBySdk(new PurchaseInfo(
productName: _productInfo.info["product_name"],
productID: _productInfo.info["product_id"],
orderID: _productInfo.info["order_id"],
currency: _productInfo.info["currency"],
price: _productInfo.info["price"],
gameExtra: _productInfo.info["mGameExtraParam"],
productType: _productInfo.info["product_type"],
failReason: null,
orderAlreadyExists: false,
purchaseResult: false,
resultType: IAPResultType.NULL
));
LoggerUtils.Debug("[iap] IAP SaveOrder 已经有表了添加订单订单ID" + _productInfo.info["order_id"] + " 未验证订单个数:" + list.Count);
}
}
else
{
List<IAPDataConfig> tem = new List<IAPDataConfig>
{
_productInfo
};
ES3.Save(_purchaseOrderMap, tem);
IAPEvent.LogSaveOrderBySdk(new PurchaseInfo(
productName: _productInfo.info["product_name"],
productID: _productInfo.info["product_id"],
orderID: _productInfo.info["order_id"],
currency: _productInfo.info["currency"],
price: _productInfo.info["price"],
gameExtra: _productInfo.info["mGameExtraParam"],
productType: _productInfo.info["product_type"],
failReason: null,
orderAlreadyExists: false,
purchaseResult: false,
resultType: IAPResultType.NULL
));
LoggerUtils.Debug("[iap] IAP SaveOrder 第一次存储表 添加订单ID" + _productInfo.info["order_id"] + " 商品类型:" + _productInfo.info["product_type"] + " 订单个数:" + tem.Count);
}
}
#endregion
#region
private bool inDealFailOrder;
private void SaveVerifyFailOrderId(IAPDataConfig _productInfo)
{
LoggerUtils.Debug("[iap] iap save verify fail order,orderId:" + _productInfo.info["order_id"] + " 商品类型:" + _productInfo.info["product_type"]);
if (ES3.KeyExists(_purchaseOrderMap))
{
List<IAPDataConfig> list = ES3.Load(_purchaseOrderMap) as List<IAPDataConfig>;
var value = _productInfo.info["order_id"];
var want = list.Find(e => e.info.ContainsValue(value));
if (want == null)
{
list.Add(_productInfo);
ES3.Save(_purchaseOrderMap, list);
ReadFailOrderId();
LoggerUtils.Debug("[iap] IAP SaveVerifyFailOrderId 已经有表了,添加失败订单,订单ID" + _productInfo.info["order_id"] + " 商品类型:" + _productInfo.info["product_type"]);
}
else
{
if (!inDealFailOrder)
{
inDealFailOrder = true;
InvokeRepeating(nameof(ReadFailOrderId), 0, 30);
}
}
}
else
{
List<IAPDataConfig> tem = new List<IAPDataConfig>
{
_productInfo
};
ES3.Save(_purchaseOrderMap, tem);
ReadFailOrderId();
LoggerUtils.Debug("[iap] IAP SaveVerifyFailOrderId 第一次存储表 添加失败订单 订单个数:" + tem.Count);
}
}
#endregion
#region
public void ReadFailOrderId()
{
if (ES3.KeyExists(_purchaseOrderMap))
{
List<IAPDataConfig> list = ES3.Load(_purchaseOrderMap) as List<IAPDataConfig>;
LoggerUtils.Debug("[iap] IAP ReadFailOrderId 读取失败订单列表count" + list.Count + " mRepeatCountDic" + mRepeatCountDic.Count);
if (list.Count > 0)
{
// 当前进程每条订单校验5次如果失败则不再处理
// 重复校验时判断次数是否大于5大于5则不再处理
IAPDataConfig tempData = null;
if (mRepeatCountDic.Count > 0)
{
foreach (var data in list)
{
LoggerUtils.Debug("[iap] iap start verify fail order with repeat dic" + data.info["order_id"] + " count:" + mRepeatCountDic[data.info["order_id"]]);
if (mRepeatCountDic.ContainsKey(data.info["order_id"]) && mRepeatCountDic[data.info["order_id"]] <= 5)
{
tempData = data;
break;
}
}
}
// 如果还有次数不超过5次的订单则继续校验否则就不再处理
if (tempData != null)
{
LoggerUtils.Debug("[iap] iap start verify fail order with repeat temp dic" + tempData.info["order_id"] + " count:" + mRepeatCountDic[tempData.info["order_id"]]);
VerifyPurchase(tempData);
IAPEvent.LogStarVerifyOrderBySdk(new PurchaseInfo(
productName: tempData.info["product_name"],
productID: tempData.info["product_id"],
orderID: tempData.info["order_id"],
currency: tempData.info["currency"],
price: tempData.info["price"],
gameExtra: tempData.info["mGameExtraParam"],
productType: tempData.info["product_type"],
failReason: null,
orderAlreadyExists: false,
purchaseResult: false,
resultType: IAPResultType.NULL));
}
else
{
LoggerUtils.Debug("[iap] iap cancel verify fail order");
CancelInvoke(nameof(ReadFailOrderId));
inDealFailOrder = false;
}
}
else
{
CancelInvoke(nameof(ReadFailOrderId));
inDealFailOrder = false;
}
}
}
#endregion
#region
// 校验成功后移除订单
public void RemoveVerifySuccessOrder(string orderId)
{
if (ES3.KeyExists(_purchaseOrderMap))
{
List<IAPDataConfig> list = ES3.Load(_purchaseOrderMap) as List<IAPDataConfig>;
var want = list.Find(e => e.info.ContainsValue(orderId));
if (want != null)
{
LoggerUtils.Debug("[iap] IAP RemoveVerifySuccessOrder 找到并移除订单订单ID:" + orderId);
list.Remove(want);
IAPEvent.LogRemoveOrderBySdk(new PurchaseInfo(
productName: want.info["product_name"],
productID: want.info["product_id"],
orderID: want.info["order_id"],
currency: want.info["currency"],
price: want.info["price"],
gameExtra: want.info["mGameExtraParam"],
productType: want.info["product_type"],
failReason: null,
orderAlreadyExists: false,
purchaseResult: false,
resultType: IAPResultType.NULL));
ES3.Save(_purchaseOrderMap, list);
}
LoggerUtils.Debug("[iap] IAP 订单还剩余:" + list.Count + " 条未校验");
if (list.Count > 0)
{
ReadFailOrderId();
}
else
{
inDealFailOrder = false;
CancelInvoke(nameof(ReadFailOrderId));
}
}
}
#endregion
public class IAPDataConfig
{
public Dictionary<string, string> info;
public IAPDataStateType state;
}
}
}
#endif