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

484 lines
24 KiB
C#
Raw Permalink 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_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