using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; using System.Web; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Net; using System.IO; using System.Xml.Linq; using LitJson; namespace Common { public class WeChat { private HttpContext _context; public WeChat(HttpContext context) { _context = context; } #region 微信支付预处理订单 public Dictionary Pay(string AppId, string MchId, decimal PayMoney, string OrderNo, string SubJect, string Description, string OpenId, string ServerIP, string Key, string NotifyUrl, string Attach = "0") { Dictionary return_result = new Dictionary(); int amount = (int)(PayMoney * 100); //具体请求参数 var par = new SortedList { {"appid", AppId}, {"mch_id", MchId}, {"nonce_str", Function.get_Random(12)}, {"body",SubJect}, {"detail",Description}, {"out_trade_no",OrderNo}, {"fee_type","CNY"}, {"total_fee",amount.ToString()}, {"spbill_create_ip",ServerIP}, {"notify_url",NotifyUrl}, {"trade_type","JSAPI"}, {"openid",OpenId}, {"attach",Attach} }; var postStr = String.Join("&", par.Select(item => String.Format("{0}={1}", item.Key.Trim(), item.Value)).ToArray()); var stringSignTemp = postStr + "&key=" + Key; Function.WriteLog(stringSignTemp, "微信支付预处理订单"); var wxsign = Function.MD532(stringSignTemp); par.Add("sign", wxsign); var postxml = new StringBuilder(); postxml.Append(""); foreach (var item in par) { postxml.AppendFormat("<{0}>{1}", item.Key, item.Value); } postxml.Append(""); try { var result = Function.PostWebRequest("https://api.mch.weixin.qq.com/pay/unifiedorder", postxml.ToString()); Function.WriteLog(result, "微信支付预处理订单"); XmlDocument doc = new XmlDocument(); doc.LoadXml(result); string timeStamp = Function.ConvertDateTimeInt(DateTime.Now).ToString(); string nonce_str = Function.get_Random(12); string package = "prepay_id=" + doc.SelectSingleNode("/xml/prepay_id").InnerText; var pay_param = new SortedList { {"appId", AppId}, {"timeStamp", timeStamp}, {"nonceStr", nonce_str}, {"package", package}, {"signType", "MD5"} }; var pay_param_str = String.Join("&", pay_param.Select(item => String.Format("{0}={1}", item.Key.Trim(), item.Value)).ToArray()); var pay_param_str_sign = pay_param_str + "&key=" + Key; string paySign = Function.MD532(pay_param_str_sign).ToUpper(); return_result.Add("appId", AppId); return_result.Add("timeStamp", timeStamp); return_result.Add("nonce_str", nonce_str); return_result.Add("package", package); return_result.Add("paySign", paySign); } catch { } return return_result; } public Dictionary AppPay(string AppId, string MchId, decimal PayMoney, string OrderNo, string SubJect, string Description, string ServerIP, string Key, string NotifyUrl) { Dictionary return_result = new Dictionary(); int amount = (int)(PayMoney * 100); //具体请求参数 var par = new SortedList { {"appid", AppId}, {"mch_id", MchId}, {"nonce_str", Function.get_Random(12)}, {"body",SubJect}, {"detail",Description}, {"out_trade_no",OrderNo}, {"fee_type","CNY"}, {"total_fee",amount.ToString()}, {"spbill_create_ip",ServerIP}, {"notify_url",NotifyUrl}, {"trade_type","APP"} }; var postStr = String.Join("&", par.Select(item => String.Format("{0}={1}", item.Key.Trim(), item.Value)).ToArray()); var stringSignTemp = postStr + "&key=" + Key; Function.WriteLog(stringSignTemp, "微信支付预处理订单"); var wxsign = Function.MD532(stringSignTemp); par.Add("sign", wxsign); var postxml = new StringBuilder(); postxml.Append(""); foreach (var item in par) { postxml.AppendFormat("<{0}>{1}", item.Key, item.Value); } postxml.Append(""); try { var result = Function.PostWebRequest("https://api.mch.weixin.qq.com/pay/unifiedorder", postxml.ToString()); Function.WriteLog(result, "微信支付预处理订单"); XmlDocument doc = new XmlDocument(); doc.LoadXml(result); string timeStamp = Function.ConvertDateTimeInt(DateTime.Now).ToString(); string nonce_str = Function.get_Random(12); string package = "prepay_id=" + doc.SelectSingleNode("/xml/prepay_id").InnerText; var pay_param = new SortedList { {"appId", AppId}, {"timeStamp", timeStamp}, {"nonceStr", nonce_str}, {"package", package}, {"signType", "MD5"} }; var pay_param_str = String.Join("&", pay_param.Select(item => String.Format("{0}={1}", item.Key.Trim(), item.Value)).ToArray()); var pay_param_str_sign = pay_param_str + "&key=" + Key; string paySign = Function.MD532(pay_param_str_sign).ToUpper(); return_result.Add("appId", AppId); return_result.Add("timeStamp", timeStamp); return_result.Add("nonce_str", nonce_str); return_result.Add("package", package); return_result.Add("paySign", paySign); } catch { } return return_result; } #endregion #region 微信支付预处理订单(H5) public string PayH5(string AppId, string MchId, decimal PayMoney, string OrderNo, string SubJect, string Description, string ServerIP, string Key, string NotifyUrl, string Attach = "0") { string return_result = ""; int amount = (int)(PayMoney * 100); //具体请求参数 var par = new SortedList { {"appid", AppId}, {"mch_id", MchId}, {"nonce_str", Function.get_Random(12)}, {"body",SubJect}, {"detail",Description}, {"out_trade_no",OrderNo}, {"fee_type","CNY"}, {"total_fee",amount.ToString()}, {"spbill_create_ip",ServerIP}, {"notify_url",NotifyUrl}, {"trade_type","MWEB"}, {"attach",Attach} }; var postStr = String.Join("&", par.Select(item => String.Format("{0}={1}", item.Key.Trim(), item.Value)).ToArray()); var stringSignTemp = postStr + "&key=" + Key; Function.WriteLog(stringSignTemp, "微信支付预处理订单(H5)"); var wxsign = Function.MD532(stringSignTemp); par.Add("sign", wxsign); var postxml = new StringBuilder(); postxml.Append(""); foreach (var item in par) { postxml.AppendFormat("<{0}>{1}", item.Key, item.Value); } postxml.Append(""); try { var result = Function.PostWebRequest("https://api.mch.weixin.qq.com/pay/unifiedorder", postxml.ToString()); Function.WriteLog(result, "微信支付预处理订单(H5)"); XmlDocument doc = new XmlDocument(); doc.LoadXml(result); return_result = doc.SelectSingleNode("/xml/mweb_url").InnerText; } catch (Exception ex) { Function.WriteLog(ex.ToString(), "微信支付预处理订单(H5)异常"); } return return_result; } #endregion #region 微信支付异步通知 public string PayCallBack(string Key, bool IsRedis = false) { var backxml = new StringBuilder(); backxml.Append(""); var logSb = new StringBuilder();//日志 try { var syncIOFeature = _context.Features.Get(); if (syncIOFeature != null) { syncIOFeature.AllowSynchronousIO = true; } //接收从微信后台POST过来的数据 var s = _context.Request.Body; var count = 0; var buffer = new byte[1024]; var builder = new StringBuilder(); while ((count = s.Read(buffer, 0, 1024)) > 0) { builder.Append(Encoding.UTF8.GetString(buffer, 0, count)); } s.Flush(); s.Close(); s.Dispose(); Function.WriteLog("\r\n========================\r\n回调通知的原始数据:" + builder.ToString(), "微信支付异步通知"); var mValues = new SortedList(); var xmlDoc = new XmlDocument(); xmlDoc.XmlResolver = null; xmlDoc.LoadXml(builder.ToString()); var xmlNode = xmlDoc.FirstChild;//获取到根节点 var nodes = xmlNode.ChildNodes; foreach (var xe in nodes.Cast()) { mValues[xe.Name] = xe.InnerText;//获取xml的键值对到WxPayData内部的数据中 } var buff = mValues.Where(pair => pair.Key != "sign" && pair.Value.ToString() != "").Aggregate("", (current, pair) => current + (pair.Key + "=" + pair.Value + "&")); buff = buff.Trim('&'); var stringSignTemp = buff + "&key=" + Key; Function.WriteLog("待签名字符串:" + stringSignTemp, "微信支付异步通知"); //MD5加密 var md5 = MD5.Create(); var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(stringSignTemp)); var sb = new StringBuilder(); foreach (byte b in bs) { sb.Append(b.ToString("x2")); } //所有字符转为大写 var wxsign = sb.ToString().ToUpper(); Function.WriteLog("签名字符串:" + wxsign, "微信支付异步通知"); //获取接收到的签名 string return_sign = ""; mValues.TryGetValue("sign", out return_sign); Function.WriteLog("签名字符串比较:" + wxsign + " VS " + return_sign, "微信支付异步通知"); if (wxsign == return_sign) { string transaction_id = ""; mValues.TryGetValue("transaction_id", out transaction_id); string out_trade_no = ""; mValues.TryGetValue("out_trade_no", out out_trade_no); string result_code = ""; mValues.TryGetValue("result_code", out result_code); string err_code = ""; mValues.TryGetValue("err_code", out err_code); string total_fee = ""; mValues.TryGetValue("total_fee", out total_fee); string openid = ""; mValues.TryGetValue("openid", out openid); string attach = ""; mValues.TryGetValue("attach", out attach); Function.WriteLog("transaction_id:" + transaction_id, "微信支付异步通知"); Function.WriteLog("out_trade_no:" + out_trade_no, "微信支付异步通知"); Function.WriteLog("result_code:" + result_code, "微信支付异步通知"); Function.WriteLog("err_code:" + err_code, "微信支付异步通知"); Function.WriteLog("total_fee:" + total_fee, "微信支付异步通知"); Function.WriteLog("openid:" + openid, "微信支付异步通知"); Function.WriteLog("attach:" + attach, "微信支付异步通知"); if (result_code == "SUCCESS") { var totalAmount = 0m; decimal.TryParse(total_fee, out totalAmount); var payAmount = totalAmount / 100; Function.WriteLog("out_trade_no:" + out_trade_no, "微信支付异步通知"); if (IsRedis) { RedisServer.Cache.LPush("PayCallBack", "{\"out_trade_no\":\"" + out_trade_no + "\",\"transaction_id\":\"" + transaction_id + "\",\"total_fee\":\"" + total_fee + "\",\"pay_mode\":\"2\",\"openid\":\"" + openid + "\",\"attach\":\"" + attach + "\"}"); } else { Function.WritePage("/PayCallBack/", Function.MD5_16(Guid.NewGuid().ToString()) + ".txt", "{\"out_trade_no\":\"" + out_trade_no + "\",\"transaction_id\":\"" + transaction_id + "\",\"total_fee\":\"" + total_fee + "\",\"pay_mode\":\"2\",\"openid\":\"" + openid + "\",\"attach\":\"" + attach + "\"}"); } backxml.Append(""); backxml.AppendFormat(" ", err_code); } else { logSb.AppendFormat(" -->订单状态错误:{0};", err_code); backxml.Append(""); backxml.AppendFormat(" ", err_code); } } else { backxml.Append(""); backxml.AppendFormat(" ", "签名失败"); Function.WriteLog("微信支付----异步通知执行后日志:" + logSb.ToString(), "微信支付异步通知"); } } catch (Exception ex) { backxml.Append(""); backxml.AppendFormat(" ", "签名失败"); Function.WriteLog("微信支付----异步通知执行后日志:" + ex.ToString(), "微信支付异步通知"); } backxml.Append(""); return backxml.ToString(); } public string PayCallBack2(string Key, string BackContent, bool IsRedis = false) { var backxml = new StringBuilder(); backxml.Append(""); var logSb = new StringBuilder();//日志 try { var syncIOFeature = _context.Features.Get(); if (syncIOFeature != null) { syncIOFeature.AllowSynchronousIO = true; } //接收从微信后台POST过来的数据 var mValues = new SortedList(); var xmlDoc = new XmlDocument(); xmlDoc.XmlResolver = null; xmlDoc.LoadXml(BackContent); var xmlNode = xmlDoc.FirstChild;//获取到根节点 var nodes = xmlNode.ChildNodes; foreach (var xe in nodes.Cast()) { mValues[xe.Name] = xe.InnerText;//获取xml的键值对到WxPayData内部的数据中 } var buff = mValues.Where(pair => pair.Key != "sign" && pair.Value.ToString() != "").Aggregate("", (current, pair) => current + (pair.Key + "=" + pair.Value + "&")); buff = buff.Trim('&'); var stringSignTemp = buff + "&key=" + Key; Function.WriteLog("待签名字符串:" + stringSignTemp, "微信支付异步通知"); //MD5加密 var md5 = MD5.Create(); var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(stringSignTemp)); var sb = new StringBuilder(); foreach (byte b in bs) { sb.Append(b.ToString("x2")); } //所有字符转为大写 var wxsign = sb.ToString().ToUpper(); Function.WriteLog("签名字符串:" + wxsign, "微信支付异步通知"); //获取接收到的签名 string return_sign = ""; mValues.TryGetValue("sign", out return_sign); Function.WriteLog("签名字符串比较:" + wxsign + " VS " + return_sign, "微信支付异步通知"); if (wxsign == return_sign) { string transaction_id = ""; mValues.TryGetValue("transaction_id", out transaction_id); string out_trade_no = ""; mValues.TryGetValue("out_trade_no", out out_trade_no); string result_code = ""; mValues.TryGetValue("result_code", out result_code); string err_code = ""; mValues.TryGetValue("err_code", out err_code); string total_fee = ""; mValues.TryGetValue("total_fee", out total_fee); string openid = ""; mValues.TryGetValue("openid", out openid); string attach = ""; mValues.TryGetValue("attach", out attach); Function.WriteLog("transaction_id:" + transaction_id, "微信支付异步通知"); Function.WriteLog("out_trade_no:" + out_trade_no, "微信支付异步通知"); Function.WriteLog("result_code:" + result_code, "微信支付异步通知"); Function.WriteLog("err_code:" + err_code, "微信支付异步通知"); Function.WriteLog("total_fee:" + total_fee, "微信支付异步通知"); Function.WriteLog("openid:" + openid, "微信支付异步通知"); Function.WriteLog("attach:" + attach, "微信支付异步通知"); if (result_code == "SUCCESS") { var totalAmount = 0m; decimal.TryParse(total_fee, out totalAmount); var payAmount = totalAmount / 100; Function.WriteLog("out_trade_no:" + out_trade_no, "微信支付异步通知"); if (IsRedis) { RedisServer.Cache.LPush("PayCallBack", "{\"out_trade_no\":\"" + out_trade_no + "\",\"transaction_id\":\"" + transaction_id + "\",\"total_fee\":\"" + total_fee + "\",\"pay_mode\":\"2\",\"openid\":\"" + openid + "\",\"attach\":\"" + attach + "\"}"); } else { Function.WritePage("/PayCallBack/", Function.MD5_16(Guid.NewGuid().ToString()) + ".txt", "{\"out_trade_no\":\"" + out_trade_no + "\",\"transaction_id\":\"" + transaction_id + "\",\"total_fee\":\"" + total_fee + "\",\"pay_mode\":\"2\",\"openid\":\"" + openid + "\",\"attach\":\"" + attach + "\"}"); } backxml.Append(""); backxml.AppendFormat(" ", err_code); } else { logSb.AppendFormat(" -->订单状态错误:{0};", err_code); backxml.Append(""); backxml.AppendFormat(" ", err_code); } } else { backxml.Append(""); backxml.AppendFormat(" ", "签名失败"); Function.WriteLog("微信支付----异步通知执行后日志:" + logSb.ToString(), "微信支付异步通知"); } } catch (Exception ex) { backxml.Append(""); backxml.AppendFormat(" ", "签名失败"); Function.WriteLog("微信支付----异步通知执行后日志:" + ex.ToString(), "微信支付异步通知"); } backxml.Append(""); return backxml.ToString(); } #endregion #region 微信分享 public Dictionary Share(string AppId, string AppSecret, string Url, bool CacheToken = true) { Dictionary result = new Dictionary(); try { string token = getWXToken(AppId, AppSecret, CacheToken); string content = Function.GetWebRequest("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + token + "&type=jsapi"); Function.WriteLog("content:" + content, "微信参数检查"); JsonData json = JsonMapper.ToObject(content); string ticket = ""; if (json["errcode"].ToString() == "0") { ticket = json["ticket"].ToString(); } string noncestr = Function.get_Random(10); string timestamp = Function.ConvertDateTimeInt(DateTime.Now).ToString(); string sign = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + Url; Function.WriteLog("sign:" + sign, "微信参数检查"); sign = SHA1(sign); result.Add("appId", AppId); result.Add("noncestr", noncestr); result.Add("timestamp", timestamp); result.Add("sign", sign); } catch (Exception ex) { Function.WriteLog(DateTime.Now.ToString() + ":" + ex.ToString(), "获取微信分享参数异常"); } return result; } #endregion #region 微信退款 public string Refund(string AppId, string MchId,string OrderNo, string TradeNo, decimal TotalPrice, string Key, string CertPath) { //生成订单号 var batchNo = DateTime.Now.ToString("HHmmss") + Function.get_Random(28); var payamount = (TotalPrice * 100).ToString("f0"); //具体请求参数 var parwxrefund = new SortedList { {"appid", AppId }, {"mch_id",MchId}, {"nonce_str", Function.get_Random(10)}, {"out_trade_no",OrderNo}, //{"transaction_id",TradeNo}, {"out_refund_no",batchNo}, {"total_fee", payamount}, {"refund_fee",payamount}, {"op_user_id",MchId}, }; if (!string.IsNullOrEmpty(TradeNo)) { parwxrefund.Add("transaction_id", TradeNo); } var signStr = String.Join("&", parwxrefund.Select(item => String.Format("{0}={1}", item.Key.Trim(), item.Value)).ToArray());; var stringSignTemp = signStr + "&key=" + Key; var wxsign = Function.MD532(stringSignTemp); parwxrefund.Add("sign", wxsign); var postxml = new StringBuilder(); postxml.Append(""); foreach (var item in parwxrefund) { postxml.AppendFormat("<{0}>{1}", item.Key, item.Value); } postxml.Append(""); //退款接口地址 string url = "https://api.mch.weixin.qq.com/secapi/pay/refund"; //本地或者服务器的证书位置(证书在微信支付申请成功发来的通知邮件中) string cert = Function.getPath(CertPath); try { var cer = new X509Certificate2(cert, MchId, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);//证书 var webrequest = (HttpWebRequest)HttpWebRequest.Create(url); webrequest.ClientCertificates.Add(cer); webrequest.Method = "post"; byte[] postdatabyte = Encoding.UTF8.GetBytes(postxml.ToString()); webrequest.ContentLength = postdatabyte.Length; Stream stream = webrequest.GetRequestStream(); stream.Write(postdatabyte, 0, postdatabyte.Length); stream.Close(); var httpWebResponse = (HttpWebResponse)webrequest.GetResponse(); var streamReader = new StreamReader(httpWebResponse.GetResponseStream()); string responseContent = streamReader.ReadToEnd(); Function.WriteLog("微信退款回调内容:" + responseContent, "微信退款"); var res = XDocument.Parse(responseContent); var xElement = res.Element("xml"); if (xElement != null) { var element = xElement.Element("return_code"); if (element != null) { var returnCode = element.Value; if (returnCode.Contains("SUCCESS")) { //商户订单号 string out_trade_no = ""; var xElement1 = xElement.Element("out_trade_no"); if (xElement1 != null) { out_trade_no = "success|" + xElement1.Value; Function.WriteLog("微信退款修改订单状态:" + out_trade_no, "微信退款"); } //业务处理 return out_trade_no; } else { Function.WriteLog("微信支付----退款接口返回错误:-》》" + responseContent, "微信退款"); //业务处理 return responseContent; } } } } catch (Exception ex) { Function.WriteLog("微信支付退款----异常:-》》" + ex.ToString(), "微信退款"); //业务处理 return ex.ToString(); } return ""; } #endregion #region 公对零钱 public string Change(string AppId, string MchId, string ServerIP, string OrderNo, string OpenId, decimal TotalPrice, string Detail, string Key, string CertPath) { var payamount = (TotalPrice * 100).ToString("f0"); //具体请求参数 var parwxrefund = new SortedList { {"mch_appid", AppId }, {"mchid",MchId}, {"nonce_str", Function.get_Random(10)}, {"partner_trade_no",OrderNo}, {"openid",OpenId}, {"check_name","NO_CHECK"}, {"amount", payamount}, {"desc",Detail}, {"spbill_create_ip",ServerIP}, }; var signStr = String.Join("&", parwxrefund.Select(item => String.Format("{0}={1}", item.Key.Trim(), item.Value)).ToArray()); ; var stringSignTemp = signStr + "&key=" + Key; var wxsign = Function.MD532(stringSignTemp); parwxrefund.Add("sign", wxsign); var postxml = new StringBuilder(); postxml.Append(""); foreach (var item in parwxrefund) { postxml.AppendFormat("<{0}>{1}", item.Key, item.Value); } postxml.Append(""); //接口地址 string url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; //本地或者服务器的证书位置(证书在微信支付申请成功发来的通知邮件中) string cert = Function.getPath(CertPath); try { var cer = new X509Certificate2(cert, MchId, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);//证书 var webrequest = (HttpWebRequest)HttpWebRequest.Create(url); webrequest.ClientCertificates.Add(cer); webrequest.Method = "post"; byte[] postdatabyte = Encoding.UTF8.GetBytes(postxml.ToString()); webrequest.ContentLength = postdatabyte.Length; Stream stream = webrequest.GetRequestStream(); stream.Write(postdatabyte, 0, postdatabyte.Length); stream.Close(); var httpWebResponse = (HttpWebResponse)webrequest.GetResponse(); var streamReader = new StreamReader(httpWebResponse.GetResponseStream()); string responseContent = streamReader.ReadToEnd(); Function.WriteLog("回调内容:" + responseContent, "零钱公对私"); var res = XDocument.Parse(responseContent); var xElement = res.Element("xml"); if (xElement != null) { var element = xElement.Element("return_code"); if (element != null) { var returnCode = element.Value; if (returnCode.Contains("SUCCESS")) { //微信付款单号 string payment_no = ""; var xElement1 = xElement.Element("payment_no"); if (xElement1 != null) { payment_no = "success|" + xElement1.Value; Function.WriteLog("微信付款单号:" + payment_no, "零钱公对私"); } //业务处理 return payment_no; } else { Function.WriteLog("零钱公对私----接口返回错误:" + responseContent, "零钱公对私"); //业务处理 return responseContent; } } } } catch (Exception ex) { Function.WriteLog("零钱公对私----异常:" + ex.ToString(), "零钱公对私"); //业务处理 return ex.ToString(); } return ""; } #endregion #region 红包发放 public string RedPackage(string AppId, string MchId, string ServerIP, string OrderNo, string OpenId, decimal TotalPrice, string SendName, string Wishing, string ActName, string Remark, string kind, string Key, string CertPath) { var payamount = (TotalPrice * 100).ToString("f0"); //具体请求参数 var parwxrefund = new SortedList { {"nonce_str", Function.get_Random(10)}, {"mch_billno",OrderNo}, {"mch_id",MchId}, {"wxappid", AppId }, {"send_name",SendName}, {"re_openid",OpenId}, {"total_amount", payamount}, {"total_num","1"}, {"wishing",Wishing}, {"client_ip",ServerIP}, {"act_name",ActName}, {"remark",Remark}, {"scene_id","PRODUCT_"+kind}, }; var signStr = String.Join("&", parwxrefund.Select(item => String.Format("{0}={1}", item.Key.Trim(), item.Value)).ToArray()); ; var stringSignTemp = signStr + "&key=" + Key; var wxsign = Function.MD532(stringSignTemp); parwxrefund.Add("sign", wxsign); var postxml = new StringBuilder(); postxml.Append(""); foreach (var item in parwxrefund) { postxml.AppendFormat("<{0}>{1}", item.Key, item.Value); } postxml.Append(""); Function.WriteLog("请求参数:" + postxml.ToString(), "微信红包发放"); //接口地址 string url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack"; //本地或者服务器的证书位置(证书在微信支付申请成功发来的通知邮件中) string cert = Function.getPath(CertPath); try { var cer = new X509Certificate2(cert, MchId, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);//证书 var webrequest = (HttpWebRequest)HttpWebRequest.Create(url); webrequest.ClientCertificates.Add(cer); webrequest.Method = "post"; byte[] postdatabyte = Encoding.UTF8.GetBytes(postxml.ToString()); webrequest.ContentLength = postdatabyte.Length; Stream stream = webrequest.GetRequestStream(); stream.Write(postdatabyte, 0, postdatabyte.Length); stream.Close(); var httpWebResponse = (HttpWebResponse)webrequest.GetResponse(); var streamReader = new StreamReader(httpWebResponse.GetResponseStream()); string responseContent = streamReader.ReadToEnd(); Function.WriteLog("回调内容:" + responseContent, "微信红包发放"); var res = XDocument.Parse(responseContent); var xElement = res.Element("xml"); if (xElement != null) { var element = xElement.Element("return_code"); if (element != null) { var returnCode = element.Value; if (returnCode.Contains("SUCCESS")) { //微信付款单号 string payment_no = ""; var xElement1 = xElement.Element("payment_no"); if (xElement1 != null) { payment_no = "success|" + xElement1.Value; Function.WriteLog("微信付款单号:" + payment_no, "微信红包发放"); } //业务处理 return payment_no; } else { Function.WriteLog("微信红包发放----接口返回错误:" + responseContent, "微信红包发放"); //业务处理 return responseContent; } } } } catch (Exception ex) { Function.WriteLog("微信红包发放----异常:" + ex.ToString(), "微信红包发放"); //业务处理 return ex.ToString(); } return ""; } #endregion #region 发送模板消息 public void SendModuleMsg(string AppId, string AppSecret, string OpenId, string TemplateId, string Url, Dictionary Msg) { string token = getWXToken(AppId, AppSecret); string MsgData = ""; foreach (string key in Msg.Keys) { MsgData += "\"" + key + "\": {" + "\"value\":\"" + Msg[key] + "\"," + "\"color\":\"#173177\"" + "},"; } MsgData = MsgData.TrimEnd(','); string requestData = "{" + "\"touser\":\"" + OpenId + "\"," + "\"template_id\":\"" + TemplateId + "\"," + "\"url\":\"" + Url + "\"," + "\"topcolor\":\"#FF0000\"," + "\"data\":{" + MsgData + "}" + "}"; string result = Function.PostWebRequest("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token, requestData); Function.WriteLog(result, "发送模板消息"); } #endregion #region 接收事件推送 public void ReceiveEventMsg() { try { //接收从微信后台POST过来的数据 var s = _context.Request.Body; var count = 0; var buffer = new byte[1024]; var builder = new StringBuilder(); while ((count = s.Read(buffer, 0, 1024)) > 0) { builder.Append(Encoding.UTF8.GetString(buffer, 0, count)); } s.Flush(); s.Close(); s.Dispose(); Function.WriteLog("\r\n========================\r\n原始数据:" + builder.ToString(), "接收事件推送"); string json = ""; var mValues = new SortedList(); var xmlDoc = new XmlDocument(); xmlDoc.LoadXml(builder.ToString()); var xmlNode = xmlDoc.FirstChild;//获取到根节点 var nodes = xmlNode.ChildNodes; foreach (var xe in nodes.Cast()) { json = "\"" + xe.Name + "\":\"" + xe.InnerText + "\","; //获取xml的键值对到WxPayData内部的数据中 } json = json.TrimEnd(','); Function.WritePage("/ReceiveEventMsg/", Function.MD5_16(Guid.NewGuid().ToString()) + ".txt", "{" + json + "}"); } catch (Exception ex) { Function.WriteLog("微信支付----异步通知执行后日志:" + ex.ToString(), "接收事件推送"); } } #endregion #region 自定3*5义菜单 public string SetMenu(string AppId, string AppSecret, Dictionary> Menu) { string json = "{\"button\":["; foreach (string key in Menu.Keys) { Dictionary sub = Menu[key]; if (sub.Count == 1) { json += "{\"type\":\"view\",\"name\":\"" + key + "\",\"url\":\"" + sub["url"] + "\"},"; } else { string subjson = ""; foreach (string subkey in sub.Keys) { subjson += "{\"type\":\"view\",\"name\":\"" + subkey + "\",\"url\":\"" + sub["url"] + "\"},"; } subjson = subjson.TrimEnd(','); json += "{\"type\":\"view\",\"name\":\"" + key + "\",\"sub_button\":[" + subjson + "],"; } } json = json.TrimEnd(','); json += "]}"; string token = getWXToken(AppId, AppSecret); string result = Function.PostWebRequest("https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + token, json); JsonData jsonObj = JsonMapper.ToObject(result); if (jsonObj["errcode"].ToString() == "0") { return "success"; } return jsonObj["errmsg"].ToString(); } #endregion #region 公用方法 public string SHA1(string content) { try { SHA1 sha1 = new SHA1CryptoServiceProvider(); byte[] bytes_in = Encoding.UTF8.GetBytes(content); byte[] bytes_out = sha1.ComputeHash(bytes_in); sha1.Dispose(); string result = BitConverter.ToString(bytes_out); result = result.Replace("-", ""); return result; } catch (Exception ex) { throw new Exception("SHA1加密出错:" + ex.Message); } } #region 获取token public string getWXToken(string AppId, string AppSecret, bool Cache = true) { string token = ""; if (Cache) { string time = Function.ReadInstance("/WeChat/TokenTimeSet.txt"); if (!string.IsNullOrEmpty(time)) { string[] times = time.Split('|'); DateTime date = DateTime.Parse(times[0]); if (date.AddMinutes(100) > DateTime.Now) { token = times[1]; } } } if (string.IsNullOrEmpty(token)) { string jsonstr = Function.GetWebRequest("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + AppId + "&secret=" + AppSecret); Function.WriteLog(jsonstr, "获取token"); if (jsonstr.Contains("access_token")) { JsonData tokenjson = JsonMapper.ToObject(jsonstr); string access_token = tokenjson["access_token"].ToString(); if (Cache) { Function.WritePage("/WeChat/", "TokenTimeSet.txt", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "|" + access_token); } return access_token; } } return token; } #endregion #endregion } }