微信支付統一下單封裝類
阿新 • • 發佈:2018-12-30
using System; using System.Collections.Generic; using System.Configuration; using System.Drawing; using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Net.Security; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Web; using System.Web.Security; using System.Web.UI; using System.Xml; using LitJson; using ThoughtWorks.QRCode.Codec; using ThoughtWorks.QRCode.Codec.Data; namespace weixin.Utility { public class JsApiPay { public static readonly string WX_APPID = ConfigurationManager.AppSettings["WX_APPID"].ToString(); public static readonly string WX_MCHID = ConfigurationManager.AppSettings["WX_MCHID"].ToString(); public static readonly string WX_KEY = ConfigurationManager.AppSettings["WX_KEY"].ToString(); public static readonly string WX_APPSECRET = ConfigurationManager.AppSettings["WX_APPSECRET"].ToString(); public static readonly string WX_NOTIFY_URL = ConfigurationManager.AppSettings["WX_NOTIFY_URL"].ToString(); public static readonly string APPWX_APPID = ConfigurationManager.AppSettings["APPWX_APPID"].ToString(); public static readonly string APPWX_MCHID = ConfigurationManager.AppSettings["APPWX_MCHID"].ToString(); public static readonly string APPWX_KEY = ConfigurationManager.AppSettings["APPWX_KEY"].ToString(); /// <summary> /// 儲存頁面物件,因為要在類的方法中使用Page的Request物件 /// </summary> private Page page { get; set; } /// <summary> /// openid用於呼叫統一下單介面 /// </summary> public string openid { get; set; } /// <summary> /// access_token用於獲取收貨地址js函式入口引數 /// </summary> public string access_token { get; set; } /// <summary> /// 商品金額,用於統一下單 /// </summary> public int total_fee { get; set; } /// <summary> /// 統一下單介面返回結果 /// </summary> public WxPayData unifiedOrderResult { get; set; } //public JsApiPay(Page page) //{ // this.page = page; //} /** * 呼叫統一下單,獲得下單結果 * @return 統一下單結果 * @失敗時拋異常WxPayException */ public WxPayData GetUnifiedOrderResult(string body, string out_trade_no, string total_fee, string trade_type, string openid, string ip, string countdown, string type) { double time = double.Parse(countdown);//交易時間 //統一下單 WxPayData data = new WxPayData(); data.SetValue("body", body);//商品描述 是 //data.SetValue("attach", "test");//附加資料 否 data.SetValue("out_trade_no", out_trade_no);//商戶訂單號 是 data.SetValue("total_fee", total_fee);//標價金額 是 data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));//交易起始時間 否 data.SetValue("time_expire", DateTime.Now.AddMinutes(time).ToString("yyyyMMddHHmmss"));//交易結束時間 否 //data.SetValue("goods_tag", "test");//商品標記 否 if (trade_type == "JSAPI") { data.SetValue("trade_type", "JSAPI");//交易型別 是 data.SetValue("openid", openid);//使用者標識 否 (交易型別是JSAPI時必須傳) } else if (trade_type == "NATIVE") { data.SetValue("trade_type", "NATIVE");//交易型別 是 data.SetValue("product_id", out_trade_no); //data.SetValue("product_id", "123456"); } else if (trade_type == "APP") { data.SetValue("trade_type", "APP");//交易型別 是 } WxPayData result = UnifiedOrder(data, ip, type); if (!result.IsSet("appid") || !result.IsSet("prepay_id") || result.GetValue("prepay_id").ToString() == "") { //Log.Error(this.GetType().ToString(), "UnifiedOrder response error!"); throw new WxPayException("UnifiedOrder response error!"); } unifiedOrderResult = result; return result; } /// <summary> /// 生成直接支付url /// </summary> /// <returns></returns> public string GetPayUrl() { WxPayData appApiParam = new WxPayData(); //appApiParam.SetValue("code_url", unifiedOrderResult.GetValue("code_url")); string url = unifiedOrderResult.GetValue("code_url").ToString();//獲得統一下單介面返回的二維碼連結 //string parameters = appApiParam.ToJson(); //初始化二維碼生成工具 QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(); qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE; qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M; qrCodeEncoder.QRCodeVersion = 6;//設定編碼版本 qrCodeEncoder.QRCodeScale = 10;//設定圖片大小 //將字串生成二維碼圖片 Bitmap image = qrCodeEncoder.Encode(url, Encoding.Default); string filename = DateTime.Now.ToString("yyyymmddhhmmssfff").ToString() + ".jpg"; string saveUrl = "~/upload/images/"; string dirPath = System.Web.HttpContext.Current.Server.MapPath(saveUrl); if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } string ymd = DateTime.Now.ToString("yyyyMMdd", DateTimeFormatInfo.InvariantInfo); dirPath += ymd + "/"; saveUrl += ymd + "/"; if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } string filePath = dirPath + filename; string fileUrl = saveUrl.Replace("~", "") + filename; //string saveUrl = "~/upload/images";//string saveUrl = "~/upload/images/"; //string dirPath = System.Web.HttpContext.Current.Server.MapPath(saveUrl) + "\\" + DateTime.Now.ToString("yyyyMMdd", DateTimeFormatInfo.InvariantInfo); //if (!Directory.Exists(dirPath)) //{ // Directory.CreateDirectory(dirPath); //} //string filePath = System.Web.HttpContext.Current.Server.MapPath(saveUrl) + "\\" + DateTime.Now.ToString("yyyyMMdd", DateTimeFormatInfo.InvariantInfo) + "\\" + filename; FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write); image.Save(fs, ImageFormat.Jpeg); fs.Close(); image.Dispose(); //string fileUrl = saveUrl.Replace("~", ""); // 網站域名 string host = ConfigurationManager.AppSettings["APIHost"]; host = host.EndsWith("/") ? host.Substring(0, host.LastIndexOf("/")) : host; return host + fileUrl; } /// <summary> /// 從統一下單成功返回的資料中獲取調起APP付所需的引數, /// </summary> /// <returns></returns> public string GetAppApiParameters() { //參與簽名的欄位名為appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式為Sign=WXPay WxPayData appApiParam = new WxPayData(); appApiParam.SetValue("appid", unifiedOrderResult.GetValue("appid"));//應用ID appApiParam.SetValue("partnerid", unifiedOrderResult.GetValue("mch_id"));//商戶號 appApiParam.SetValue("prepayid", unifiedOrderResult.GetValue("prepay_id"));//預支付交易會話ID appApiParam.SetValue("package", "Sign=WXPay");//擴充套件欄位 appApiParam.SetValue("noncestr", GenerateNonceStr());//隨機字串 appApiParam.SetValue("timestamp", GenerateTimeStamp());//時間戳 //appApiParam.SetValue("signType", "MD5"); appApiParam.SetValue("paySign", appApiParam.MakeSign()); string parameters = appApiParam.ToJson(); return parameters; } /** * * 從統一下單成功返回的資料中獲取微信瀏覽器調起jsapi支付所需的引數, * 微信瀏覽器調起JSAPI時的輸入引數格式如下: * { * "appId" : "wx2421b1c4370ec43b", //公眾號名稱,由商戶傳入 * "timeStamp":" 1395712654", //時間戳,自1970年以來的秒數 * "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //隨機串 * "package" : "prepay_id=u802345jgfjsdfgsdg888", * "signType" : "MD5", //微信簽名方式: * "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信簽名 * } * @return string 微信瀏覽器調起JSAPI時的輸入引數,json格式可以直接做引數用 * 更詳細的說明請參考網頁端調起支付API:http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7 * */ public string GetJsApiParameters() { //Log.Debug(this.GetType().ToString(), "JsApiPay::GetJsApiParam is processing..."); WxPayData jsApiParam = new WxPayData(); jsApiParam.SetValue("appId", unifiedOrderResult.GetValue("appid")); jsApiParam.SetValue("timeStamp", GenerateTimeStamp()); jsApiParam.SetValue("nonceStr", GenerateNonceStr()); jsApiParam.SetValue("package", "prepay_id=" + unifiedOrderResult.GetValue("prepay_id")); jsApiParam.SetValue("signType", "MD5"); jsApiParam.SetValue("paySign", jsApiParam.MakeSign()); string parameters = jsApiParam.ToJson(); //Log.Debug(this.GetType().ToString(), "Get jsApiParam : " + parameters); return parameters; } /** * * 獲取收貨地址js函式入口引數,詳情請參考收貨地址共享介面:http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_9 * @return string 共享收貨地址js函式需要的引數,json格式可以直接做引數使用 */ public string GetEditAddressParameters() { string parameter = ""; try { string host = page.Request.Url.Host; string path = page.Request.Path; string queryString = page.Request.Url.Query; //這個地方要注意,參與簽名的是網頁授權獲取使用者資訊時微信後臺回傳的完整url string url = "http://" + host + path + queryString; //構造需要用SHA1演算法加密的資料 WxPayData signData = new WxPayData(); signData.SetValue("appid", WX_APPID); signData.SetValue("url", url); signData.SetValue("timestamp", GenerateTimeStamp()); signData.SetValue("noncestr", GenerateNonceStr()); signData.SetValue("accesstoken", access_token); string param = signData.ToUrl(); //Log.Debug(this.GetType().ToString(), "SHA1 encrypt param : " + param); //SHA1加密 string addrSign = FormsAuthentication.HashPasswordForStoringInConfigFile(param, "SHA1"); //Log.Debug(this.GetType().ToString(), "SHA1 encrypt result : " + addrSign); //獲取收貨地址js函式入口引數 WxPayData afterData = new WxPayData(); afterData.SetValue("appId", WX_APPID); afterData.SetValue("scope", "jsapi_address"); afterData.SetValue("signType", "sha1"); afterData.SetValue("addrSign", addrSign); afterData.SetValue("timeStamp", signData.GetValue("timestamp")); afterData.SetValue("nonceStr", signData.GetValue("noncestr")); //轉為json格式 parameter = afterData.ToJson(); //Log.Debug(this.GetType().ToString(), "Get EditAddressParam : " + parameter); } catch (Exception ex) { //Log.Error(this.GetType().ToString(), ex.ToString()); throw new WxPayException(ex.ToString()); } return parameter; } /** * * 統一下單 * @param WxPaydata inputObj 提交給統一下單API的引數 * @param int timeOut 超時時間 * @throws WxPayException * @return 成功時返回,其他拋異常 */ public static WxPayData UnifiedOrder(WxPayData inputObj, string ip, string type, int timeOut = 6) { string url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; //檢測必填引數 if (!inputObj.IsSet("out_trade_no"))//商戶訂單號 { throw new WxPayException("缺少統一支付介面必填引數out_trade_no!"); } else if (!inputObj.IsSet("body"))//商品描述 { throw new WxPayException("缺少統一支付介面必填引數body!"); } else if (!inputObj.IsSet("total_fee"))//標價金額 { throw new WxPayException("缺少統一支付介面必填引數total_fee!"); } else if (!inputObj.IsSet("trade_type"))//交易型別 { throw new WxPayException("缺少統一支付介面必填引數trade_type!"); } //關聯引數 if (inputObj.GetValue("trade_type").ToString() == "JSAPI" && !inputObj.IsSet("openid")) { throw new WxPayException("統一支付介面中,缺少必填引數openid!trade_type為JSAPI時,openid為必填引數!"); } if (inputObj.GetValue("trade_type").ToString() == "NATIVE" && !inputObj.IsSet("product_id")) { throw new WxPayException("統一支付介面中,缺少必填引數product_id!trade_type為JSAPI時,product_id為必填引數!"); } //非同步通知url未設定,則使用配置檔案中的url if (!inputObj.IsSet("notify_url")) { inputObj.SetValue("notify_url", WX_NOTIFY_URL);//非同步通知url } if (type == "1") { inputObj.SetValue("appid", WX_APPID);//公眾賬號ID inputObj.SetValue("mch_id", WX_MCHID);//商戶號 } if (type == "2")//app商戶號 { inputObj.SetValue("appid", APPWX_APPID);//公眾賬號ID inputObj.SetValue("mch_id", APPWX_MCHID);//商戶號 } inputObj.SetValue("spbill_create_ip", ip);//終端ip inputObj.SetValue("nonce_str", GenerateNonceStr());//隨機字串 //簽名 inputObj.SetValue("sign", inputObj.MakeSign()); string xml = inputObj.ToXml(); var start = DateTime.Now; //Log.Debug("WxPayApi", "UnfiedOrder request : " + xml); string response = HttpService.Post(xml, url, false, timeOut); //Log.Debug("WxPayApi", "UnfiedOrder response : " + response); var end = DateTime.Now; int timeCost = (int)((end - start).TotalMilliseconds); WxPayData result = new WxPayData(); result.FromXml(response); //ReportCostTime(url, timeCost, result);//測速上報 return result; } /** * 根據當前系統時間加隨機序列來生成訂單號 * @return 訂單號 */ public static string GenerateOutTradeNo() { var ran = new Random(); return string.Format("{0}{1}{2}", WX_MCHID, DateTime.Now.ToString("yyyyMMddHHmmss"), ran.Next(999)); } /** * 生成時間戳,標準北京時間,時區為東八區,自1970年1月1日 0點0分0秒以來的秒數 * @return 時間戳 */ public static string GenerateTimeStamp() { TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalSeconds).ToString(); } /** * 生成隨機串,隨機串包含字母或數字 * @return 隨機串 */ public static string GenerateNonceStr() { return Guid.NewGuid().ToString().Replace("-", ""); } } public class WxPayData { public static readonly string WX_KEY = ConfigurationManager.AppSettings["WX_KEY"].ToString(); public static readonly string APPWX_KEY = ConfigurationManager.AppSettings["APPWX_KEY"].ToString(); public WxPayData() { } //採用排序的Dictionary的好處是方便對資料包進行簽名,不用再簽名之前再做一次排序 private SortedDictionary<string, object> m_values = new SortedDictionary<string, object>(); /** * 設定某個欄位的值 * @param key 欄位名 * @param value 欄位值 */ public void SetValue(string key, object value) { m_values[key] = value; } /** * 根據欄位名獲取某個欄位的值 * @param key 欄位名 * @return key對應的欄位值 */ public object GetValue(string key) { object o = null; m_values.TryGetValue(key, out o); return o; } /** * 判斷某個欄位是否已設定 * @param key 欄位名 * @return 若欄位key已被設定,則返回true,否則返回false */ public bool IsSet(string key) { object o = null; m_values.TryGetValue(key, out o); if (null != o) return true; else return false; } /** * @將Dictionary轉成xml * @return 經轉換得到的xml串 * @throws WxPayException **/ public string ToXml() { //資料為空時不能轉化為xml格式 if (0 == m_values.Count) { //Log.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) { //Log.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型別不能含有其他資料型別 { //Log.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)) { //Log.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; } /** * @Dictionary格式轉化成url引數格式 * @ return url格式串, 該串不包含sign欄位值 */ public string ToUrl() { string buff = ""; foreach (KeyValuePair<string, object> pair in m_values) { if (pair.Value == null) { //Log.Error(this.GetType().ToString(), "WxPayData內部含有值為null的欄位!"); throw new WxPayException("WxPayData內部含有值為null的欄位!"); } if (pair.Key != "sign" && pair.Value.ToString() != "") { buff += pair.Key + "=" + pair.Value + "&"; } } buff = buff.Trim('&'); return buff; } /** * @Dictionary格式化成Json * @return json串資料 */ public string ToJson() { string jsonStr = JsonMapper.ToJson(m_values); return jsonStr; } /** * @values格式化成能在Web頁面上顯示的結果(因為web頁面上不能直接輸出xml格式的字串) */ public string ToPrintStr() { string str = ""; foreach (KeyValuePair<string, object> pair in m_values) { if (pair.Value == null) { //Log.Error(this.GetType().ToString(), "WxPayData內部含有值為null的欄位!"); throw new WxPayException("WxPayData內部含有值為null的欄位!"); } str += string.Format("{0}={1}<br>", pair.Key, pair.Value.ToString()); } //Log.Debug(this.GetType().ToString(), "Print in Web Page : " + str); return str; } /** * @生成簽名,詳見簽名生成演算法 * @return 簽名, sign欄位不參加簽名 */ public string MakeSign() { //轉url格式 string str = ToUrl(); //在string後加入API KEY str += "&key=" + WX_KEY; //MD5加密 var md5 = MD5.Create(); var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(str)); var sb = new StringBuilder(); foreach (byte b in bs) { sb.Append(b.ToString("x2")); } //所有字元轉為大寫 return sb.ToString().ToUpper(); } /** * * 檢測簽名是否正確 * 正確返回true,錯誤拋異常 */ public bool CheckSign() { //如果沒有設定簽名,則跳過檢測 if (!IsSet("sign")) { //Log.Error(this.GetType().ToString(), "WxPayData簽名存在但不合法!"); throw new WxPayException("WxPayData簽名存在但不合法!"); } //如果設定了簽名但是簽名為空,則拋異常 else if (GetValue("sign") == null || GetValue("sign").ToString() == "") { //Log.Error(this.GetType().ToString(), "WxPayData簽名存在但不合法!"); throw new WxPayException("WxPayData簽名存在但不合法!"); } //獲取接收到的簽名 string return_sign = GetValue("sign").ToString(); //在本地計算新的簽名 string cal_sign = MakeSign(); if (cal_sign == return_sign) { return true; } //Log.Error(this.GetType().ToString(), "WxPayData簽名驗證錯誤!"); throw new WxPayException("WxPayData簽名驗證錯誤!"); } /** * @獲取Dictionary */ public SortedDictionary<string, object> GetValues() { return m_values; } } public class WxPayException : Exception { public WxPayException(string msg) : base(msg) { } } /// <summary> /// http連線基礎類,負責底層的http通訊 /// </summary> public class HttpService { public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { //直接確認,否則打不開 return true; } public static string Post(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.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 = System.Text.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); // //Log.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) { //Log.Error("HttpService", "Thread - caught ThreadAbortException - resetting."); //Log.Error("Exception message: {0}", e.Message); System.Threading.Thread.ResetAbort(); } catch (WebException e) { //Log.Error("HttpService", e.ToString()); //if (e.Status == WebExceptionStatus.ProtocolError) //{ // Log.Error("HttpService", "StatusCode : " + ((HttpWebResponse)e.Response).StatusCode); // Log.Error("HttpService", "StatusDescription : " + ((HttpWebResponse)e.Response).StatusDescription); //} throw new WxPayException(e.ToString()); } catch (Exception e) { // Log.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) { //Log.Error("HttpService", "Thread - caught ThreadAbortException - resetting."); //Log.Error("Exception message: {0}", e.Message); System.Threading.Thread.ResetAbort(); } catch (WebException e) { //Log.Error("HttpService", e.ToString()); //if (e.Status == WebExceptionStatus.ProtocolError) //{ // Log.Error("HttpService", "StatusCode : " + ((HttpWebResponse)e.Response).StatusCode); // Log.Error("HttpService", "StatusDescription : " + ((HttpWebResponse)e.Response).StatusDescription); //} throw new WxPayException(e.ToString()); } catch (Exception e) { //Log.Error("HttpService", e.ToString()); throw new WxPayException(e.ToString()); } finally { //關閉連線和流 if (response != null) { response.Close(); } if (request != null) { request.Abort(); } } return result; } } }
呼叫支付:
string body = " "; string out_trade_no =“”; string total_fee =“0.01”//單位分 string trade_type = ""; string type;//為了後面區分商戶號 if (transactionType == "1")//JSAPI { //JSAPI支付預處理 trade_type = "JSAPI"; WxPayData unifiedOrderResult = jsApiPay.GetUnifiedOrderResult(body, out_trade_no, total_fee, trade_type, openID, ip, countdown, type = "1"); payInfo = jsApiPay.GetJsApiParameters();//獲取H5調起JS API引數 } else if (transactionType == "2") {//NATIVE trade_type = "NATIVE"; WxPayData unifiedOrderResult = jsApiPay.GetUnifiedOrderResult(body, out_trade_no, total_fee, trade_type, openID, ip, countdown, type = "1"); payInfo = jsApiPay.GetPayUrl();//獲取NATIVE 引數 } else if (transactionType == "3") { //APP trade_type = "APP"; WxPayData unifiedOrderResult = jsApiPay.GetUnifiedOrderResult(body, out_trade_no, total_fee, trade_type, openID, ip, countdown, type = "2"); payInfo = jsApiPay.GetAppApiParameters();//獲取app API引數 }