using MyCode.Project.Infrastructure.Common; using MyCode.Project.Infrastructure.Utils; using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Web; using System.Xml; using Wolf.ExternalService.CMBPay.Common; using Wolf.ExternalService.CMBPay.Core; using Wolf.ExternalService.CMBPay.Core.Events; using Wolf.ExternalService.CMBPay.Core.Utils; using static MyCode.Project.Infrastructure.Constant.LxmConst; namespace MyCode.Project.Infrastructure.PayModels { /// /// 招行支付的底层类扩展, /// 方法1 增加查询订单实际支付情况的接口 /// public class ExtendedGateway : Gateway { #region 字段 /// /// 统一下单 接口类型 /// private const string UnifiedOrderApiType = "unified.trade.micropay"; /// /// 查询订单 接口类型 /// private const string QueryApiType = "unified.trade.query"; /// /// 关闭订单 接口类型 /// private const string CloseOrderApiType = "unified.micropay.reverse"; #endregion #region 属性 /// /// 通知 /// public new Notify Notify => (Notify)base.Notify; #endregion #region 构造函数 /// /// 初始化一个类型的实例 /// public ExtendedGateway() : this(new Merchant()) { } /// /// 初始化一个类型的实例 /// /// 商家数据 public ExtendedGateway(Merchant merchant) : base(merchant) { } #endregion #region 查询订单 /// /// 每隔5秒轮询判断用户各种支付的真实支付情况,总共轮询5次 /// /// 辅助接口 private void PollQueryTradeState(IAuxiliary auxiliary) { for (int i = 0; i < 5; i++) { Thread.Sleep(5000); BuildQuery(auxiliary); string dsds = Notify.TradeState.ToLower(); if (IsSuccessPay && Notify.TradeState.ToLower() == SUCCESS) { OnPaymentSucceed(new PaymentSucceedEventArgs(this)); return; } } } /// /// 异步每隔5秒轮询判断用户是否支付,总共轮询5次 /// /// 辅助接口 /// private async Task PollQueryTradeStateAsync(IAuxiliary auxiliary) { await Task.Run(() => PollQueryTradeState(auxiliary)); } /// /// 查询订单的相关平台参数 /// /// public void QueryOrderPay(Auxiliary query) { Task.Run(async () => { await PollQueryTradeStateAsync(new Auxiliary() { TransactionId = query.TransactionId, OutTradeNo = query.OutTradeNo }); }) .GetAwaiter() .GetResult(); } /// /// 生成查询订单参数 /// /// 辅助参数 /// private INotify BuildQuery(IAuxiliary auxiliary) { InitQuery(auxiliary); Commit(); return Notify; } /// /// 初始化查询订单参数 /// /// 辅助参数 private void InitQuery(IAuxiliary auxiliary) { Merchant.Service = QueryApiType; InitAuxiliaryParameter(GatewayAuxiliaryType.Query, auxiliary); } #endregion /// /// 初始化订单参数 /// /// 操作 private void InitOrderParameter(Action action = null) { GatewayData.Clear(); Merchant.NonceStr = Util.GenerateNonceStr(); Merchant.DeviceInfo = Wolf.ExternalService.CMBPay.Common.Constant.WEB; action?.Invoke(); GatewayData.Add(Merchant, StringCase.Snake); GatewayData.Add(Order, StringCase.Snake); AddSign(); } /// /// 初始化辅助参数 /// /// 辅助类型 /// 辅助参数 private void InitAuxiliaryParameter(GatewayAuxiliaryType gatewayAuxiliaryType, IAuxiliary auxiliary) { auxiliary.Validate(gatewayAuxiliaryType); Merchant.NonceStr = Util.GenerateNonceStr(); //Merchant.NotifyUrl = ""; GatewayData.Add(Merchant, StringCase.Snake); GatewayData.Add(auxiliary, StringCase.Snake); AddSign(); } /// /// 转换通知对象 /// /// protected override INotify ToObject() { return GatewayData.ToObject(StringCase.Snake); } /// /// 转换通知对象 /// /// protected override async Task ToObjectAsync() { return await GatewayData.ToObjectAsync(StringCase.Snake); } #region testfuyoupay(富友扫客户支付码支付) /// /// 富友扫客户支付码支付 /// /// /// 支付类型 ALIPAY , WECHAT, QQ(QQ 钱包), UNIONPAY(银联二维码) , BESTPAY(翼支付) /// public string FuiouScanpPay(Wolf.ExternalService.CMBPay.Barcodepay.Order order, string order_type) { Dictionary map = new Dictionary(); map.Add("version", "1.0"); map.Add("ins_cd", FuiouPayConst.ins_cd); map.Add("mchnt_cd", order.OpUserId); map.Add("term_id", FuiouPayConst.term_id); map.Add("random_str", Guid.NewGuid().ToString("N")); map.Add("sign", ""); map.Add("order_type", order_type); map.Add("goods_des", order.Body); map.Add("goods_detail", ""); map.Add("reserved_expire_minute", "1440"); map.Add("addn_inf", order.Attach); map.Add("auth_code", order.AuthCode); map.Add("mchnt_order_no", order.OutTradeNo); map.Add("curr_type", ""); map.Add("order_amt", order.Amount.ToString()); map.Add("term_ip", FuiouPayConst.term_ip); map.Add("txn_begin_ts", DateTime.Now.ToString("yyyyMMddhhmmss")); map.Add("goods_tag", ""); map.Add("sence", "1"); map.Add("reserved_sub_appid", ""); map.Add("reserved_limit_pay", ""); string result = run(map, FuiouPayConst.fuiouScanpPayUrl); return result; } #endregion private static string run(Dictionary map, string url) { Dictionary reqs = new Dictionary(); Dictionary nvs = new Dictionary(); foreach (KeyValuePair kvp in map) { reqs.Add(kvp.Key, kvp.Value); } string sign = FuYouPayUtils.getSign(reqs); reqs.Remove("sign"); reqs.Add("sign", sign); XmlDocument doc = new XmlDocument(); XmlElement elem = doc.CreateElement("xml"); doc.AppendChild(elem); foreach (KeyValuePair kvp in reqs) { XmlElement elem2 = doc.CreateElement(kvp.Key); elem2.InnerText = kvp.Value; elem.AppendChild(elem2); } string reqBody = "" + doc.OuterXml; LogHelper.Info("请求报文:" + reqBody); reqBody = FuYouPayUtils.UrlEncode(reqBody, Encoding.GetEncoding(FuiouPayConst.charset)); nvs.Add("req", reqBody); StringBuilder result = new StringBuilder(""); Infrastructure.Utils.HttpUtils httpUtils = new HttpUtils(); httpUtils.post(url, nvs, result); string data = HttpUtility.UrlDecode(result.ToString(), Encoding.GetEncoding(FuiouPayConst.charset)); LogHelper.Info("在线支付返回报文:" + data); return data; } #region FuyouOnlinePay(富友客户扫商家的二维码支付) /// /// 富友客户扫商家的二维码支付 /// /// /// 支付类型 ALIPAY , WECHAT, QQ(QQ 钱包), UNIONPAY(银联二维码) , BESTPAY(翼支付) /// public string FuiouOnlinePay(FuiouOrder order, string order_type) { Dictionary map = new Dictionary(); map.Add("order_type", order_type); map.Add("goods_des", order.Body); map.Add("reserved_expire_minute", "1440"); map.Add("addn_inf", order.Attach); map.Add("mchnt_order_no", order.OutTradeNo); map.Add("order_amt", order.Amount.ToString()); map.Add("version", "1.0"); map.Add("ins_cd", FuiouPayConst.ins_cd); map.Add("mchnt_cd", order.OpUserId); //map.Add("mchnt_cd", FuiouPayConst.mchnt_cd); map.Add("term_id", FuiouPayConst.term_id); map.Add("random_str", Guid.NewGuid().ToString("N")); map.Add("sign", ""); map.Add("goods_detail", ""); map.Add("curr_type", ""); map.Add("term_ip", order.SpbillCreateIp);//FuiouPayConst.term_ip); map.Add("txn_begin_ts", DateTime.Now.ToString("yyyyMMddhhmmss")); map.Add("goods_tag", ""); map.Add("notify_url", FuiouPayConst.notify_url); map.Add("reserved_sub_appid", ""); map.Add("reserved_limit_pay", ""); map.Add("reserved_terminal_info", order.DeviceInfo); string result = run(map, FuiouPayConst.fuiouOnlinePayUrl); XmlDocument doc = new XmlDocument(); doc.LoadXml(result); string ifok = doc.SelectSingleNode("/xml/result_code").InnerText; if (ifok == "000000") result = doc.SelectSingleNode("/xml/qr_code").InnerText; else result = doc.SelectSingleNode("/xml/result_msg").InnerText; return result; } #endregion /// /// 解析富友的XML字符串为可读文本 /// /// /// public string GetXMLString(string res) { res = HttpUtility.UrlDecode(res, Encoding.GetEncoding(FuiouPayConst.charset)); return res; } #region FuyouWXOnlinePay(富友 公众号/服务窗统一下单) /// /// 富友 公众号/服务窗统一下单 /// /// /// 支付类型 ALIPAY , JSAPI, QQ(QQ 钱包), UNIONPAY(银联二维码) , BESTPAY(翼支付) LETPAY-小程序 /// /// /// public string FuyouWXOnlinePay(Wolf.ExternalService.CMBPay.Barcodepay.Order order, string order_type, string openid, string appid) { Dictionary map = new Dictionary(); map.Add("version", "1.0"); map.Add("ins_cd", FuiouPayConst.ins_cd); map.Add("mchnt_cd", order.OpUserId); map.Add("term_id", FuiouPayConst.term_id); map.Add("random_str", Guid.NewGuid().ToString("N")); map.Add("sign", ""); map.Add("goods_des", order.Body); map.Add("goods_detail", ""); map.Add("goods_tag", ""); map.Add("txn_begin_ts", DateTime.Now.ToString("yyyyMMddhhmmss")); map.Add("notify_url", FuiouPayConst.notify_url); map.Add("limit_pay", ""); if (order_type == "WECHAT") order_type = "JSAPI"; else if (order_type == "ALIPAY") order_type = "FWC"; else if (order_type == "LETPAY") order_type = "LETPAY"; map.Add("trade_type", order_type); map.Add("addn_inf", order.Attach); map.Add("openid", ""); map.Add("product_id", ""); map.Add("sub_openid", openid); map.Add("sub_appid", appid); map.Add("reserved_expire_minute", "1440"); map.Add("mchnt_order_no", order.OutTradeNo); map.Add("curr_type", "CNY"); map.Add("order_amt", order.Amount.ToString()); map.Add("term_ip", FuiouPayConst.term_ip); string result = run(map, FuiouPayConst.fuiouOnlineWxPayUrl); LogHelper.Info(result); XmlDocument doc = new XmlDocument(); doc.LoadXml(result); string ifok = doc.SelectSingleNode("/xml/result_code").InnerText; if (ifok == "000000") result = doc.SelectSingleNode("/xml/reserved_pay_info").InnerText; else result = doc.SelectSingleNode("/xml/result_msg").InnerText; return result; } #endregion #region FuyouOnlinePay(富友主动查询订单支付状态) /// /// 富友主动查询订单支付状态 /// /// 商户订单交易号 /// 支付类型 ALIPAY , WECHAT, QQ(QQ 钱包), UNIONPAY(银联二维码) , BESTPAY(翼支付) /// public string FuyouQueryPay(string mchnt_order_no, string order_type, string mchnt_cd = "0002900F0370588") { Dictionary map = new Dictionary(); map.Add("order_type", order_type); map.Add("mchnt_order_no", mchnt_order_no); map.Add("version", "1.0"); map.Add("ins_cd", FuiouPayConst.ins_cd); map.Add("mchnt_cd", mchnt_cd); map.Add("term_id", FuiouPayConst.term_id); map.Add("random_str", Guid.NewGuid().ToString("N")); map.Add("sign", ""); string result = run(map, FuiouPayConst.fuiou_23_url); //XmlDocument doc = new XmlDocument(); //doc.LoadXml(result); //string ifok = doc.SelectSingleNode("/xml/result_code").InnerText; //if (ifok == "000000") // result = doc.SelectSingleNode("/xml/trans_stat").InnerText; //else // result = doc.SelectSingleNode("/xml/result_msg").InnerText; return result; } #endregion #region FuYouReturnMoney(富友退款申请) /// /// 富友退款申请 /// public string FuYouReturnMoney(string OutTradeNo, string order_type, string refund_order_no , decimal total_amt, decimal refund_amt, string mchnt_cd = "") { string total = (total_amt * 100).ToString("0"); string refund = (refund_amt * 100).ToString("0"); Dictionary map = new Dictionary(); map.Add("version", "1.0"); map.Add("ins_cd", FuiouPayConst.ins_cd); map.Add("mchnt_cd", mchnt_cd); map.Add("term_id", FuiouPayConst.term_id); map.Add("random_str", Guid.NewGuid().ToString("N")); map.Add("sign", ""); map.Add("order_type", order_type); map.Add("mchnt_order_no", OutTradeNo); map.Add("total_amt", total); map.Add("operator_id", ""); map.Add("reserved_fy_term_id", ""); map.Add("refund_amt", refund); map.Add("refund_order_no", refund_order_no); string result = run(map, FuiouPayConst.fuiou_24_url); result = GetXMLString(result); //XmlDocument doc = new XmlDocument(); //doc.LoadXml(result); //string ifok = doc.SelectSingleNode("/xml/result_code").InnerText; //if (ifok == "000000") // result = doc.SelectSingleNode("/xml/reserved_refund_amt").InnerText; //else // result = doc.SelectSingleNode("/xml/result_msg").InnerText; return result; } #endregion #region FuYouRefundQuery(富友退款申请进度查询) /// /// 富友退款申请进度查询 /// /// 商户退款单号 /// 商户号, 富友分配的商户号 /// public string FuYouRefundQuery(string refund_order_no , string mchnt_cd = "") { Dictionary map = new Dictionary(); map.Add("version", "1.0"); map.Add("ins_cd", FuiouPayConst.ins_cd); map.Add("mchnt_cd", mchnt_cd); map.Add("term_id", FuiouPayConst.term_id); map.Add("refund_order_no", refund_order_no); map.Add("random_str", Guid.NewGuid().ToString("N")); map.Add("sign", ""); string result = run(map, FuiouPayConst.fuiou_30_url); result = GetXMLString(result); //XmlDocument doc = new XmlDocument(); //doc.LoadXml(result); //string ifok = doc.SelectSingleNode("/xml/result_code").InnerText; //if (ifok == "000000") // result = doc.SelectSingleNode("/xml/reserved_refund_amt").InnerText; //else // result = doc.SelectSingleNode("/xml/result_msg").InnerText; return result; } #endregion } }