.net mvc 微信支付
1 一、微信第三方登录 2 通过微信打开链接:http://www.hzm.com/Entry/Login 3 微信OAuth2.0授权登录目前支持authorization_code模式,适用于拥有server端的应用授权。该模式整体流程为: 4 1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数; 5 6 2. 通过code参数加上AppID和AppSecret等,通过API换取access_token; 7 8 3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。 9 1.控制器中代码 10 public ActionResult Login() 11 { 12 //若已经登录,直接跳到首页 13 if (HttpContext.User.Identity.IsAuthenticated) 14 { 15 return RedirectToAction("Index", "Entry"); 16 } 17 //微信登录 18 //1.获取code 19 if (string.IsNullOrEmpty(Request.QueryString["code"])) 20 { 21 //从定向到微信,微信再重定向到当前函数(进入第1步获取code) 22 return RedirectToWeixin(); 23 } 24 //2.获取openID 25 //通过code获取openID 26 string openID = ""; 27 try 28 { 29 openID = GetOpenID(Request.QueryString["code"]); 30 } 31 catch(Exception e) 32 { 33 Log.Debug("GetOpenID Exception", e.StackTrace); 34 return Redirect("/Entry/Login"); 35 } 36 //3.查找或存储用户信息 37 User user = new User(); 38 user = db.Users.SingleOrDefault(p => p.OpenID == openID); 39 if (user == null) 40 { 41 //添加用户 42 user = new User(); 43 user.OpenID = openID; 44 db.Users.Add(user); 45 db.SaveChanges(); 46 } 47 //登录成功 48 FormsAuthentication.SetAuthCookie(user.ID.ToString(), false);//记录登录凭证 49 return RedirectToAction("Index", "Entry"); 50 } 51 1.1.获取code 52 private ActionResult RedirectToWeixin() 53 { 54 JsApiPay jsApiPay = new JsApiPay(this); 55 var redirect_url = jsApiPay.GetRedirectToWeixinUrlForCode();//将回调stata参数值设为awardUserID 56 return Redirect(redirect_url);//调回:/Entry/Login 57 } 58 1.2.通过code获取openID和access_token 59 private string GetOpenID(string code) 60 { 61 JsApiPay jsApiPay = new JsApiPay(this); 62 //如果code有值 63 if (!string.IsNullOrEmpty(code)) 64 { 65 Log.Debug(" GetOpenID code", code); 66 //去获取OpenID 67 jsApiPay.GetOpenidAndAccessTokenFromCode(code); 68 } 69 Log.Debug("GetOpenidAndAccessTokenFromCode openid", jsApiPay.openid.ToString()); 70 return jsApiPay.openid.ToString(); 71 } 72 二、微信支付 73 2.1.生成业务订单和微信交易号Out_trade_no 74 public ActionResult CreateOrder(int entryID, PayMode payMode) 75 { 76 //一个报名只应对应一个订单 77 //判断订单是否已经存在,则直接进入详情页 78 if (db.Orders.Any(p => p.EntryID == entryID)) 79 { 80 return Redirect("/Entry/Detail?out_trade_no=" + db.Orders.SingleOrDefault(p => p.EntryID == entryID).Out_trade_no); 81 } 82 Entry entry = db.Entrys.Include("Event").SingleOrDefault(p => p.ID == entryID); 83 Order order = new Order(); 84 order.EntryID = entry.ID; 85 order.Amount = GetDiscount(entry.Event); 86 order.PayMode = payMode; 87 order.State = OrderSatet.Unpaid; 88 order.SubmitTime = DateTime.Now; 89 order.Body = entry.Event.Theme; 90 order.Out_trade_no = WxPayApi.GenerateOutTradeNo(); 91 db.Orders.Add(order); 92 db.SaveChanges(); 93 if (payMode == PayMode.Remittance) 94 { 95 return RedirectToAction("Detail", new { out_trade_no = order.Out_trade_no }); 96 } 97 return RedirectToAction("Pay", new { orderID = order.ID }); 98 } 99 2.2.微信支付 100 public ActionResult Pay(int orderID) 101 { 102 //获取订单 103 Order order = db.Orders.SingleOrDefault(p => p.ID == orderID); 104 105 //修改支付方式 106 order.PayMode = PayMode.Weixin; 107 db.SaveChanges(); 108 109 //微信openID 110 Entry entry = db.Entrys.Include("Event").SingleOrDefault(p => p.ID == order.EntryID); 111 User user = db.Users.SingleOrDefault(p => p.ID == entry.UserID); 112 Log.Debug("openID", user.OpenID); 113 Log.Debug("entry.UserID", entry.UserID.ToString()); 114 Log.Debug("HttpContext.User.Identity.Name", HttpContext.User.Identity.Name); 115 //当前订单的商户系统的订单号 116 ViewData["out_trade_no"] = order.Out_trade_no; 117 //支付费用 118 decimal totalFee = GetDiscount(entry.Event); 119 Log.Debug("totalFee", "100.00"); 120 JsApiPay jsApiPay = new JsApiPay(this); 121 try 122 { 123 //若传递了相关参数,则调统一下单接口,获得后续相关接口的入口参数 124 jsApiPay.openid = user.OpenID; 125 126 jsApiPay.total_fee = Convert.ToInt32(totalFee * 100);//支持两位小数,如0.01 127 Log.Debug(this.GetType().ToString(), "参数赋值成功1"); 128 //JSAPI支付预处理 129 Log.Debug(this.GetType().ToString(), "参数赋值成功2"); 130 WxPayData unifiedOrderResult = jsApiPay.GetUnifiedOrderResult(entry.Name + "的" + entry.Event.Theme, "报名", order.Out_trade_no); 131 132 Log.Debug(this.GetType().ToString(), "预支付订单生成成功"); 133 //获取H5调起JS API参数 134 var wxJsApiParam = jsApiPay.GetJsApiParameters(); 135 ViewData["wxJsApiParam"] = wxJsApiParam; 136 137 Log.Debug(this.GetType().ToString(), "wxJsApiParam参数获取成功"); 138 //预支付订单号 139 var prepay_id = jsApiPay.unifiedOrderResult.GetValue("prepay_id").ToString(); 140 ViewData["prepay_id"] = prepay_id; 141 Log.Debug(this.GetType().ToString(), "prepay_id参数获取成功"); 142 /*###################################*/ 143 Log.Debug(this.GetType().ToString(), "wxJsApiParam : " + wxJsApiParam); 144 } 145 catch (Exception ex) 146 { 147 Response.Write("<span style='color:#FF0000;font-size:20px'>" + "下单失败,请返回重试" + "</span>"); 148 Log.Debug("Award-ConfirmPayPage", ex.Message + ex.StackTrace); 149 Log.Debug("Award-ConfirmPayPage", "预支付订单生成或保存异常"); 150 } 151 152 return View(); 153 154 } 155 2.3.页面中调起微信支付接口(Pay.html) 156 @{ 157 Layout = null; 158 } 159 <!DOCTYPE html> 160 <html> 161 <head> 162 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 163 <title>支付页面</title> 164 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> 165 <script type="text/javascript"> 166 var wxJsApiParam=@Html.Raw(ViewData["wxJsApiParam"].ToString()); 167 //调用微信JS api 支付 168 169 function jsApiCall() { 170 WeixinJSBridge.invoke( 171 'getBrandWCPayRequest', 172 wxJsApiParam, 173 function (res) 174 { 175 WeixinJSBridge.log(res.err_msg); 176 177 //alert(res.err_code + res.err_desc + res.err_msg); 178 179 if(res.err_msg=="get_brand_wcpay_request:ok"){ 180 location.href ="/Entry/Detail?out_trade_no=@ViewData["out_trade_no"]"; 181 }else 182 { 183 location.href ="/Entry/Detail?out_trade_no=@ViewData["out_trade_no"]"; 184 } 185 186 //alert(res.err_msg); 187 } 188 ); 189 } 190 191 function callpay() 192 { 193 if (typeof WeixinJSBridge == "undefined") 194 { 195 if (document.addEventListener) 196 { 197 document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); 198 } 199 else if (document.attachEvent) 200 { 201 document.attachEvent('WeixinJSBridgeReady', jsApiCall); 202 document.attachEvent('onWeixinJSBridgeReady', jsApiCall); 203 } 204 } 205 else 206 { 207 jsApiCall(); 208 } 209 } 210 callpay(); 211 </script> 212 </head> 213 <body> 214 </body> 215 </html> 216 2.4.支付成功后微信发送支付成功异步通知(post方式,通知地址在Config.cs中配置的NOTIFY_URL,在这里添加订单处理业务逻辑) 217 public ActionResult Notify() 218 { 219 ResultNotify notify = new ResultNotify(this); 220 WxPayData data = notify.GetNotifyData(); 221 Log.Debug("return_code", data.GetValue("return_code").ToString()); 222 Log.Debug("return_msg", data.GetValue("return_code").ToString()); 223 if (data.GetValue("return_code").ToString() == "SUCCESS") 224 { 225 Log.Debug("out_trade_no", data.GetValue("out_trade_no").ToString()); 226 var out_trade_no = data.GetValue("out_trade_no").ToString(); 227 228 Order order = db.Orders.SingleOrDefault(p => p.Out_trade_no == out_trade_no); 229 Log.Debug("orderID", order.ID.ToString()); 230 231 order.State = OrderSatet.Paid; 232 var time_end = data.GetValue("time_end").ToString(); 233 order.PayTime = DateTime.ParseExact(time_end, "yyyyMMddHHmmss", CultureInfo.CurrentCulture); 234 order.TransactionID = data.GetValue("transaction_id").ToString(); 235 order.OpenID = data.GetValue("openid").ToString(); 236 db.SaveChanges(); 237 238 } 239 notify.ProcessNotify(); 240 241 return View(); 242 } 243 2.5.支付成功后跳转到(Pay.html页面设置的地址) 244 如:location.href ="/Entry/Detail?out_trade_no=@ViewData["out_trade_no"]";
微信支付官方文档地址:
1.App微信支付:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3
posted on 2016-03-15 12:00 CeleryCabbage 阅读(1736) 评论(0) 收藏 举报
浙公网安备 33010602011771号