799 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			799 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using APT.Infrastructure.Core;
 | 
						||
using Newtonsoft.Json;
 | 
						||
using System;
 | 
						||
using System.Collections.Generic;
 | 
						||
using System.Diagnostics;
 | 
						||
using System.Diagnostics.Contracts;
 | 
						||
using System.IO;
 | 
						||
using System.Linq;
 | 
						||
using System.Net;
 | 
						||
using System.Net.Http;
 | 
						||
using System.Net.Http.Headers;
 | 
						||
using System.Net.Security;
 | 
						||
using System.Security.Cryptography.X509Certificates;
 | 
						||
using System.Text;
 | 
						||
using System.Text.Json;
 | 
						||
using System.Text.Json.Serialization;
 | 
						||
using System.Threading.Tasks;
 | 
						||
using System.Xml.Linq;
 | 
						||
using APT.Infrastructure.Api;
 | 
						||
 | 
						||
namespace APT.Utility
 | 
						||
{
 | 
						||
    public class WeChatPayHelper
 | 
						||
    {
 | 
						||
        // private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
 | 
						||
 | 
						||
        public static WeixinToken GetToken()
 | 
						||
        {
 | 
						||
            var appId = LibUtils.ToString(ConfigurationManager.WexinSettings["AppId"]).ToString();
 | 
						||
            var secret = LibUtils.ToString(ConfigurationManager.WexinSettings["AppSecret"]).ToString();
 | 
						||
            var toenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + secret;
 | 
						||
            var res = HttpMethods.Get(toenUrl);
 | 
						||
            WeixinToken token = JsonConvert.DeserializeObject<WeixinToken>(res);
 | 
						||
            if (token == null || !string.IsNullOrEmpty(token.errcode))
 | 
						||
                throw new Exception("获取token失败");
 | 
						||
            APT.Infrastructure.Api.AppContext.WxToken = token;
 | 
						||
            return token;
 | 
						||
        }
 | 
						||
        public class WxMessageModel
 | 
						||
        {
 | 
						||
            public string touser { get; set; }
 | 
						||
            public string template_id { get; set; }
 | 
						||
            public dynamic data { get; set; }
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
        public class WxMessageReturnModel
 | 
						||
        {
 | 
						||
            public int errcode { get; set; }
 | 
						||
            public string errmsg { get; set; }
 | 
						||
 | 
						||
        }
 | 
						||
        public static int SendWxMessage(string openid, string token, string tmpId, dynamic data)
 | 
						||
        {
 | 
						||
            var msgUrl = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token;
 | 
						||
            var sendObj = new WxMessageModel
 | 
						||
            {
 | 
						||
                template_id = tmpId,
 | 
						||
                touser = openid,
 | 
						||
                data = data,
 | 
						||
            };
 | 
						||
            var sendStr = JsonConvert.SerializeObject(sendObj);
 | 
						||
            var returnStr = HttpMethods.Post(msgUrl, sendStr);
 | 
						||
            var retObj = JsonConvert.DeserializeObject<WxMessageReturnModel>(returnStr);
 | 
						||
            return retObj.errcode;
 | 
						||
        }
 | 
						||
 | 
						||
        public static PayRequesEntity Unifiedorder(string openid, int totalfee, string orderNo,string orderType, string macId, string wxPaykey)
 | 
						||
        {
 | 
						||
            //var PayUrl = AppSetting.Load().WechatPayStrings.FirstOrDefault().UnifiedorderURL;
 | 
						||
            //获取统一下单参数
 | 
						||
            var param = GetUnifiedOrderParam(openid, orderNo, totalfee, orderType, macId, wxPaykey);
 | 
						||
            //_logger.Info(() => "微信支付统一下单 发送参数为 " + param + "");
 | 
						||
            //统一下单后拿到的xml结果
 | 
						||
 | 
						||
            var payResXML = HttpMethods.Post(LibUtils.ToString(ConfigurationManager.WexinSettings["UnifiedorderURL"]).ToString(), param);
 | 
						||
            //_logger.Info(() => "微信支付统一下单 返回参数为 " + payResXML + "");
 | 
						||
            var payRes = XDocument.Parse(payResXML);
 | 
						||
            var root = payRes.Element("xml");
 | 
						||
            var res = GetPayRequestParam(root, wxPaykey);
 | 
						||
            //_logger.Info(() => "微信支付统一下单 参数实体为 " + JsonConvert.SerializeObject(res) + "");
 | 
						||
            return res;
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        /// 取消订单退款接口
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="totalfee"></param>
 | 
						||
        /// <param name="refundfee"></param>
 | 
						||
        /// <param name="orderNo"></param>
 | 
						||
        /// <param name="code"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public static bool Cancelorder(int totalfee, int refundfee, string orderNo, string code)
 | 
						||
        {
 | 
						||
            //var PayUrl = AppSetting.Load().WechatPayStrings.FirstOrDefault().UnifiedorderURL;
 | 
						||
            //获取统一下单参数
 | 
						||
            var param = GetCancelOrderParam(orderNo, code, totalfee, refundfee);
 | 
						||
            //_logger.Info(() => "微信支付统一下单 发送参数为 " + param + "");
 | 
						||
            //统一下单后拿到的xml结果
 | 
						||
 | 
						||
            var payResXML = HttpMethods.PostByCert(param, LibUtils.ToString(ConfigurationManager.WexinSettings["CancelorderURL"]).ToString(), true, 5);
 | 
						||
            //_logger.Info(() => "微信支付统一下单 返回参数为 " + payResXML + "");
 | 
						||
            var payRes = XDocument.Parse(payResXML);
 | 
						||
            var root = payRes.Element("xml");
 | 
						||
            return GetCancelOrderParam(root);
 | 
						||
            //_logger.Info(() => "微信支付统一下单 参数实体为 " + JsonConvert.SerializeObject(res) + "");
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        /// 取消订单退款接口
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="totalfee"></param>
 | 
						||
        /// <param name="refundfee"></param>
 | 
						||
        /// <param name="orderNo"></param>
 | 
						||
        /// <param name="code"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public static bool CancelorderByTenant(int totalfee, int refundfee, string orderNo, string code, string orderType, string macId, string wxPaykey,string certpath,string certpassword)
 | 
						||
        {
 | 
						||
            //var PayUrl = AppSetting.Load().WechatPayStrings.FirstOrDefault().UnifiedorderURL;
 | 
						||
            //获取统一下单参数
 | 
						||
            var param = GetCancelOrderParamByTenant(orderNo, code, totalfee, refundfee ,orderType, macId, wxPaykey);
 | 
						||
            //_logger.Info(() => "微信支付统一下单 发送参数为 " + param + "");
 | 
						||
            //统一下单后拿到的xml结果
 | 
						||
 | 
						||
            var payResXML = HttpMethods.PostByCertByTenant(param, 
 | 
						||
                    LibUtils.ToString(ConfigurationManager.WexinSettings["CancelorderURL"]).ToString(), true, 5, certpath, certpassword);
 | 
						||
            //_logger.Info(() => "微信支付统一下单 返回参数为 " + payResXML + "");
 | 
						||
            var payRes = XDocument.Parse(payResXML);
 | 
						||
            var root = payRes.Element("xml");
 | 
						||
            return GetCancelOrderParam(root);
 | 
						||
            //_logger.Info(() => "微信支付统一下单 参数实体为 " + JsonConvert.SerializeObject(res) + "");
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        /// 微信转账到零钱接口
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="orderNo">单号</param>
 | 
						||
        /// <param name="openid">openId</param>
 | 
						||
        /// <param name="username">用户名</param>
 | 
						||
        /// <param name="fee">金额</param>
 | 
						||
        /// <param name="desc">备注</param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public static bool PayforChange(string orderNo, string openid, string username, int fee, string desc)
 | 
						||
        {
 | 
						||
            //var PayUrl = AppSetting.Load().WechatPayStrings.FirstOrDefault().UnifiedorderURL;
 | 
						||
            //获取统一下单参数
 | 
						||
            var param = GetPayforChangeParam(orderNo, openid, username, fee, desc);
 | 
						||
            //_logger.Info(() => "微信支付统一下单 发送参数为 " + param + "");
 | 
						||
            //统一下单后拿到的xml结果
 | 
						||
 | 
						||
            var payResXML = HttpMethods.PostByCert(param, LibUtils.ToString(ConfigurationManager.WexinSettings["PayForChangeUrl"]).ToString(), true, 5);
 | 
						||
            //_logger.Info(() => "微信支付统一下单 返回参数为 " + payResXML + "");
 | 
						||
            var payRes = XDocument.Parse(payResXML);
 | 
						||
            var root = payRes.Element("xml");
 | 
						||
            return GetCancelOrderParam(root);
 | 
						||
            //_logger.Info(() => "微信支付统一下单 参数实体为 " + JsonConvert.SerializeObject(res) + "");
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 取统一下单的请求参数
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="openid"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        private static string GetUnifiedOrderParam(string openid, string orderNo, int totalfee, string orderType, string mch_id, string wxPaykey)
 | 
						||
        {
 | 
						||
            string appid = LibUtils.ToString(ConfigurationManager.WexinSettings["AppId"]);
 | 
						||
            string secret = LibUtils.ToString(ConfigurationManager.WexinSettings["AppSecret"]);
 | 
						||
            //string mch_id = LibUtils.ToString(ConfigurationManager.WexinSettings["Mch_ID"]);
 | 
						||
 | 
						||
            string ip = LibUtils.ToString(ConfigurationManager.WexinSettings["IP"]);
 | 
						||
            string PayResulturl = LibUtils.ToString(ConfigurationManager.WexinSettings["WxPayResultUrl"]);
 | 
						||
 | 
						||
            string strcode = "充电-下单";////商品描述交易字段格式根据不同的应用场景按照以下格式:APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。
 | 
						||
            byte[] buffer = Encoding.UTF8.GetBytes(strcode);
 | 
						||
            string body = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
 | 
						||
            System.Random Random = new System.Random();
 | 
						||
            var dic = new Dictionary<string, string>
 | 
						||
                {
 | 
						||
                    {"appid", appid},
 | 
						||
                    {"mch_id", mch_id},
 | 
						||
                    {"nonce_str", GetRandomString(20)/*Random.Next().ToString()*/},
 | 
						||
                    {"body",body},
 | 
						||
                    {"out_trade_no",orderNo+"_"+totalfee+"_" +orderType},//商户自己的订单号码
 | 
						||
                    {"total_fee",totalfee.ToString()},
 | 
						||
                    {"spbill_create_ip",ip},//服务器的IP地址
 | 
						||
                    {"notify_url",PayResulturl},//异步通知的地址,不能带参数
 | 
						||
                    {"trade_type","JSAPI" },
 | 
						||
                    {"openid",openid}
 | 
						||
                };
 | 
						||
            //加入签名
 | 
						||
            dic.Add("sign", GetSignStringByTenant(dic,wxPaykey));
 | 
						||
 | 
						||
            var sb = new StringBuilder();
 | 
						||
            sb.Append("<xml>");
 | 
						||
            foreach (var d in dic)
 | 
						||
            {
 | 
						||
                sb.Append("<" + d.Key + ">" + d.Value + "</" + d.Key + ">");
 | 
						||
            }
 | 
						||
            sb.Append("</xml>");
 | 
						||
            return sb.ToString();
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        /// 取统一下单的请求参数
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="openid"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        private static string GetCancelOrderParam(string orderNo, string code, int totalfee, int refundfee)
 | 
						||
        {
 | 
						||
            string appid = LibUtils.ToString(ConfigurationManager.WexinSettings["AppId"]);
 | 
						||
            //string secret = LibUtils.ToString(ConfigurationManager.WexinSettings["AppSecret"]);
 | 
						||
            string mch_id = LibUtils.ToString(ConfigurationManager.WexinSettings["Mch_ID"]);
 | 
						||
            string ip = LibUtils.ToString(ConfigurationManager.WexinSettings["IP"]);
 | 
						||
            string WxPayCancelUrl = LibUtils.ToString(ConfigurationManager.WexinSettings["WxPayCancelUrl"]);
 | 
						||
 | 
						||
            string strcode = "充电-支付";////商品描述交易字段格式根据不同的应用场景按照以下格式:APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。
 | 
						||
            byte[] buffer = Encoding.UTF8.GetBytes(strcode);
 | 
						||
            string body = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
 | 
						||
            System.Random Random = new System.Random();
 | 
						||
            var dic = new Dictionary<string, string>
 | 
						||
                {
 | 
						||
                    {"appid", appid},
 | 
						||
                    {"mch_id", mch_id},
 | 
						||
                    {"nonce_str", GetRandomString(20)/*Random.Next().ToString()*/},
 | 
						||
                    {"out_trade_no",orderNo+"_"+totalfee},//商户自己的订单号码
 | 
						||
                    {"out_refund_no",code+"@"+totalfee},//退款单号
 | 
						||
                    {"total_fee",totalfee.ToString()},
 | 
						||
                    {"refund_fee", refundfee.ToString()},//退款金额
 | 
						||
                    { "notify_url",WxPayCancelUrl},//异步通知的地址,不能带参数
 | 
						||
                };
 | 
						||
            //加入签名
 | 
						||
            dic.Add("sign", GetSignString(dic));
 | 
						||
 | 
						||
            var sb = new StringBuilder();
 | 
						||
            sb.Append("<xml>");
 | 
						||
            foreach (var d in dic)
 | 
						||
            {
 | 
						||
                sb.Append("<" + d.Key + ">" + d.Value + "</" + d.Key + ">");
 | 
						||
            }
 | 
						||
            sb.Append("</xml>");
 | 
						||
            return sb.ToString();
 | 
						||
        }
 | 
						||
        private static string GetCancelOrderParamByTenant(string orderNo, string code, int totalfee, int refundfee , string orderType, string mch_id, string wxPaykey)
 | 
						||
        {
 | 
						||
            string appid = LibUtils.ToString(ConfigurationManager.WexinSettings["AppId"]);
 | 
						||
            //string secret = LibUtils.ToString(ConfigurationManager.WexinSettings["AppSecret"]);
 | 
						||
            //string mch_id = LibUtils.ToString(ConfigurationManager.WexinSettings["Mch_ID"]);
 | 
						||
            string ip = LibUtils.ToString(ConfigurationManager.WexinSettings["IP"]);
 | 
						||
            string WxPayCancelUrl = LibUtils.ToString(ConfigurationManager.WexinSettings["WxPayCancelUrl"]);
 | 
						||
 | 
						||
            string strcode = "充电-支付";////商品描述交易字段格式根据不同的应用场景按照以下格式:APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。
 | 
						||
            byte[] buffer = Encoding.UTF8.GetBytes(strcode);
 | 
						||
            string body = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
 | 
						||
            System.Random Random = new System.Random();
 | 
						||
            var dic = new Dictionary<string, string>
 | 
						||
                {
 | 
						||
                    {"appid", appid},
 | 
						||
                    {"mch_id", mch_id},
 | 
						||
                    {"nonce_str", GetRandomString(20)/*Random.Next().ToString()*/},
 | 
						||
                    {"out_trade_no",orderNo+"_"+totalfee+"_"+orderType},//商户自己的订单号码
 | 
						||
                    {"out_refund_no",code+"@"+totalfee},//退款单号
 | 
						||
                    {"total_fee",totalfee.ToString()},
 | 
						||
                    {"refund_fee", refundfee.ToString()},//退款金额
 | 
						||
                    { "notify_url",WxPayCancelUrl},//异步通知的地址,不能带参数
 | 
						||
                };
 | 
						||
            //加入签名
 | 
						||
            dic.Add("sign", GetSignStringByTenant(dic, wxPaykey));
 | 
						||
 | 
						||
            var sb = new StringBuilder();
 | 
						||
            sb.Append("<xml>");
 | 
						||
            foreach (var d in dic)
 | 
						||
            {
 | 
						||
                sb.Append("<" + d.Key + ">" + d.Value + "</" + d.Key + ">");
 | 
						||
            }
 | 
						||
            sb.Append("</xml>");
 | 
						||
            return sb.ToString();
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        /// 取统一下单的请求参数
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="openid"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        private static string GetPayforChangeParam(string orderNo, string openid, string username, int fee, string desc)
 | 
						||
        {
 | 
						||
            string appid = LibUtils.ToString(ConfigurationManager.WexinSettings["AppId"]);
 | 
						||
            //string secret = LibUtils.ToString(ConfigurationManager.AppSettings["AppSecret"]);
 | 
						||
            string mch_id = LibUtils.ToString(ConfigurationManager.WexinSettings["Mch_ID"]);
 | 
						||
          
 | 
						||
 | 
						||
 | 
						||
            System.Random Random = new System.Random();
 | 
						||
            var dic = new Dictionary<string, string>
 | 
						||
                {
 | 
						||
                    {"mch_appid", appid},
 | 
						||
                    {"mchid", mch_id},
 | 
						||
                    {"nonce_str", GetRandomString(20)/*Random.Next().ToString()*/},
 | 
						||
                    {"partner_trade_no",orderNo},//提现的订单号
 | 
						||
                    {"openid",openid},
 | 
						||
                    {"check_name","NO_CHECK"},//校验姓名:FORCE_CHECK,NO_CHECK:不校验
 | 
						||
                    {"re_user_name",username},//用户姓名
 | 
						||
                    {"amount", fee.ToString()},//退款金额
 | 
						||
                    { "desc",desc},//异步通知的地址,不能带参数
 | 
						||
                };
 | 
						||
            //加入签名
 | 
						||
            dic.Add("sign", GetSignString(dic));
 | 
						||
 | 
						||
            var sb = new StringBuilder();
 | 
						||
            sb.Append("<xml>");
 | 
						||
            foreach (var d in dic)
 | 
						||
            {
 | 
						||
                sb.Append("<" + d.Key + ">" + d.Value + "</" + d.Key + ">");
 | 
						||
            }
 | 
						||
            sb.Append("</xml>");
 | 
						||
            return sb.ToString();
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 获取返回给小程序的支付参数
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="root"></param>
 | 
						||
        /// <param name="appid"></param>
 | 
						||
        /// <param name="key"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        private static PayRequesEntity GetPayRequestParam(XElement root, string wxPaykey)
 | 
						||
        {
 | 
						||
            string appid = LibUtils.ToString(ConfigurationManager.WexinSettings["AppId"]);
 | 
						||
            //当return_code 和result_code都为SUCCESS时才有我们要的prepay_id
 | 
						||
            if (root.Element("return_code").Value == "SUCCESS" && root.Element("result_code").Value == "SUCCESS")
 | 
						||
            {
 | 
						||
                var res = new Dictionary<string, string>
 | 
						||
                {
 | 
						||
                    {"appId", appid},
 | 
						||
                    {"timeStamp", Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds).ToString()},
 | 
						||
                    {"nonceStr", GetRandomString(20)},
 | 
						||
                    {"package",  "prepay_id=" + root.Element("prepay_id").Value},
 | 
						||
                    {"signType", "MD5"}
 | 
						||
                };
 | 
						||
                //在服务器上签名
 | 
						||
                res.Add("paySign", GetSignStringByTenant(res, wxPaykey));
 | 
						||
 | 
						||
                var payEntity = new PayRequesEntity
 | 
						||
                {
 | 
						||
                    package = res["package"],
 | 
						||
                    nonceStr = res["nonceStr"],
 | 
						||
                    paySign = res["paySign"],
 | 
						||
                    signType = res["signType"],
 | 
						||
                    timeStamp = res["timeStamp"]
 | 
						||
                };
 | 
						||
                return payEntity;
 | 
						||
            }
 | 
						||
            else
 | 
						||
            {
 | 
						||
                throw new Exception("微信返回错误:" + root.Element("err_code_des").Value);
 | 
						||
            }
 | 
						||
 | 
						||
            return new PayRequesEntity();
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        /// 取消订单退款接口
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="root"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        private static bool GetCancelOrderParam(XElement root)
 | 
						||
        {
 | 
						||
            string appid = LibUtils.ToString(ConfigurationManager.WexinSettings["AppId"]);
 | 
						||
            //当return_code 和result_code都为SUCCESS时才有我们要的prepay_id
 | 
						||
            if (root.Element("return_code").Value == "SUCCESS" && root.Element("result_code").Value == "SUCCESS")
 | 
						||
            {
 | 
						||
 | 
						||
                return true;
 | 
						||
            }
 | 
						||
            else
 | 
						||
            {
 | 
						||
                throw new Exception("微信返回错误:" + root.ToString());
 | 
						||
            }
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 从字符串里随机得到,规定个数的字符串.
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="allChar"></param>
 | 
						||
        /// <param name="CodeCount"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        private static string GetRandomString(int CodeCount)
 | 
						||
        {
 | 
						||
            string allChar = "1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,i,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
 | 
						||
            string[] allCharArray = allChar.Split(',');
 | 
						||
            string RandomCode = "";
 | 
						||
            int temp = -1;
 | 
						||
            Random rand = new Random();
 | 
						||
            for (int i = 0; i < CodeCount; i++)
 | 
						||
            {
 | 
						||
                if (temp != -1)
 | 
						||
                {
 | 
						||
                    rand = new Random(temp * i * ((int)DateTime.Now.Ticks));
 | 
						||
                }
 | 
						||
                int t = rand.Next(allCharArray.Length - 1);
 | 
						||
                while (temp == t)
 | 
						||
                {
 | 
						||
                    t = rand.Next(allCharArray.Length - 1);
 | 
						||
                }
 | 
						||
                temp = t;
 | 
						||
                RandomCode += allCharArray[t];
 | 
						||
            }
 | 
						||
 | 
						||
            return RandomCode;
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
        private static string GetSignString(Dictionary<string, string> dic)
 | 
						||
        {
 | 
						||
            string key = LibUtils.ToString(ConfigurationManager.WexinSettings["WxPayKey"]);//商户平台 API安全里面设置的KEY  32位长度                                                                                                            
 | 
						||
            dic = dic.OrderBy(d => d.Key).ToDictionary(d => d.Key, d => d.Value);//排序
 | 
						||
                                                                                 //连接字段
 | 
						||
            var sign = dic.Aggregate("", (current, d) => current + (d.Key + "=" + d.Value + "&"));
 | 
						||
            sign += "key=" + key;
 | 
						||
            System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
 | 
						||
            sign = BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(sign))).Replace("-", null);
 | 
						||
            return sign;
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        /// 运营商Key
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="dic"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        private static string GetSignStringByTenant(Dictionary<string, string> dic,string key)
 | 
						||
        {
 | 
						||
            //string key = LibUtils.ToString(ConfigurationManager.WexinSettings["WxPayKey"]);//商户平台 API安全里面设置的KEY  32位长度                                                                                                            
 | 
						||
            dic = dic.OrderBy(d => d.Key).ToDictionary(d => d.Key, d => d.Value);//排序
 | 
						||
                                                                                 //连接字段
 | 
						||
            var sign = dic.Aggregate("", (current, d) => current + (d.Key + "=" + d.Value + "&"));
 | 
						||
            sign += "key=" + key;
 | 
						||
            System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
 | 
						||
            sign = BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(sign))).Replace("-", null);
 | 
						||
            return sign;
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
        private static Object PostUnifiedOrder(string payUrl, string para)
 | 
						||
        {
 | 
						||
            string result = string.Empty;
 | 
						||
            try
 | 
						||
            {
 | 
						||
                HttpClient client = new HttpClient();
 | 
						||
                HttpContent httpContent = new StringContent(para);
 | 
						||
                httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
 | 
						||
                httpContent.Headers.ContentType.CharSet = "utf-8";
 | 
						||
                HttpResponseMessage hrm = client.PostAsync(payUrl, httpContent).Result;
 | 
						||
                return hrm;
 | 
						||
            }
 | 
						||
            catch (Exception e)
 | 
						||
            {
 | 
						||
                result = e.Message;
 | 
						||
            }
 | 
						||
            return result;
 | 
						||
        }
 | 
						||
    }
 | 
						||
    public class PayRequesEntity
 | 
						||
    {
 | 
						||
        /// <summary>
 | 
						||
        /// 时间戳从1970年1月1日00:00:00至今的秒数,即当前的时间
 | 
						||
        /// </summary>
 | 
						||
        public string timeStamp { get; set; }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 随机字符串,长度为32个字符以下。
 | 
						||
        /// </summary>
 | 
						||
        public string nonceStr { get; set; }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 统一下单接口返回的 prepay_id 参数值
 | 
						||
        /// </summary>
 | 
						||
        public string package { get; set; }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 签名算法
 | 
						||
        /// </summary>
 | 
						||
        public string signType { get; set; }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 签名
 | 
						||
        /// </summary>
 | 
						||
        public string paySign { get; set; }
 | 
						||
 | 
						||
        public dynamic order { get; set; }
 | 
						||
    }
 | 
						||
 | 
						||
    /// <summary>
 | 
						||
    ///     Http方法
 | 
						||
    /// </summary>
 | 
						||
    public class HttpMethods
 | 
						||
    {
 | 
						||
        /// <summary>
 | 
						||
        /// 创建HttpClient
 | 
						||
        /// </summary>
 | 
						||
        /// <returns></returns>
 | 
						||
        public static HttpClient CreateHttpClient(string url, IDictionary<string, string> cookies = null)
 | 
						||
        {
 | 
						||
            HttpClient httpclient;
 | 
						||
            HttpClientHandler handler = new HttpClientHandler();
 | 
						||
            var uri = new Uri(url);
 | 
						||
            if (cookies != null)
 | 
						||
            {
 | 
						||
                foreach (var key in cookies.Keys)
 | 
						||
                {
 | 
						||
                    string one = key + "=" + cookies[key];
 | 
						||
                    handler.CookieContainer.SetCookies(uri, one);
 | 
						||
                }
 | 
						||
            }
 | 
						||
            //如果是发送HTTPS请求 
 | 
						||
            if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
 | 
						||
            {
 | 
						||
                ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
 | 
						||
                httpclient = new HttpClient(handler);
 | 
						||
            }
 | 
						||
            else
 | 
						||
            {
 | 
						||
                httpclient = new HttpClient(handler);
 | 
						||
            }
 | 
						||
            return httpclient;
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
        #region 同步请求
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// post 请求
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="url">请求地址</param>
 | 
						||
        /// <param name="jsonData">请求参数</param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public static string Post(string url, string jsonData)
 | 
						||
        {
 | 
						||
            HttpClient httpClient = CreateHttpClient(url);
 | 
						||
            var postData = new StringContent(jsonData);
 | 
						||
            postData.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
 | 
						||
            Task<string> result = httpClient.PostAsync(url, postData).Result.Content.ReadAsStringAsync();
 | 
						||
            return result.Result;
 | 
						||
        }
 | 
						||
        public static string PostByCert(string xml, string url, bool isUseCert, int timeout)
 | 
						||
        {
 | 
						||
            System.GC.Collect();//垃圾回收,回收没有正常关闭的http连接
 | 
						||
 | 
						||
            string result = "";//返回结果
 | 
						||
 | 
						||
            HttpWebRequest request = null;
 | 
						||
            HttpWebResponse response = null;
 | 
						||
            Stream reqStream = null;
 | 
						||
 | 
						||
            try
 | 
						||
            {
 | 
						||
                //设置最大连接数
 | 
						||
                ServicePointManager.DefaultConnectionLimit = 200;
 | 
						||
                //设置https验证方式
 | 
						||
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
 | 
						||
                {
 | 
						||
                    ServicePointManager.ServerCertificateValidationCallback =
 | 
						||
                            new RemoteCertificateValidationCallback(CheckValidationResult);
 | 
						||
                }
 | 
						||
 | 
						||
                /***************************************************************
 | 
						||
                * 下面设置HttpWebRequest的相关属性
 | 
						||
                * ************************************************************/
 | 
						||
                request = (HttpWebRequest)WebRequest.Create(url);
 | 
						||
                //request.UserAgent = USER_AGENT;
 | 
						||
                request.Method = "POST";
 | 
						||
                request.Timeout = timeout * 1000;
 | 
						||
 | 
						||
                //设置POST的数据类型和长度
 | 
						||
                request.ContentType = "text/xml";
 | 
						||
                byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);
 | 
						||
                request.ContentLength = data.Length;
 | 
						||
 | 
						||
                //是否使用证书
 | 
						||
                if (isUseCert)
 | 
						||
                {
 | 
						||
                    X509Certificate2 cert = new X509Certificate2(LibUtils.ToString(ConfigurationManager.WexinSettings["CertPath"]),
 | 
						||
                        LibUtils.ToString(ConfigurationManager.WexinSettings["CertPassword"]));
 | 
						||
                    request.ClientCertificates.Add(cert);
 | 
						||
                }
 | 
						||
 | 
						||
                //往服务器写入数据
 | 
						||
                reqStream = request.GetRequestStream();
 | 
						||
                reqStream.Write(data, 0, data.Length);
 | 
						||
                reqStream.Close();
 | 
						||
 | 
						||
                //获取服务端返回
 | 
						||
                response = (HttpWebResponse)request.GetResponse();
 | 
						||
 | 
						||
                //获取服务端返回数据
 | 
						||
                StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
 | 
						||
                result = sr.ReadToEnd().Trim();
 | 
						||
                sr.Close();
 | 
						||
            }
 | 
						||
            catch (System.Threading.ThreadAbortException e)
 | 
						||
            {
 | 
						||
                System.Threading.Thread.ResetAbort();
 | 
						||
            }
 | 
						||
            catch (Exception e)
 | 
						||
            {
 | 
						||
                throw new Exception(e.Message);
 | 
						||
            }
 | 
						||
            finally
 | 
						||
            {
 | 
						||
                //关闭连接和流
 | 
						||
                if (response != null)
 | 
						||
                {
 | 
						||
                    response.Close();
 | 
						||
                }
 | 
						||
                if (request != null)
 | 
						||
                {
 | 
						||
                    request.Abort();
 | 
						||
                }
 | 
						||
            }
 | 
						||
            return result;
 | 
						||
        }
 | 
						||
        public static string PostByCertByTenant(string xml, string url, bool isUseCert, int timeout, string certpath, string certpassword)
 | 
						||
        {
 | 
						||
            System.GC.Collect();//垃圾回收,回收没有正常关闭的http连接
 | 
						||
 | 
						||
            string result = "";//返回结果
 | 
						||
 | 
						||
            HttpWebRequest request = null;
 | 
						||
            HttpWebResponse response = null;
 | 
						||
            Stream reqStream = null;
 | 
						||
 | 
						||
            try
 | 
						||
            {
 | 
						||
                //设置最大连接数
 | 
						||
                ServicePointManager.DefaultConnectionLimit = 200;
 | 
						||
                //设置https验证方式
 | 
						||
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
 | 
						||
                {
 | 
						||
                    ServicePointManager.ServerCertificateValidationCallback =
 | 
						||
                            new RemoteCertificateValidationCallback(CheckValidationResult);
 | 
						||
                }
 | 
						||
 | 
						||
                /***************************************************************
 | 
						||
                * 下面设置HttpWebRequest的相关属性
 | 
						||
                * ************************************************************/
 | 
						||
                request = (HttpWebRequest)WebRequest.Create(url);
 | 
						||
                //request.UserAgent = USER_AGENT;
 | 
						||
                request.Method = "POST";
 | 
						||
                request.Timeout = timeout * 1000;
 | 
						||
 | 
						||
                //设置POST的数据类型和长度
 | 
						||
                request.ContentType = "text/xml";
 | 
						||
                byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);
 | 
						||
                request.ContentLength = data.Length;
 | 
						||
 | 
						||
                //是否使用证书
 | 
						||
                if (isUseCert)
 | 
						||
                {
 | 
						||
                    X509Certificate2 cert = new X509Certificate2(certpath,certpassword);
 | 
						||
                    request.ClientCertificates.Add(cert);
 | 
						||
                }
 | 
						||
 | 
						||
                //往服务器写入数据
 | 
						||
                reqStream = request.GetRequestStream();
 | 
						||
                reqStream.Write(data, 0, data.Length);
 | 
						||
                reqStream.Close();
 | 
						||
 | 
						||
                //获取服务端返回
 | 
						||
                response = (HttpWebResponse)request.GetResponse();
 | 
						||
 | 
						||
                //获取服务端返回数据
 | 
						||
                StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
 | 
						||
                result = sr.ReadToEnd().Trim();
 | 
						||
                sr.Close();
 | 
						||
            }
 | 
						||
            catch (System.Threading.ThreadAbortException e)
 | 
						||
            {
 | 
						||
                System.Threading.Thread.ResetAbort();
 | 
						||
            }
 | 
						||
            catch (Exception e)
 | 
						||
            {
 | 
						||
                throw new Exception(e.Message);
 | 
						||
            }
 | 
						||
            finally
 | 
						||
            {
 | 
						||
                //关闭连接和流
 | 
						||
                if (response != null)
 | 
						||
                {
 | 
						||
                    response.Close();
 | 
						||
                }
 | 
						||
                if (request != null)
 | 
						||
                {
 | 
						||
                    request.Abort();
 | 
						||
                }
 | 
						||
            }
 | 
						||
            return result;
 | 
						||
        }
 | 
						||
        private static bool CheckValidationResult(object sender,
 | 
						||
X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
 | 
						||
        {
 | 
						||
            if (errors == SslPolicyErrors.None)
 | 
						||
                return true;
 | 
						||
            return false;
 | 
						||
        }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// post 请求
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="url">请求地址</param>
 | 
						||
        /// <param name="req">请求参数</param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public static string Post(string url, byte[] req)
 | 
						||
        {
 | 
						||
            HttpClient httpClient = CreateHttpClient(url);
 | 
						||
            var postData = new ByteArrayContent(req);
 | 
						||
            Task<string> result = httpClient.PostAsync(url, postData).Result.Content.ReadAsStringAsync();
 | 
						||
            return result.Result;
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        ///     post 请求
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="url">请求地址</param>
 | 
						||
        /// <param name="pairs">请求参数</param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public static string Post(string url, Dictionary<string, string> pairs)
 | 
						||
        {
 | 
						||
            HttpClient httpClient = CreateHttpClient(url);
 | 
						||
            var postData = new FormUrlEncodedContent(pairs);
 | 
						||
            var result = httpClient.PostAsync(url, postData).Result.Content.ReadAsStringAsync();
 | 
						||
            return result.Result;
 | 
						||
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        /// get 请求
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="url">请求地址</param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public static string Get(string url)
 | 
						||
        {
 | 
						||
            HttpClient httpClient = CreateHttpClient(url);
 | 
						||
            Task<string> result = httpClient.GetAsync(url).Result.Content.ReadAsStringAsync();
 | 
						||
            return result.Result;
 | 
						||
        }
 | 
						||
 | 
						||
        #endregion
 | 
						||
 | 
						||
        #region 异步请求
 | 
						||
        /// <summary>
 | 
						||
        ///     post 请求
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="url">请求地址</param>
 | 
						||
        /// <param name="jsonData">请求参数</param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public static Task<HttpResponseMessage> PostAsync(string url, string jsonData)
 | 
						||
        {
 | 
						||
            HttpClient httpClient = CreateHttpClient(url);
 | 
						||
            var postData = new StringContent(jsonData);
 | 
						||
            postData.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
 | 
						||
            var result = httpClient.PostAsync(url, postData);
 | 
						||
            return result;
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        ///     post 请求
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="url">请求地址</param>
 | 
						||
        /// <param name="req">请求参数</param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public static Task<HttpResponseMessage> PostAsync(string url, byte[] req)
 | 
						||
        {
 | 
						||
            HttpClient httpClient = CreateHttpClient(url);
 | 
						||
            var postData = new ByteArrayContent(req);
 | 
						||
            var result = httpClient.PostAsync(url, postData);
 | 
						||
            return result;
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        ///     post 请求
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="url">请求地址</param>
 | 
						||
        /// <param name="pairs">请求参数</param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public static Task<HttpResponseMessage> PostAsync(string url, Dictionary<string, string> pairs)
 | 
						||
        {
 | 
						||
            HttpClient httpClient = CreateHttpClient(url);
 | 
						||
            var postData = new FormUrlEncodedContent(pairs);
 | 
						||
            var result = httpClient.PostAsync(url, postData);
 | 
						||
            return result;
 | 
						||
        }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        ///     get 请求
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="url">请求地址</param>
 | 
						||
        /// <returns></returns>
 | 
						||
        public static Task<HttpResponseMessage> GetAsync(string url)
 | 
						||
        {
 | 
						||
            HttpClient httpClient = CreateHttpClient(url);
 | 
						||
            var result = httpClient.GetAsync(url);
 | 
						||
            return result;
 | 
						||
        }
 | 
						||
        #endregion
 | 
						||
 | 
						||
    }
 | 
						||
}
 |