微信支付官方坑太多,我们来精简
我把官方的代码,打包成了 an.wxapi.dll。
里面主要替换了下注释。呵呵。然后修改了几个地方。
修改一、Config.cs
1 namespace an.wxapi 2 { 3 public class WxPayConfig 4 { 5 6 public static string AppKey(string key) 7 { 8 return System.Configuration.ConfigurationManager.AppSettings[key]; 9 } 10 11 ///12 /// APPID:绑定支付的APPID(必须配置) 13 /// 14 public static string APPID { 15 get 16 { 17 return AppKey("wx_appid"); 18 } 19 } 20 21 ///22 /// KEY:商户支付密钥,参考开户邮件设置(必须配置) 23 /// 24 public static string KEY 25 { 26 get { 27 return AppKey("wx_key"); 28 } 29 } 30 ///31 /// 商户号(必须配置) 32 /// 33 public static string MCHID 34 { 35 get { 36 return AppKey("wx_mchid"); 37 } 38 } 39 ///40 /// APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置) 41 /// 42 public static string APPSECRET 43 { 44 get { 45 return AppKey("wx_appsecret"); 46 } 47 } 48 ///49 /// 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要) 50 /// 51 public static string SSLCERT_PATH 52 { 53 get 54 { 55 return AppKey("wx_sslcert_path"); 56 } 57 } 58 ///59 /// 证书密码,默认商户号为密码 60 /// 61 public static string SSLCERT_PASSWORD 62 { 63 get 64 { 65 return AppKey("wx_sslcert_password"); 66 } 67 } 68 69 ///70 /// 支付结果通知回调url,用于商户接收支付结果 71 /// 72 public static string NOTIFY_URL 73 { 74 get 75 { 76 return AppKey("wx_notify_url"); 77 } 78 } 79 80 ///81 /// 商户系统后台机器IP,此参数可手动配置也可在程序中自动获取 82 /// 83 public static string IP = "8.8.8.8"; 84 85 ///86 /// 代理服务器设置,默认IP和端口号分别为0.0.0.0和0,此时不开启代理(如有需要才设置) 87 /// 88 public static string PROXY_URL = "http://10.152.18.220:8080"; 89 90 ///91 ///上报信息配置,测速上报等级,0.关闭上报; 1.仅错误时上报; 2.全量上报 92 /// 93 public static int REPORT_LEVENL = 1; 94 95 ///96 /// 日志等级,0.不输出日志;1.只输出错误信息; 2.输出错误和正常信息; 3.输出错误信息、正常信息和调试信息 97 /// 98 99 public static int LOG_LEVENL100 {101 get102 {103 string log_levenl = "0";104 if(AppKey("log_leven")!="")105 {106 log_levenl = AppKey("log_leven");107 }108 return Convert.ToInt32(log_levenl);109 }110 }111 112 }113 }
只是把静态的替换成可以从web.config里面调用的。
修改二、HttpService.cs
1 namespace an.wxapi 2 { 3 ///4 /// http连接基础类,负责底层的http通信 5 /// 6 public class HttpService 7 { 8 9 public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) 10 { 11 //直接确认,否则打不开 12 return true; 13 } 14 15 public static string Post(string xml, string url, bool isUseCert, int timeout) 16 { 17 System.GC.Collect();//垃圾回收,回收没有正常关闭的http连接 18 19 string result = "";//返回结果 20 21 HttpWebRequest request = null; 22 HttpWebResponse response = null; 23 Stream reqStream = null; 24 25 try 26 { 27 //设置最大连接数 28 ServicePointManager.DefaultConnectionLimit = 200; 29 //设置https验证方式 30 if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) 31 { 32 ServicePointManager.ServerCertificateValidationCallback = 33 new RemoteCertificateValidationCallback(CheckValidationResult); 34 } 35 36 /*************************************************************** 37 * 下面设置HttpWebRequest的相关属性 38 * ************************************************************/ 39 request = (HttpWebRequest)WebRequest.Create(url); 40 41 request.Method = "POST"; 42 request.Timeout = timeout * 1000; 43 44 //设置代理服务器 45 //WebProxy proxy = new WebProxy(); //定义一个网关对象 46 //proxy.Address = new Uri(WxPayConfig.PROXY_URL); //网关服务器端口:端口 47 //request.Proxy = proxy; 48 49 //设置POST的数据类型和长度 50 request.ContentType = "text/xml"; 51 byte[] data = System.Text.Encoding.UTF8.GetBytes(xml); 52 request.ContentLength = data.Length; 53 54 //是否使用证书 55 if (isUseCert) 56 { 57 string path = HttpContext.Current.Request.PhysicalApplicationPath; 58 X509Certificate2 cert = new X509Certificate2(path + WxPayConfig.SSLCERT_PATH, WxPayConfig.SSLCERT_PASSWORD); 59 request.ClientCertificates.Add(cert); 60 Log.Debug("WxPayApi", "PostXml used cert"); 61 } 62 63 //往服务器写入数据 64 reqStream = request.GetRequestStream(); 65 reqStream.Write(data, 0, data.Length); 66 reqStream.Close(); 67 68 //获取服务端返回 69 response = (HttpWebResponse)request.GetResponse(); 70 71 //获取服务端返回数据 72 StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8); 73 result = sr.ReadToEnd().Trim(); 74 sr.Close(); 75 } 76 catch (System.Threading.ThreadAbortException e) 77 { 78 Log.Error("HttpService", "Thread - caught ThreadAbortException - resetting."); 79 Log.Error("Exception message: {0}", e.Message); 80 System.Threading.Thread.ResetAbort(); 81 } 82 catch (WebException e) 83 { 84 Log.Error("HttpService", e.ToString()); 85 if (e.Status == WebExceptionStatus.ProtocolError) 86 { 87 Log.Error("HttpService", "StatusCode : " + ((HttpWebResponse)e.Response).StatusCode); 88 Log.Error("HttpService", "StatusDescription : " + ((HttpWebResponse)e.Response).StatusDescription); 89 } 90 throw new WxPayException(e.ToString()); 91 } 92 catch (Exception e) 93 { 94 Log.Error("HttpService", e.ToString()); 95 throw new WxPayException(e.ToString()); 96 } 97 finally 98 { 99 //关闭连接和流100 if (response != null)101 {102 response.Close();103 }104 if (request != null)105 {106 request.Abort();107 }108 }109 return result;110 }111 112 ///113 /// 处理http GET请求,返回数据114 /// 115 /// 请求的url地址116 ///http GET成功后返回的数据,失败抛WebException异常 117 public static string Get(string url)118 {119 System.GC.Collect();120 string result = "";121 122 HttpWebRequest request = null;123 HttpWebResponse response = null;124 125 //请求url以获取数据126 try127 {128 //设置最大连接数129 ServicePointManager.DefaultConnectionLimit = 200;130 //设置https验证方式131 if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))132 {133 ServicePointManager.ServerCertificateValidationCallback =134 new RemoteCertificateValidationCallback(CheckValidationResult);135 }136 137 /***************************************************************138 * 下面设置HttpWebRequest的相关属性139 * ************************************************************/140 request = (HttpWebRequest)WebRequest.Create(url);141 142 request.Method = "GET";143 144 //设置代理145 //WebProxy proxy = new WebProxy();146 //proxy.Address = new Uri(WxPayConfig.PROXY_URL);147 //request.Proxy = proxy;148 149 //获取服务器返回150 response = (HttpWebResponse)request.GetResponse();151 152 //获取HTTP返回数据153 StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);154 result = sr.ReadToEnd().Trim();155 sr.Close();156 }157 catch (System.Threading.ThreadAbortException e)158 {159 Log.Error("HttpService", "Thread - caught ThreadAbortException - resetting.");160 Log.Error("Exception message: {0}", e.Message);161 System.Threading.Thread.ResetAbort();162 }163 catch (WebException e)164 {165 Log.Error("HttpService", e.ToString());166 if (e.Status == WebExceptionStatus.ProtocolError)167 {168 Log.Error("HttpService", "StatusCode : " + ((HttpWebResponse)e.Response).StatusCode);169 Log.Error("HttpService", "StatusDescription : " + ((HttpWebResponse)e.Response).StatusDescription);170 }171 throw new WxPayException(e.ToString());172 }173 catch (Exception e)174 {175 Log.Error("HttpService", e.ToString());176 throw new WxPayException(e.ToString());177 }178 finally179 {180 //关闭连接和流181 if (response != null)182 {183 response.Close();184 }185 if (request != null)186 {187 request.Abort();188 }189 }190 return result;191 }192 }193 }
主要注释掉了设置代理服务器,基本上就注释掉这个就可以用了。
前台页面,我只用了三个(JsApiPayPage.aspx,ProductPage.aspx,ResultNotifyPage.aspx)
因为我只需要做微信里面的网页支付,其他很多功能我都不需要。所以。BIN文件夹,也只需要LitJSON.dll,RestSharp.dll,an.wxapi.dll(我上面打包的)
ProductPage.aspx(主要获取用户的openid和access_token)
1 <%@ Page Language="C#" Inherits="an.web" %> 2 <%@ Import Namespace="an.wxapi" %> 3 11 12 13 14 1516 17 18 商品一:价格为:1分
19 20 21
我比较懒,所以,我一般不用.cs文件,我喜欢写到一起。呵呵,(这样有个好处,不需要编译,即可运行。)
基本上是拿官方的过来,没怎么修改。
1 protected void Page_Load(object sender, EventArgs e) 2 { 3 Log.Info(this.GetType().ToString(), "page load"); 4 if (!IsPostBack) 5 { 6 JsApiPay jsApiPay = new JsApiPay(this); 7 try 8 { 9 //调用【网页授权获取用户信息】接口获取用户的openid和access_token10 jsApiPay.GetOpenidAndAccessToken();11 12 //获取收货地址js函数入口参数13 //wxEditAddrParam = jsApiPay.GetEditAddressParameters();14 ViewState["openid"] = jsApiPay.openid;15 }16 catch (Exception ex)17 {18 Response.Write("" + "页面加载出错,请重试" +ex.Message +"");19 //Button1.Visible = false;20 //Button2.Visible = false;21 //Label1.Visible = false;22 //Label2.Visible = false;23 }24 }25 }
官方用的是ViewState这玩意,会产生庞大的垃圾代码,(反正我也不知道这玩意,有啥子用)
我的做法是:
1 namespace an2 {3 public class web : System.Web.UI.Page4 {5 public string wx_openid { get; set; }6 public string wxJsApiParam { get; set; }7 }8 }
直接在an.web里面定义下属性,不完啦。
JsApiPayPage.aspx(这个页面用来提交支付请求)
1 <%@ Page Language="C#" Inherits="an.web" %> 2 <%@ Import Namespace="an.wxapi" %> 3 17 18 19 20 21 22微信支付样例-JSAPI支付 23 24 25 62 63 64 65 66
ResultNotifyPage.aspx(回调)
1 <%@ Page Language="C#" Inherits="an.web" %> 2 <%@ Import Namespace="an.wxapi" %> 3 10 11 12 13 1415 16 17 18 19
很简单咯...
an.wxapi.dll 下载地址:http://files.cnblogs.com/files/ancms/an.wxapi.rar
本人很菜,希望以微薄之力帮助大家。
再次感谢:smallerpig