ASP.NET MVC 微信公眾號支付


1、首先到官網下載微信API。

2、解壓后將cert、lib兩個文件夾復制到項目更目錄下。

3、微信公眾號支付

  控制器代碼

  1 /// <summary>
  2         /// 生成訂單及JSAPI提交參數
  3         /// </summary>
  4         /// <param name="tmpModel"></param>
  5         /// <returns></returns>
  6         public ActionResult GenerateOrder(string orderno)
  7         {
  8             //string wxEditAddrParam;
  9 
 10             JsApiPay jsapipay = new JsApiPay();
 11             try
 12             {
 13                 GetOpenidAndAccessToken();
 14                 jsapipay.openid = Session["openid"].ToString();
 15                 jsapipay.access_token = Session["access_token"].ToString();
 16                 Log.Info(this.GetType().ToString(),"openid:"+jsapipay.openid+",access_token:"+jsapipay.access_token);
 17                 //wxEditAddrParam = GetEditAddressParameters();
 18                 //ViewBag.wxEditAddrParam = wxEditAddrParam;
 19                 ViewBag.openid = jsapipay.openid;
 20             }
 21             catch (Exception)
 22             {
 23                 throw;
 24             }
 25             return View();
 26         }
 27 
 28         /**
 29         * 
 30         * 網頁授權獲取用戶基本信息的全部過程
 31         * 詳情請參看網頁授權獲取用戶基本信息:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
 32         * 第一步:利用url跳轉獲取code
 33         * 第二步:利用code去獲取openid和access_token
 34         * 
 35         */
 36         private void GetOpenidAndAccessToken()
 37         {
 38             if (!string.IsNullOrEmpty(Request.QueryString["code"]))
 39             {
 40                 string code = Request.QueryString["code"];
 41                 GetOpenidAndAccessTokenFromCode(code);
 42             }
 43             else
 44             {
 45                 string host = Request.Url.Host;
 46                 string path = Request.Url.PathAndQuery;
 47                 string redirect_uri = HttpUtility.UrlEncode("http://" + host + path);  
 48                 //string redirect_uri = HttpUtility.UrlEncode("http://gzh.lmx.ren");
 49                 WxPayData data = new WxPayData();
 50                 data.SetValue("appid", PublicConst.Wx_appid);
 51                 data.SetValue("redirect_uri", redirect_uri);
 52                 data.SetValue("response_type", "code");
 53                 data.SetValue("scope", "snsapi_base");
 54                 data.SetValue("state", "STATE" + "#wechat_redirect");
 55                 string url = "https://open.weixin.qq.com/connect/oauth2/authorize?" + data.ToUrl();
 56                 Response.Redirect(url);
 57             }
 58         }
 59 
 60         public void GetOpenidAndAccessTokenFromCode(string code)
 61         {
 62             try
 63             {
 64                 WxPayData data = new WxPayData();
 65                 data.SetValue("appid", WxPayConfig.APPID);
 66                 data.SetValue("secret", WxPayConfig.APPSECRET);
 67                 data.SetValue("code", code);
 68                 data.SetValue("grant_type", "authorization_code");
 69                 string url = "https://api.weixin.qq.com/sns/oauth2/access_token?" + data.ToUrl();
 70 
 71                 //請求url以獲取數據
 72                 string result = HttpService.Get(url);
 73 
 74                 //Log.Debug(this.GetType().ToString(), "GetOpenidAndAccessTokenFromCode response : " + result);
 75 
 76                 //保存access_token,用於收貨地址獲取
 77                 JsonData jd = JsonMapper.ToObject(result);
 78 
 79                 Session["access_token"] = (string)jd["access_token"];
 80                 Session["openid"] = (string)jd["openid"];
 81             }
 82             catch (Exception ex)
 83             {
 84                 throw new WxPayException(ex.ToString());
 85             }
 86         }
 87 
 88         public string GetEditAddressParameters()
 89         {
 90             string parameter = "";
 91             try
 92             {
 93                 string host = Request.Url.Host;
 94                 string path = Request.Path;
 95                 string queryString = Request.Url.Query;
 96                 //這個地方要注意,參與簽名的是網頁授權獲取用戶信息時微信后台回傳的完整url
 97                 string url = "http://" + host + path + queryString;
 98 
 99                 //構造需要用SHA1算法加密的數據
100                 WxPayData signData = new WxPayData();
101                 signData.SetValue("appid", WxPayConfig.APPID);
102                 signData.SetValue("url", url);
103                 signData.SetValue("timestamp", WxPayApi.GenerateTimeStamp());
104                 signData.SetValue("noncestr", WxPayApi.GenerateNonceStr());
105                 signData.SetValue("accesstoken", Session["access_token"]);
106                 string param = signData.ToUrl();
107 
108                 Log.Debug(this.GetType().ToString(), "SHA1 encrypt param : " + param);
109                 //SHA1加密
110                 string addrSign = FormsAuthentication.HashPasswordForStoringInConfigFile(param, "SHA1");
111                 Log.Debug(this.GetType().ToString(), "SHA1 encrypt result : " + addrSign);
112 
113                 //獲取收貨地址js函數入口參數
114                 WxPayData afterData = new WxPayData();
115                 afterData.SetValue("appId", WxPayConfig.APPID);
116                 afterData.SetValue("scope", "jsapi_address");
117                 afterData.SetValue("signType", "sha1");
118                 afterData.SetValue("addrSign", addrSign);
119                 afterData.SetValue("timeStamp", signData.GetValue("timestamp"));
120                 afterData.SetValue("nonceStr", signData.GetValue("noncestr"));
121 
122                 //轉為json格式
123                 parameter = afterData.ToJson();
124                 Log.Debug(this.GetType().ToString(), "Get EditAddressParam : " + parameter);
125             }
126             catch (Exception ex)
127             {
128                 Log.Error(this.GetType().ToString(), ex.ToString());
129                 throw new WxPayException(ex.ToString());
130             }
131 
132             return parameter;
133         }
134 
135         [HttpPost]
136         public JsonResult CreateWxPayOrder(string openid,string orderno)
137         {
138             Log.Info(this.GetType().ToString(), "生成訂單 : openid:" + openid + ",orderno=" + orderno);
139             ResponseDto<string> ret = new ResponseDto<string>();
140             ret.IsSuccess = false;
141             var order = _order.QueryFirstOrDefault(c => c.OrderNo == orderno);  //訂單信息
142             var orderDetail = _orderDetail.QueryFirstOrDefault(c => c.OrderNo == orderno);  //訂單明細
143             JsApiPay jsApiPay = new JsApiPay();
144             jsApiPay.openid = openid;
145             jsApiPay.total_fee = Convert.ToInt32(order.OrderAmount * 100);  //付款金額
146             try
147             {
148                 WxPayData unifiedOrderResult = GetUnifiedOrderResult(order,orderDetail,ref jsApiPay);
149                 //ViewBag.wxJsApiParam = jsApiPay.GetJsApiParameters();
150                 ret.Data = jsApiPay.GetJsApiParameters();
151                 ret.IsSuccess = true;
152             }
153             catch (Exception ex)
154             {
155                 Log.Info(this.GetType().ToString(), ex.StackTrace);
156                 ret.ErrMessage = ex.Message;
157             }
158             return Json(ret);
159         }
160 
161         public WxPayData GetUnifiedOrderResult(MXOrdersDto order,MXOrderDetailsDto detail,ref JsApiPay api)
162         {
163             WxPayData data = new WxPayData();
164             data.SetValue("body", detail.ProductName);
165             data.SetValue("attach", "XX網訂單");
166             data.SetValue("out_trade_no", order.OrderNo);
167             data.SetValue("total_fee", Convert.ToInt32(order.OrderAmount * 100));
168             data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));
169             data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));
170             data.SetValue("goods_tag", detail.ProductName);
171             data.SetValue("trade_type", "JSAPI");
172             data.SetValue("openid", api.openid);
173             data.SetValue("appid", PublicConst.Wx_appid);//公眾賬號ID
174             data.SetValue("mch_id", PublicConst.Wx_wchid);//商戶號
175             
176             Log.Error(this.GetType().ToString(), Newtonsoft.Json.JsonConvert.SerializeObject(data));
177             WxPayData result = WxPayApi.UnifiedOrder(data);
178             if (!result.IsSet("appid") || !result.IsSet("prepay_id") || result.GetValue("prepay_id").ToString() == "")
179             {
180                 Log.Error(this.GetType().ToString(), "UnifiedOrder response error!");
181                 throw new WxPayException("UnifiedOrder response error!");
182             }
183             api.unifiedOrderResult = result;
184             return result;
185         }
186 
187         /// <summary>
188         /// 獲取code
189         /// </summary>
190         /// <returns></returns>
191         [HttpPost]
192         public ActionResult getCode()
193         {
194             object objResult = "";
195             if (Session["url"] != null)
196             {
197                 objResult = Session["url"].ToString();
198             }
199             else
200             {
201                 objResult = "url為空。";
202             }
203             return Json(objResult);
204         }
205 
206         [HttpPost]
207         public JsonResult WxUpdateOrder(string orderno)
208         {
209             var order = _order.QueryFirstOrDefault(c => c.OrderNo == orderno);
210             if (order != null)
211             {             223                 //這里寫入自己的訂單處理邏輯;
224                 return Json(true);
225             }
226             return Json(false);
227         }
228 
229         /// <summary>
230         /// 接收從微信支付后台發送過來的數據並驗證簽名
231         /// </summary>
232         /// <returns>微信支付后台返回的數據</returns>
233         private WxPayData GetNotifyData()
234         {
235             //接收從微信后台POST過來的數據
236             System.IO.Stream s = Request.InputStream;
237             int count = 0;
238             byte[] buffer = new byte[1024];
239             StringBuilder builder = new StringBuilder();
240             while ((count = s.Read(buffer, 0, 1024)) > 0)
241             {
242                 builder.Append(Encoding.UTF8.GetString(buffer, 0, count));
243             }
244             s.Flush();
245             s.Close();
246             s.Dispose();
247 
248             Log.Info(this.GetType().ToString(), "Receive data from WeChat : " + builder.ToString());
249 
250             //轉換數據格式並驗證簽名
251             WxPayData data = new WxPayData();
252             try
253             {
254                 data.FromXml(builder.ToString());
255             }
256             catch (WxPayException ex)
257             {
258                 //若簽名錯誤,則立即返回結果給微信支付后台
259                 WxPayData res = new WxPayData();
260                 res.SetValue("return_code", "FAIL");
261                 res.SetValue("return_msg", ex.Message);
262                 Log.Error(this.GetType().ToString(), "Sign check error : " + res.ToXml());
263                 Response.Write(res.ToXml());
264                 Response.End();
265             }
266 
267             Log.Info(this.GetType().ToString(), "Check sign success");
268             return data;
269         }

    GenerateOrder.cshtml 頁面代碼:(需要url傳入訂單號)

  1 <!DOCTYPE html>
  2 
  3 <html>
  4 <head>
  5     <meta name="viewport" content="width=device-width" />
  6     <title>生成微信訂單並支付</title>
  7     <script src="~/Scripts/jquery-1.10.2.min.js" type="text/javascript"></script>
  9 </head>
 10 <body>
 11     <p id="pmsg">生成訂單中,請稍候。。。</p>
 12     <input id="txtOrderNo" type="hidden" value="@Request.QueryString["orderno"]" />
 13     <input type="hidden" value="@Request.QueryString["code"]" />
 14     <input id="txtOpenID" type="hidden" value="@ViewBag.openid" />
 15     <script type="text/javascript">
 16         $(function () {
 17             //if (typeof WeixinJSBridge == "undefined") {
 18             //    if (document.addEventListener) {
 19             //        document.addEventListener('WeixinJSBridgeReady', editAddress, false);
 20             //    }
 21             //    else if (document.attachEvent) {
 22             //        document.attachEvent('WeixinJSBridgeReady', editAddress);
 23             //        document.attachEvent('onWeixinJSBridgeReady', editAddress);
 24             //    }
 25             //    //jsApiCall();
 26             //}
 27             //else {
 28             //    editAddress();
 29             //}
 60             callpay();
 61         })
 62         //獲取url的參數
 63         function getQueryString(name) {
 64             var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
 65             var r = window.location.search.substr(1).match(reg);
 66             if (r != null) return unescape(r[2]); return null;
 67         }
 68         function editAddress() {
 69             WeixinJSBridge.invoke(
 70                 'editAddress',
 71                 '',
 72                 function (res) {
 73                     var addr1 = res.provinceFirstStageName;
 74                     var addr2 = res.addressCitySecondStageName;
 75                     var addr3 = res.addressCountiesThirdStageName;
 76                     var addr4 = res.addressDetailInfo;
 77                     var tel = res.telNumber;
 78                     var addr = addr1 + addr2 + addr3 + addr4;
 79                     alert(addr + ":" + tel);
 80                     alert(res.err_code + res.err_desc + res.err_msg);
 91                 }
 92             );
 93         }
 94         function onBridgeReady(json) {
 95             WeixinJSBridge.invoke(
 96                 'getBrandWCPayRequest', {
 97                     "appId": json.appId,     //公眾號名稱,由商戶傳入
 98                     "timeStamp": json.timeStamp,         //時間戳,自1970年以來的秒數
 99                     "nonceStr": json.nonceStr, //隨機串
100                     "package": json.packageValue,
101                     "signType": "MD5",         //微信簽名方式:
102                     "paySign": json.paySign //微信簽名
103                 },
104                 function (res) {
105                     //alert(res.err_code + res.err_desc + res.err_msg);
106                     if (res.err_msg == "get_brand_wcpay_request:ok") {
107                         //alert("支付成功,請稍后查詢余額,如有疑問,請聯系管理員.");
108                         //fAlreadyPay();
                <!--這里寫入回傳的處理邏輯-->
109 $.post("/WxUpdateOrder/?orderno="+$("#txtOrderNo").val(),function(data){ 110 111 }); 112 } // 使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功后返回 ok,但並不保證它絕對可靠。 113 } 114 ); 115 } 116 //調用微信JS api 支付 117 function jsApiCall() { 118 $.ajax({ 119 type: "post", 120 url: "/CreateWxPayOrder/?openid=" + $("#txtOpenID").val() + "&orderno=" + $("#txtOrderNo").val(), 121 async: false, 122 success: function (data) { 123 var json = $.parseJSON(data.Data); 124 $("#pmsg").text("訂單生成成功,轉到支付界面中。。。"); 125 //var json = eval("(" + msg + ")");//轉換后的JSON對象 126 WeixinJSBridge.invoke( 127 'getBrandWCPayRequest', { 128 "appId": json.appId, //公眾號名稱,由商戶傳入 129 "timeStamp": json.timeStamp, //時間戳,自1970年以來的秒數 130 "nonceStr": json.nonceStr, //隨機串 131 "package": json.package, 132 "signType": "MD5", //微信簽名方式: 133 "paySign": json.paySign //微信簽名 134 }, 135 function (res) { 136 //alert(res.err_code + res.err_desc + res.err_msg); 137 if (res.err_msg == "get_brand_wcpay_request:ok") { 138 //alert("支付成功,請稍后查詢余額,如有疑問,請聯系管理員."); 139 //fAlreadyPay(); 140 $.post("/WxUpdateOrder/?orderno=" + $("#txtOrderNo").val(), function (data) { 141 $("#pmsg").text("支付完成"); 143 }); 144 } // 使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功后返回 ok,但並不保證它絕對可靠。 145 } 146 ); 147 }, 148 error: function (XMLHttpRequest, textStatus, errorThrown) { 149 alert(XMLHttpRequest.status); 150 alert(XMLHttpRequest.readyState); 151 alert(textStatus); 152 } 153 }) 169 } 170 171 function callpay() { 172 if (typeof WeixinJSBridge == "undefined") { 173 if (document.addEventListener) { 174 document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); 175 } 176 else if (document.attachEvent) { 177 document.attachEvent('WeixinJSBridgeReady', jsApiCall); 178 document.attachEvent('onWeixinJSBridgeReady', jsApiCall); 179 } 180 //jsApiCall(); 181 } 182 else { 183 jsApiCall(); 184 } 185 } 186 187 </script> 188 </body> 189 </html>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM