using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using Sog; using LitJson; using ProtoCSStruct; using Sog.Crypto; namespace HttpProxyPay { public class HeroUSDKSvc { // 支付发货追踪url private static string init_payTrackUrl = "https://data-track-global.yingxiong.com/v1/order/data"; private static string _payTrackUrl; private static string _postContentType = "multipart/form-data; boundary=-----------------"; public static string[] _PCODE = new string[(int)HeroUSDKProj.Max]; public static string[] _APP_KEY = new string[(int)HeroUSDKProj.Max]; public static string[] _CALLBACK_KEY = new string[(int)HeroUSDKProj.Max]; private static long lastTickTime = 0; private static void InitDefaultProjectInfo() { // 游戏产品在SDK平台的应用ID, 默认值只是为了方便没有添加配置项的私人服务器 _PCODE[(int)HeroUSDKProj.Min] = "0"; _PCODE[(int)HeroUSDKProj.SEA] = "17310"; _PCODE[(int)HeroUSDKProj.JP] = "17303"; _PCODE[(int)HeroUSDKProj.KR] = "17323"; _PCODE[(int)HeroUSDKProj.ZH] = "17332"; _PCODE[(int)HeroUSDKProj.JP2] = "17343"; _PCODE[(int)HeroUSDKProj.EN] = "17344"; // 游戏产品在SDK平台的应用私钥, 默认值只是为了方便没有添加配置项的私人服务器 _APP_KEY[(int)HeroUSDKProj.Min] = "invalid_key"; _APP_KEY[(int)HeroUSDKProj.SEA] = "2dl4v39v93dmexqcvxku"; _APP_KEY[(int)HeroUSDKProj.JP] = "7czh206jaoh27zp5cv9x"; _APP_KEY[(int)HeroUSDKProj.KR] = "qqsm0uqbnx2omt2v7ox8"; _APP_KEY[(int)HeroUSDKProj.ZH] = "p6stvkxm5zeasoqfvx1d"; _APP_KEY[(int)HeroUSDKProj.JP2] = "bzdmwhx75nv34yn5eex0"; _APP_KEY[(int)HeroUSDKProj.EN] = "ghptn7zb63ys6oxd753v"; // 支付回调私钥, 默认值只是为了方便没有添加配置项的私人服务器 _CALLBACK_KEY[(int)HeroUSDKProj.Min] = "invalid_key"; _CALLBACK_KEY[(int)HeroUSDKProj.SEA] = "35uydxhx443r0gn9de7c"; _CALLBACK_KEY[(int)HeroUSDKProj.JP] = "40nl3jnvf7e3hz84xluh"; _CALLBACK_KEY[(int)HeroUSDKProj.KR] = "wqiep8e0p5m8sx8ducd0"; _CALLBACK_KEY[(int)HeroUSDKProj.ZH] = "8ib67ridw2ga4c9agejf"; _CALLBACK_KEY[(int)HeroUSDKProj.JP2] = "v5js01u9s5ejt3s86cjr"; _CALLBACK_KEY[(int)HeroUSDKProj.EN] = "5ape3axcd935cel0z9a0"; } public static void Init(HttpProxyPayServerConfig config) { string payUrl = config.heroUsdk_payCheckUrl; if (! string.IsNullOrEmpty(payUrl)) { _payTrackUrl = payUrl; } else { _payTrackUrl = init_payTrackUrl; } TraceLog.Trace("HeroUSDKSvc.Init payTrackUrl {0}", _payTrackUrl); _postContentType += DateTime.Now.Ticks.ToString("x"); InitProjectInfo(config); } public static void InitProjectInfo(HttpProxyPayServerConfig config) { // 默认使用代码中的默认值, 方便没有配置的私人服务器 InitDefaultProjectInfo(); // 用config中的配置项替换默认值 if (config.heroUsdkProjCfg == null || config.heroUsdkProjCfg.Count == 0) { return; } foreach (HeroUsdkProjCfgOne one in config.heroUsdkProjCfg) { TraceLog.Trace("HeroUSDKSvc.InitProjectInfo cpId {0} cpName {1} pcode {2} appKey {3} callbackKey {4}" , one.cpId, one.cpName, one.pcode, one.appKey, one.callbackKey); if (0 <= one.cpId && one.cpId < _PCODE.Length && !string.IsNullOrEmpty(one.pcode)) { _PCODE[one.cpId] = one.pcode; } if (0 <= one.cpId && one.cpId < _APP_KEY.Length && !string.IsNullOrEmpty(one.appKey)) { _APP_KEY[one.cpId] = one.appKey; } if (0 <= one.cpId && one.cpId < _CALLBACK_KEY.Length && !string.IsNullOrEmpty(one.callbackKey)) { _CALLBACK_KEY[one.cpId] = one.callbackKey; } } for (int i = (int)HeroUSDKProj.Min + 1; i < (int)HeroUSDKProj.Max; i++) { if (_PCODE[i] != null) { TraceLog.Trace("HeroUSDKSvc.InitProjectInfo {0} pcode {1}", (HeroUSDKProj)i, _PCODE[i]); } if (_APP_KEY[i] != null) { TraceLog.Trace("HeroUSDKSvc.InitProjectInfo {0} appKey {1}", (HeroUSDKProj)i, _APP_KEY[i]); } if (_CALLBACK_KEY[i] != null) { TraceLog.Trace("HeroUSDKSvc.InitProjectInfo {0} callbackKey {1}", (HeroUSDKProj)i, _CALLBACK_KEY[i]); } } } public static void Tick(long nowMs) { // 启动30s后再开始tick if (lastTickTime == 0) { lastTickTime = nowMs - 30000; return; } // 60s检查一次是否有未提交的http请求 if (nowMs < lastTickTime + 60000) { return; } var req = new SSPayHeroSelectHttpContentReq(); uint dbServerID = DBServerSelect.GetDBServerID(0); HttpProxyPayServerUtils.GetPacketSender().SendToServerByID(dbServerID, (int)SSGameMsgID.PayHeroSelectHttpContentReq, ref req, 0); lastTickTime = nowMs; } public static void OnPayAddItemNotify(ref SSPayAddPlayerItemNotify notify) { var dataParam = new Dictionary(); dataParam["eventType"] = "sdk_order_callback"; dataParam["channelId"] = notify.ChannelId.ToString(); dataParam["cUid"] = notify.CUid.GetString(); dataParam["cName"] = notify.CName.GetString(); dataParam["orderNo"] = notify.OrderNo.GetString(); dataParam["cpOrderId"] = notify.CpOrderId.GetString(); dataParam["goodsId"] = notify.GoodsId.GetString(); dataParam["amount"] = notify.Amount.ToString(); dataParam["unit"] = notify.Unit.GetString(); dataParam["payTime"] = notify.PayTime.ToString(); dataParam["roleName"] = notify.RoleName.GetString(); dataParam["roleId"] = notify.RoleId.ToString(); dataParam["serverName"] = notify.ServerName.GetString(); dataParam["serverId"] = notify.ServerId.ToString(); dataParam["roleLevel"] = notify.RoleLevel.ToString(); dataParam["vipLevel"] = notify.VipLevel.ToString(); dataParam["totalCharge"] = Convert.ToDouble(notify.TotalCharge * 1.0 / 100).ToString(); dataParam["getTime"] = notify.GetTime.ToString(); dataParam["extraGet1"] = notify.ExtraGet1.ToString(); dataParam["extraGet2"] = notify.ExtraGet2.ToString(); dataParam["moneyType"] = notify.MoneyType.ToString(); dataParam["paymentMethod"] = notify.PaymentMethod.ToString(); int proj = (int)GetProject(notify.ProductId.GetString()); var allParams = new Dictionary(); allParams["pcode"] = _PCODE[proj]; allParams["data"] = HeroUSDKSecurity.CreateData(dataParam); allParams["timestamp"] = HttpProxyPayServerUtils.GetTimeSecond().ToString(); // sign以外的字段全部添加到上面用于计算签名 allParams["sign"] = HeroUSDKSecurity.CalcSign(_APP_KEY[proj], allParams); StringBuilder sb = new StringBuilder(); foreach (KeyValuePair pair in allParams) { sb.Append(pair.Key).Append('&').Append(pair.Value).Append('|'); } // http请求保存至DB后再post var saveReq = new SSPayHeroSaveHttpContentReq(); saveReq.Http.Method = 2; // post saveReq.Http.Url.SetString(_payTrackUrl); saveReq.Http.Content.SetString(JsonMapper.ToJson(allParams)); saveReq.Http.OrderId.SetString(notify.CpOrderId.GetPtr()); saveReq.Http.Uid = notify.RoleId; saveReq.Http.IsTestPay = notify.IsTestPay; uint dbServerID = DBServerSelect.GetDBServerID(0); HttpProxyPayServerUtils.GetPacketSender().SendToServerByID(dbServerID, (int) SSGameMsgID.PayHeroSaveHttpContentReq, ref saveReq, notify.RoleId); } public static void PostHttpRequest(ref SSHttpRequest http) { int ret = 0; try { if (http.IsTestPay == 0) { ret = PostHttpRequestInner(ref http); } } catch (Exception e) { ret = -1; TraceLog.Exception(e); } if (ret == 0) { string orderId = http.OrderId.GetString(); TraceLog.Trace("HeroUSDKSvc.PostHttpRequest orderId {0} notify hero usdk server succ", orderId); var notify = new SSPayHeroDeleteHttpContentNotify { Uid = http.Uid }; notify.OrderId.SetString(orderId); uint dbServerID = DBServerSelect.GetDBServerID(0); HttpProxyPayServerUtils.GetPacketSender().SendToServerByID(dbServerID, (int)SSGameMsgID.PayHeroDeleteHttpContentNotify, ref notify, http.Uid); } } private static int PostHttpRequestInner(ref SSHttpRequest http) { var allParams = new Dictionary(); { JsonData contentJson = JsonMapper.ToObject(http.Content.GetString()); var keys = contentJson.Keys; foreach (var key in keys) { JsonData value = contentJson[key]; string strValue = value.ToString(); allParams.Add(key, strValue); TraceLog.Trace("HeroUSDKSvc.PostHttpRequestInner key {0} value {1}", key, strValue); } } /* string[] kvpair = http.Content.GetString().Split(','); foreach (string one in kvpair) { if (!string.IsNullOrEmpty(one)) { string[] kv = one.Split(':'); if (kv != null && kv.Length == 2) { allParams.Add(kv[0], kv[1]); TraceLog.Trace("HeroUSDKSvc.PostHttpRequestInner key {0} value {1}", kv[0], kv[1]); } } }*/ var content = new FormUrlEncodedContent(allParams); string ret = HttpUtils.HttpPost(http.Url.GetString(), content, out bool exception); if (ret == null) { TraceLog.Error("HeroUSDKSvc.PostHttpRequestInner HttpPost return null query failed"); return -1; } string orderId = http.OrderId.GetString(); TraceLog.Trace("HeroUSDKSvc.PostHttpRequestInner orderId {0} ret {1}", orderId, ret); JsonData jsonData = JsonMapper.ToObject(ret); JsonData codeData = jsonData["code"]; int code = codeData != null ? (int)codeData : -1; if (code != 0) { TraceLog.Error("HeroUSDKSvc.PostHttpRequest res code {0} not 0", code); return -1; } JsonData msg = jsonData["msg"]; if (msg == null) { TraceLog.Error("HeroUSDKSvc.PostHttpRequest res msg is null"); return -1; } string resMsg = msg.ToString(); if (resMsg != "Success") { TraceLog.Error("HeroUSDKSvc.PostHttpRequest res msg {0} not Success", resMsg); return -1; } return 0; } public static string GetProjectCode(HeroUSDKProj proj) { if (0 <= (int)proj && (int)proj < _PCODE.Length) { return _PCODE[(int) proj]; } return null; } public static HeroUSDKProj GetProject(string pcode) { for (int i = 0; i < _PCODE.Length; i++) { if (_PCODE[i] == pcode) { return (HeroUSDKProj)i; } } return HeroUSDKProj.Min; } } }