chicken_dy/Assets/HCMiniSdk/Scripts/WebGL/HCWX/HCWxPurchase.cs

484 lines
24 KiB
C#
Raw Normal View History

2024-03-07 12:12:48 +00:00
#if UNITY_WEBGL && WEBGL_WX
using System;
using System.Collections.Generic;
using HC.MiniJSON;
using JetBrains.Annotations;
using WeChatWASM;
namespace HC
{
public class HCWxPurchase : HCSingleton<HCWxPurchase>, HCIPurchase
{
private const string PayTypeH5 = "hc_pay_type_h5";
private const string PayServiceOrderId = "hc_pay_service_order_id";
private static bool IsH5Pay => HCAnalyticsManager.Instance.GetRemoteConfigBool("h5_pay", HCWebGLSDKManager.AppInfo.GetPlatform().ToLower().Contains("ios"));
private bool _isOpenCustomerService;
private string lastOrderId = "";
private int checkH5ExecutionCount = 0;
private HashSet<string> h5callbackOrderStatus = new();
public void Init()
{
if (HCWebGLSDKManager.Base is HCWXBase hcwxBase)
{
hcwxBase.OpenCustomerServiceSuccess += OpenCustomerServiceSuccess;
hcwxBase.OpenCustomerServiceFail += OpenCustomerServiceFail;
}
CheckOrderList();
InvokeRepeating("CheckOrderList", 800, 32);
}
private void OpenCustomerServiceSuccess(CustomerServiceSuccessBean customerServiceSuccessBean)
{
HCDebugger.LogDebug($"[HCWxPurchase] [OpenCustomerServiceSuccess] lastOrderId = {lastOrderId} _isOpenCustomerService = {_isOpenCustomerService} path = {customerServiceSuccessBean.path} ");
if (!_isOpenCustomerService) return;
_isOpenCustomerService = false;
if (string.IsNullOrEmpty(lastOrderId))
{
HCSDKManager.Instance.LogEvent(HCInnerStaticSting.HC_WECHAT_PAY_ERROR, "msg", "客服界面跳转回来lastOrderId为空", "order_no", lastOrderId);
HCDebugger.LogError("[HCWxPurchase] [OpenCustomerServiceSuccess] lastOrderId is null");
return;
}
HCSDKManager.Instance.LogEvent(HCInnerStaticSting.HC_WECHAT_PAY_OPEN_CUSTOMER_SERVICE_SUCCESS, "order_no", lastOrderId);
checkH5ExecutionCount = 0;
// 打开查询load
WX.ShowLoading(new ShowLoadingOption()
{
title = "查询中...",
success = result => { HCDebugger.LogDebug($"[HCWxPurchase] [ShowLoading] success result.errMsg = {result.errMsg}"); },
fail = result => { HCDebugger.LogDebug($"[HCWxPurchase] [ShowLoading] fail result.errMsg = {result.errMsg}"); }
});
h5callbackOrderStatus.Add(lastOrderId);
H5CheckOrderStatus();
InvokeRepeating("H5CheckOrderStatus", 2, 2);
}
private void H5CheckOrderStatus()
{
HCServer.Instance.OrderQuery(lastOrderId, (code, msg, orderQueryResult) =>
{
checkH5ExecutionCount++;
if (code == 0 && orderQueryResult != null && orderQueryResult.pay_status != HCServer.OrderQueryResult.PayStatusNotPaid)
{
HCDebugger.LogDebug(
$"[HCWxPurchase] [H5CheckOrderStatus] 校验成功 :code = {code} pay_status = {orderQueryResult.pay_status} transaction_id = {orderQueryResult.transaction_id} pay_success_time = {orderQueryResult.pay_success_time}");
var readPaymentArgsFromOrderId = ReadPaymentArgsFromOrderId(lastOrderId);
if (readPaymentArgsFromOrderId == null)
{
HCSDKManager.Instance.LogEvent(HCInnerStaticSting.HC_WECHAT_PAY_ERROR, "msg", "缓存查询订单不存在", "order_no", lastOrderId);
HCDebugger.LogError($"[HCWxPurchase] [H5CheckOrderStatus] orderId查询订单失败 lastOrderId = {lastOrderId}");
// 已经被销毁了,无需给回调了
// CallbackPay(lastOrderId, "", "", -1, "");
// 取消 查询
CheckComplete();
return;
}
DeleteOrder(lastOrderId);
if (h5callbackOrderStatus.Contains(lastOrderId))
{
// 标记已经通知
h5callbackOrderStatus.Remove(lastOrderId);
CallbackPay(lastOrderId, readPaymentArgsFromOrderId.productName, readPaymentArgsFromOrderId.productId, HCServer.OrderQueryResult.PayStatusPaid == orderQueryResult.pay_status ? 0 : orderQueryResult.pay_status,
readPaymentArgsFromOrderId.gameExtraParam, serverGameExtraParam: orderQueryResult.game_extra_param, hcPaymentArgs: readPaymentArgsFromOrderId,
msg: $"pay_status = {orderQueryResult.pay_status} transaction_id = {orderQueryResult.transaction_id}");
}
else
{
HCDebugger.LogError($"[HCWxPurchase] [H5CheckOrderStatus] lastOrderId = {lastOrderId} callbacked.");
}
lastOrderId = "";
// 取消 查询
CheckComplete();
return;
}
HCDebugger.LogDebug($"[HCWxPurchase] [H5CheckOrderStatus] fail checkH5ExecutionCount = {checkH5ExecutionCount} code = {code} msg = {msg} orderQueryResult = {orderQueryResult?.pay_status}");
// 如果执行次数达到3次取消重复调用并执行其他方法
if (checkH5ExecutionCount >= 3)
{
CheckComplete();
var readPaymentArgsFromOrderId = ReadPaymentArgsFromOrderId(lastOrderId);
CallbackPay(lastOrderId, readPaymentArgsFromOrderId.productName, readPaymentArgsFromOrderId.productId, 2, readPaymentArgsFromOrderId.gameExtraParam, msg: "查询次数到达3次");
}
});
}
private void CheckComplete()
{
WX.HideLoading(new HideLoadingOption()
{
success = result => { HCDebugger.LogDebug($"[HCWxPurchase] [HideLoading] success result.errMsg = {result.errMsg}"); },
fail = result => { HCDebugger.LogDebug($"[HCWxPurchase] [HideLoading] fail result.errMsg = {result.errMsg}"); }
});
// 取消重复调用
CancelInvoke("H5CheckOrderStatus");
// 查询一下历史订单
CheckOrderList();
}
private void OpenCustomerServiceFail(string errMsg)
{
if (!_isOpenCustomerService) return;
_isOpenCustomerService = false;
HCSDKManager.Instance.LogEvent(HCInnerStaticSting.HC_WECHAT_PAY_OPEN_CUSTOMER_SERVICE_FAIL, "msg", errMsg, "order_no", lastOrderId);
var readPaymentArgsFromOrderId = ReadPaymentArgsFromOrderId(lastOrderId);
CallbackPay(lastOrderId, readPaymentArgsFromOrderId.productName, readPaymentArgsFromOrderId.productId, 1, readPaymentArgsFromOrderId.gameExtraParam, msg: $"open customer service fail : errMsg = {errMsg}");
DeleteOrder(lastOrderId);
// 查询一下历史订单
CheckOrderList();
}
private bool CallbackPay(string orderNo, string productName, string productId, int code, string gameExtraParam, bool repeat = false, string serverGameExtraParam = "", HCPaymentArgs hcPaymentArgs = null, int balance = 0,
string msg = "")
{
hcPaymentArgs ??= new HCPaymentArgs();
if (code == 0)
{
HCAnalyticsManager.Instance.IAPSuccess(productName, productId, orderNo, "CNY", hcPaymentArgs.money, gameExtraParam, balance);
}
else
{
HCAnalyticsManager.Instance.IAPFail(productName, productId, orderNo, "CNY", hcPaymentArgs.money, hcPaymentArgs.gameExtraParam, $"code = {code} msg = {msg}");
}
HCDebugger.LogDebug($"[HCWxPurchase] [CallbackPay] orderNo = {orderNo} productName = {productName} productId = {productId} code = {code} gameExtraParam = {gameExtraParam} serverGameExtraParam = {serverGameExtraParam}");
HCSDKManager.Instance.OnPurchaseDone?.Invoke(orderNo, productName, productId, code == 0, gameExtraParam, repeat, serverGameExtraParam);
return HCSDKManager.Instance.OnPurchaseDone != null;
}
public void Buy(HCPaymentArgs paymentArgs)
{
lastOrderId = "";
paymentArgs.ext ??= new Dictionary<string, object>();
paymentArgs.ext[PayTypeH5] = IsH5Pay;
HCSDKManager.Instance.LogEvent(HCInnerStaticSting.HC_WECHAT_PAY_CREATE_ORDER_ID, new Dictionary<string, object>()
{
["money"] = paymentArgs.money,
["productId"] = paymentArgs.productId,
["productName"] = paymentArgs.productName,
["gameExtraParam"] = paymentArgs.gameExtraParam,
["ext"] = paymentArgs.ext,
});
// 创建订单号
HCServer.Instance.OrderCreate(paymentArgs.productName, paymentArgs.productId, "" + paymentArgs.money, 1, gameExtraParam: paymentArgs.gameExtraParam, callback: (code, msg, orderCreateInfo) =>
{
if (code != 0 || orderCreateInfo == null || string.IsNullOrEmpty(orderCreateInfo.order_no))
{
HCSDKManager.Instance.LogEvent(HCInnerStaticSting.HC_WECHAT_PAY_CREATE_ORDER_ID_FAIL, "msg", msg, "code", code);
HCDebugger.LogError($"[HCWxPurchase] [Buy] create order error. code = {code} orderCreateInfo = {orderCreateInfo} msg = {msg}");
CallbackPay(lastOrderId, paymentArgs.productName, paymentArgs.productId, 3, paymentArgs.gameExtraParam, msg: $"create order error. code = {code} orderCreateInfo = {orderCreateInfo} msg = {msg}");
return;
}
var serverOrderNo = orderCreateInfo.order_no;
lastOrderId = serverOrderNo;
paymentArgs.ext[PayServiceOrderId] = serverOrderNo;
HCDebugger.LogDebug($"[HCWxPurchase] [Buy] sessionFrom = {serverOrderNo} sendMessageTitle = {paymentArgs.productName} IsH5Pay = {IsH5Pay}");
if (IsH5Pay)
{
WX.ShowModal(new ShowModalOption
{
title = HCAnalyticsManager.Instance.GetRemoteConfigStr("pay_title", ""),
content = HCAnalyticsManager.Instance.GetRemoteConfigStr("pay_content", "即将进入客服会话。在客服会话中点击右下角图片即可开始充值"),
confirmText = HCAnalyticsManager.Instance.GetRemoteConfigStr("pay_confirm_text", "去充值"),
cancelText = HCAnalyticsManager.Instance.GetRemoteConfigStr("pay_cancel_text", "取消"),
success = result =>
{
// 用户点击确定'
if (result.confirm)
{
_isOpenCustomerService = true;
// 保存订单
SaveOrder(serverOrderNo, paymentArgs);
HCWebGLSDKManager.Base.OpenCustomerService(new Dictionary<string, object>
{
["sessionFrom"] = serverOrderNo,
["showMessageCard"] = true,
["sendMessageTitle"] = $"我要充值{paymentArgs.money * 1.0 / 100}元",
["sendMessagePath"] = serverOrderNo,
["sendMessageImg"] = HCAnalyticsManager.Instance.GetRemoteConfigStr("pay_img", "https://wxres.dgtverse.cn/h5pay/img/20231228-145750.png"),
});
}
else if (result.cancel)
{
HCSDKManager.Instance.LogEvent(HCInnerStaticSting.HC_WECHAT_PAY_CANCEL, "order_no", serverOrderNo);
CallbackPay(lastOrderId, paymentArgs.productName, paymentArgs.productId, 3, paymentArgs.gameExtraParam, msg: $"cancel : order_no = {serverOrderNo}");
}
}
});
}
else
{
// Android
var requestMidasPaymentOption = new RequestMidasPaymentOption
{
mode = "game",
// 沙箱环境 0正式环境 1 测试环境
env = HCAnalyticsManager.Instance.GetRemoteConfigInt("pay_env", 1),
offerId = HCStaticParams.PAY_OFFERID,
currencyType = "CNY",
platform = "android",
buyQuantity = paymentArgs.money,
zoneId = "1",
outTradeNo = serverOrderNo,
success = result =>
{
HCDebugger.LogDebug($"[] result.errMsg = {result.errMsg}");
HCAnalyticsManager.Instance.IAPChannelSuccess(paymentArgs.productName, paymentArgs.productId, serverOrderNo, "CNY", paymentArgs.money, paymentArgs.gameExtraParam);
// 保存订单,开始充值
SaveOrder(serverOrderNo, paymentArgs);
ServerBuy(serverOrderNo, paymentArgs.productName, paymentArgs.money, (code, msg, data) => { });
},
fail = result =>
{
CallbackPay(serverOrderNo, paymentArgs.productName, paymentArgs.productId, 1, paymentArgs.gameExtraParam, msg: $"支付失败: {result.errMsg} {result.errCode}");
HCAnalyticsManager.Instance.IAPChannelFail(paymentArgs.productName, paymentArgs.productId, serverOrderNo, "CNY", paymentArgs.money, paymentArgs.gameExtraParam,
$"code = {result.errCode} msg = {result.errMsg}");
HCDebugger.LogDebug($"支付失败: {result.errMsg} {result.errCode}");
},
complete = result =>
{
HCDebugger.LogDebug("支付完成");
HCDebugger.LogDebug($"支付完成: {result.errMsg} {result.errCode}");
}
};
WX.RequestMidasPayment(requestMidasPaymentOption);
}
});
}
public void Awarded(string orderID)
{
HCServer.Instance.OrderAwarded(orderID, ((code, msg, _) => { HCDebugger.LogDebug($"[Awarded] 上报结果: code ={code}"); }));
}
private string GenerateTradeNo()
{
// 微信客户端的订单号只要32位
var generateTradeNo = Guid.NewGuid().ToString().Replace("-", "");
HCDebugger.LogDebug($"[HCWxPurchase] [GenerateTradeNo] generateTradeNo = {generateTradeNo}");
return generateTradeNo;
}
/// <summary>
/// 检查订单列表,进行补单。
/// </summary>
private void CheckOrderList()
{
HCDebugger.LogDebug("[HCWxPurchase] [CheckOrderList] start");
var readAllPaymentArgs = ReadAllPaymentArgs();
if (readAllPaymentArgs.Count > 0)
{
HCSDKManager.Instance.LogEvent("CheckOrderList", "Count", readAllPaymentArgs.Count, "OrderList", OrderListInfoObjToString(readAllPaymentArgs));
}
foreach (var (orderId, paymentArgs) in readAllPaymentArgs)
{
HCDebugger.LogDebug($"[HCWxPurchase] [CheckOrderList] start : orderId = {orderId}");
if (paymentArgs.ext.ContainsKey(PayTypeH5) && (bool)paymentArgs.ext.GetValue(PayTypeH5, false))
{
HCServer.Instance.OrderQuery(orderId, callback: (code, msg, orderQueryResult) =>
{
if (code != 0 || orderQueryResult == null)
{
HCDebugger.LogError($"[HCWxPurchase] [CheckOrderList] error. orderId = {orderId} code = {code} msg = {msg}");
return;
}
switch (orderQueryResult.pay_status)
{
case HCServer.OrderQueryResult.PayStatusNotPaid:
HCDebugger.LogDebug($"[HCWxPurchase] [CheckOrderList] orderId = {orderId} pay_status = {orderQueryResult.pay_status}");
break;
case HCServer.OrderQueryResult.PayStatusPaid when HCSDKManager.Instance.OnPurchaseDone == null:
return;
case HCServer.OrderQueryResult.PayStatusPaid:
CallbackPay(orderId, paymentArgs.productName, paymentArgs.productId, 0, paymentArgs.gameExtraParam, false, orderQueryResult.game_extra_param, hcPaymentArgs: paymentArgs,
msg: $"pay_status = {orderQueryResult.pay_status}");
DeleteOrder(orderId);
break;
case HCServer.OrderQueryResult.PayStatusPaymentFailed:
DeleteOrder(orderId);
break;
}
});
}
else
{
ServerBuy(orderId, paymentArgs.productName, paymentArgs.money, (code, msg, data) => { });
}
}
}
private void ServerBuy(string orderId, string productName, int money, [CanBeNull] Action<int, string, HCServer.MiniPayResult> callback = null)
{
HCServer.Instance.MiniAppPay(orderId, productName, money, (code, msg, data) =>
{
HCDebugger.LogDebug($"支付成功后的服务器校验回调 code = {code} msg = {msg} data balance = {data.balance} order_no = {data.order_no} callback = {callback}");
callback?.Invoke(code, msg, data);
if (HCSDKManager.Instance.OnPurchaseDone == null)
{
HCDebugger.LogError("[HCWxPurchase] [ServerBuy] [MiniAppPay] OnPurchaseDone is null;");
}
// 如果服务器返回的了订单id那就直接给删除掉
var orderNo = data.order_no;
if (code == 0 && !string.IsNullOrEmpty(orderNo))
{
HCDebugger.LogDebug($"微信支付成功了,删除订单, orderNo = {orderNo}");
// DeleteOrder(orderId);
var paymentArgs = ReadPaymentArgsFromOrderId(orderNo);
paymentArgs.ext ??= new Dictionary<string, object>();
paymentArgs.ext[PayTypeH5] = true;
HCDebugger.LogDebug($"微信支付成功了,保存h5订单, orderNo = {orderNo} paymentArgs = {Json.Serialize(paymentArgs)}");
SaveOrder(orderId, paymentArgs);
// 查h5订单
h5callbackOrderStatus.Add(lastOrderId);
H5CheckOrderStatus();
InvokeRepeating("H5CheckOrderStatus", 2, 2);
}
else
{
HCDebugger.LogDebug("微信支付成功了,请求失败了。");
}
});
}
private void SaveOrder(string orderId, HCPaymentArgs paymentArgs)
{
HCDebugger.LogDebug($"[HCWxPurchase] [SaveOrder] orderId = {orderId}");
var readAllPaymentArgs = ReadAllPaymentArgs();
if (readAllPaymentArgs.ContainsKey(orderId))
{
readAllPaymentArgs.Remove(orderId);
}
readAllPaymentArgs[orderId] = paymentArgs;
var data = Save(readAllPaymentArgs);
HCDebugger.LogDebug($"[HCWxPurchase] [SaveOrder] orderId = {orderId} data = {data}");
}
private void DeleteOrder(string orderId)
{
HCDebugger.LogDebug($"[HCWxPurchase] [DeleteOrder] orderId = {orderId}");
var readAllPaymentArgs = ReadAllPaymentArgs();
if (readAllPaymentArgs.ContainsKey(orderId))
{
HCDebugger.LogDebug($"[HCWxPurchase] [DeleteOrder] orderId = {orderId} success");
readAllPaymentArgs.Remove(orderId);
}
var data = Save(readAllPaymentArgs);
HCDebugger.LogDebug($"[HCWxPurchase] [DeleteOrder] orderId = {orderId} data = {data}");
}
private static string Save(Dictionary<string, HCPaymentArgs> readAllPaymentArgs)
{
var saveString = OrderListInfoObjToString(readAllPaymentArgs);
HCTools.SavePlayerPrefsString("HCIPurchase", saveString);
return saveString;
}
private static string OrderListInfoObjToString(Dictionary<string, HCPaymentArgs> readAllPaymentArgs)
{
var saveData = new Dictionary<string, object>();
readAllPaymentArgs ??= new Dictionary<string, HCPaymentArgs>();
foreach (var (key, paymentArgs) in readAllPaymentArgs)
{
saveData[key] = new Dictionary<string, object>()
{
["productId"] = paymentArgs.productId,
["productName"] = paymentArgs.productName,
["gameExtraParam"] = paymentArgs.gameExtraParam,
["money"] = paymentArgs.money,
["ext"] = paymentArgs.ext ??= new Dictionary<string, object>()
};
}
var saveString = MiniJSON.Json.Serialize(saveData);
return saveString;
}
public HCPaymentArgs ReadPaymentArgsFromOrderId(string orderId)
{
return ReadAllPaymentArgs().GetValue(orderId, null);
}
private Dictionary<string, HCPaymentArgs> ReadAllPaymentArgs()
{
var result = new Dictionary<string, HCPaymentArgs>();
try
{
var playerPrefsString = HCTools.GetPlayerPrefsString("HCIPurchase");
HCDebugger.LogDebug($"[HCWxPurchase] [ReadAllPaymentArgs] playerPrefsString = {playerPrefsString}");
if (string.IsNullOrEmpty(playerPrefsString))
{
return result;
}
var deserialize = (Dictionary<string, object>)MiniJSON.Json.Deserialize(playerPrefsString);
foreach (var (key, value) in deserialize)
{
var data = value as Dictionary<string, object>;
result[key] = new HCPaymentArgs
{
productId = (string)data.GetValue("productId", ""),
gameExtraParam = (string)data.GetValue("gameExtraParam", ""),
productName = (string)data.GetValue("productName", ""),
money = int.Parse("" + data.GetValue("money", 0)),
ext = (Dictionary<string, object>)data.GetValue("ext", new Dictionary<string, object>())
};
}
}
catch (Exception e)
{
// ignored
HCDebugger.LogDebug($"[HCWxPurchase] [ReadAllPaymentArgs] Error = {e.Message}");
}
return result;
}
}
}
#endif