/** * @将Dictionary转成xml * @return 经转换得到的xml串 * @throws WxPayException **/ public string ToXml() { //数据为空时不能转化为xml格式 if (0 == m_values.Count) { WxPayLog.Error(this.GetType().ToString(), "WxPayData数据为空!"); throw new WxPayException("WxPayData数据为空!"); } string xml = "<xml>"; foreach (KeyValuePair <string, object> pair in m_values) { //字段值不能为null,会影响后续流程 if (pair.Value == null) { WxPayLog.Error(this.GetType().ToString(), "WxPayData内部含有值为null的字段!"); throw new WxPayException("WxPayData内部含有值为null的字段!"); } if (pair.Value.GetType() == typeof(int)) { xml += "<" + pair.Key + ">" + pair.Value + "</" + pair.Key + ">"; } else if (pair.Value.GetType() == typeof(string)) { xml += "<" + pair.Key + ">" + "<![CDATA[" + pair.Value + "]]></" + pair.Key + ">"; } else//除了string和int类型不能含有其他数据类型 { WxPayLog.Error(this.GetType().ToString(), "WxPayData字段数据类型错误!"); throw new WxPayException("WxPayData字段数据类型错误!"); } } xml += "</xml>"; return(xml); }
/** * @将xml转为WxPayData对象并返回对象内部的数据 * @param string 待转换的xml串 * @return 经转换得到的Dictionary * @throws WxPayException */ public SortedDictionary <string, object> FromXml(string xml) { if (string.IsNullOrEmpty(xml)) { WxPayLog.Error(this.GetType().ToString(), "将空的xml串转换为WxPayData不合法!"); throw new WxPayException("将空的xml串转换为WxPayData不合法!"); } XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xml); XmlNode xmlNode = xmlDoc.FirstChild;//获取到根节点<xml> XmlNodeList nodes = xmlNode.ChildNodes; foreach (XmlNode xn in nodes) { XmlElement xe = (XmlElement)xn; m_values[xe.Name] = xe.InnerText;//获取xml的键值对到WxPayData内部的数据中 } try { //2015-06-29 错误是没有签名 if (m_values["return_code"] != "SUCCESS") { return(m_values); } CheckSign();//验证签名,不通过会抛异常 } catch (WxPayException ex) { throw new WxPayException(ex.Message); } return(m_values); }
public static string Post(string xml, string url, bool isUseCert, int timeout) { 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.Method = "POST"; request.Timeout = timeout * 1000; //设置代理服务器 //WebProxy proxy = new WebProxy(); //定义一个网关对象 //proxy.Address = new Uri(WxPayConfig.PROXY_URL); //网关服务器端口:端口 //request.Proxy = proxy; //设置POST的数据类型和长度 request.ContentType = "text/xml"; byte[] data = Encoding.UTF8.GetBytes(xml); request.ContentLength = data.Length; //是否使用证书 if (isUseCert) { string path = HttpContext.Current.Request.PhysicalApplicationPath; X509Certificate2 cert = new X509Certificate2(path + WxPayConfig.SSLCERT_PATH, WxPayConfig.SSLCERT_PASSWORD); request.ClientCertificates.Add(cert); WxPayLog.Debug("WxPayApi", "PostXml used 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) { WxPayLog.Error("HttpService", "Thread - caught ThreadAbortException - resetting."); WxPayLog.Error("Exception message: {0}", e.Message); System.Threading.Thread.ResetAbort(); } catch (WebException e) { WxPayLog.Error("HttpService", e.ToString()); if (e.Status == WebExceptionStatus.ProtocolError) { WxPayLog.Error("HttpService", "StatusCode : " + ((HttpWebResponse)e.Response).StatusCode); WxPayLog.Error("HttpService", "StatusDescription : " + ((HttpWebResponse)e.Response).StatusDescription); } throw new WxPayException(e.ToString()); } catch (Exception e) { WxPayLog.Error("HttpService", e.ToString()); throw new WxPayException(e.ToString()); } finally { //关闭连接和流 if (response != null) { response.Close(); } if (request != null) { request.Abort(); } } return(result); }
/// <summary> /// 处理http GET请求,返回数据 /// </summary> /// <param name="url">请求的url地址</param> /// <returns>http GET成功后返回的数据,失败抛WebException异常</returns> public static string Get(string url) { System.GC.Collect(); string result = ""; HttpWebRequest request = null; HttpWebResponse response = null; //请求url以获取数据 try { //设置最大连接数 ServicePointManager.DefaultConnectionLimit = 200; //设置https验证方式 if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); } /*************************************************************** * 下面设置HttpWebRequest的相关属性 * ************************************************************/ request = (HttpWebRequest)WebRequest.Create(url); request.Method = "GET"; //设置代理 //WebProxy proxy = new WebProxy(); //proxy.Address = new Uri(WxPayConfig.PROXY_URL); //request.Proxy = proxy; //获取服务器返回 response = (HttpWebResponse)request.GetResponse(); //获取HTTP返回数据 StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8); result = sr.ReadToEnd().Trim(); sr.Close(); } catch (System.Threading.ThreadAbortException e) { WxPayLog.Error("HttpService", "Thread - caught ThreadAbortException - resetting."); WxPayLog.Error("Exception message: {0}", e.Message); System.Threading.Thread.ResetAbort(); } catch (WebException e) { WxPayLog.Error("HttpService", e.ToString()); if (e.Status == WebExceptionStatus.ProtocolError) { WxPayLog.Error("HttpService", "StatusCode : " + ((HttpWebResponse)e.Response).StatusCode); WxPayLog.Error("HttpService", "StatusDescription : " + ((HttpWebResponse)e.Response).StatusDescription); } throw new WxPayException(e.ToString()); } catch (Exception e) { WxPayLog.Error("HttpService", e.ToString()); throw new WxPayException(e.ToString()); } finally { //关闭连接和流 if (response != null) { response.Close(); } if (request != null) { request.Abort(); } } return(result); }
public static void ProcessNativeNotify(HttpContextBase httpContext) { var methodString = TypeString + ".ProcessNativeNotify"; WxPayData notifyData = GetNotifyData(httpContext); //检查openid和product_id是否返回 if (!notifyData.IsSet("openid") || !notifyData.IsSet("product_id")) { WxPayData res = new WxPayData(); res.SetValue("return_code", "FAIL"); res.SetValue("return_msg", "回调数据异常"); WxPayLog.Info(methodString, "The data WeChat post is error : " + res.ToXml()); httpContext.Response.Write(res.ToXml()); httpContext.Response.End(); } //调统一下单接口,获得下单结果 string openid = notifyData.GetValue("openid").ToString(); string product_id = notifyData.GetValue("product_id").ToString(); WxPayData unifiedOrderResult = new WxPayData(); try { //统一下单 WxPayData req = new WxPayData(); req.SetValue("body", "test"); req.SetValue("attach", "test"); req.SetValue("out_trade_no", WxPayApi.GenerateOutTradeNo()); req.SetValue("total_fee", 1); req.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss")); req.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss")); req.SetValue("goods_tag", "test"); req.SetValue("trade_type", "NATIVE"); req.SetValue("openid", openid); req.SetValue("product_id", product_id); unifiedOrderResult = WxPayApi.UnifiedOrder(req); } catch (Exception ex)//若在调统一下单接口时抛异常,立即返回结果给微信支付后台 { WxPayData res = new WxPayData(); res.SetValue("return_code", "FAIL"); res.SetValue("return_msg", "统一下单失败"); WxPayLog.Error(methodString, "UnifiedOrder failure : " + res.ToXml()); httpContext.Response.Write(res.ToXml()); httpContext.Response.End(); } //若下单失败,则立即返回结果给微信支付后台 if (!unifiedOrderResult.IsSet("appid") || !unifiedOrderResult.IsSet("mch_id") || !unifiedOrderResult.IsSet("prepay_id")) { WxPayData res = new WxPayData(); res.SetValue("return_code", "FAIL"); res.SetValue("return_msg", "统一下单失败"); WxPayLog.Error(methodString, "UnifiedOrder failure : " + res.ToXml()); httpContext.Response.Write(res.ToXml()); httpContext.Response.End(); } //统一下单成功,则返回成功结果给微信支付后台 WxPayData data = new WxPayData(); data.SetValue("return_code", "SUCCESS"); data.SetValue("return_msg", "OK"); data.SetValue("appid", WxPayConfig.APPID); data.SetValue("mch_id", WxPayConfig.MCHID); data.SetValue("nonce_str", WxPayApi.GenerateNonceStr()); data.SetValue("prepay_id", unifiedOrderResult.GetValue("prepay_id")); data.SetValue("result_code", "SUCCESS"); data.SetValue("err_code_des", "OK"); data.SetValue("sign", data.MakeSign()); WxPayLog.Info(methodString, "UnifiedOrder success , send data to WeChat : " + data.ToXml()); httpContext.Response.Write(data.ToXml()); httpContext.Response.End(); }
/// <summary> /// 刷卡支付完整业务流程逻辑 /// MicroPay.Run /// </summary> /// <param name="body">商品描述</param> /// <param name="total_fee">总金额</param> /// <param name="auth_code">支付授权码</param> /// <returns>刷卡支付结果</returns> /// <exception cref="WxPayException"></exception> public static string MicroPay(string body, string total_fee, string auth_code) { var methodString = TypeString + ".MicroPay"; WxPayLog.Info(methodString, "Micropay is processing..."); WxPayData data = new WxPayData(); data.SetValue("auth_code", auth_code); //授权码 data.SetValue("body", body); //商品描述 data.SetValue("total_fee", int.Parse(total_fee)); //总金额 data.SetValue("out_trade_no", WxPayApi.GenerateOutTradeNo()); //产生随机的商户订单号 WxPayData result = WxPayApi.Micropay(data, 10); //提交被扫支付,接收返回结果 //如果提交被扫支付接口调用失败,则抛异常 if (!result.IsSet("return_code") || result.GetValue("return_code").ToString() == "FAIL") { string returnMsg = result.IsSet("return_msg") ? result.GetValue("return_msg").ToString() : ""; WxPayLog.Error(methodString, "Micropay API interface call failure, result : " + result.ToXml()); throw new WxPayException("Micropay API interface call failure, return_msg : " + returnMsg); } //签名验证 result.CheckSign(); WxPayLog.Debug("MicroPay", "Micropay response check sign success"); //刷卡支付直接成功 if (result.GetValue("return_code").ToString() == "SUCCESS" && result.GetValue("result_code").ToString() == "SUCCESS") { WxPayLog.Debug(methodString, "Micropay business success, result : " + result.ToXml()); return(result.ToPrintStr()); } /****************************************************************** * 剩下的都是接口调用成功,业务失败的情况 * ****************************************************************/ //1)业务结果明确失败 if (result.GetValue("err_code").ToString() != "USERPAYING" && result.GetValue("err_code").ToString() != "SYSTEMERROR") { WxPayLog.Error(methodString, "micropay API interface call success, business failure, result : " + result.ToXml()); return(result.ToPrintStr()); } //2)不能确定是否失败,需查单 //用商户订单号去查单 string out_trade_no = data.GetValue("out_trade_no").ToString(); //确认支付是否成功,每隔一段时间查询一次订单,共查询10次 int queryTimes = 10;//查询次数计数器 while (queryTimes-- > 0) { int succResult = 0;//查询结果 WxPayData queryResult = MicroPayQuery(out_trade_no, out succResult); //如果需要继续查询,则等待2s后继续 if (succResult == 2) { Thread.Sleep(2000); continue; } //查询成功,返回订单查询接口返回的数据 else if (succResult == 1) { WxPayLog.Debug(methodString, "Mircopay success, return order query result : " + queryResult.ToXml()); return(queryResult.ToPrintStr()); } //订单交易失败,直接返回刷卡支付接口返回的结果,失败原因会在err_code中描述 else { WxPayLog.Error(methodString, "Micropay failure, return micropay result : " + result.ToXml()); return(result.ToPrintStr()); } } //确认失败,则撤销订单 WxPayLog.Error(methodString, "Micropay failure, Reverse order is processing..."); if (!MicroPayCancel(out_trade_no)) { WxPayLog.Error(methodString, "Reverse order failure"); throw new WxPayException("Reverse order failure!"); } return(result.ToPrintStr()); }