zoukankan      html  css  js  c++  java
  • .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
  • 相关阅读:
    移动端底部fixed固定定位输入框ios下不兼容
    mint-ui Picker设置指定初始值
    vue项目的mode:history模式
    更改checkbox的默认样式
    vue组件通信的几种方式
    Python运行Google App Engineer时出现的UnicodeDecodeError错误解决方案
    ActionFilterAttribute之HtmlFilter,压缩HTML代码
    MongoDB C#驱动中Query几个方法
    无需路由端口映射 花生壳6.5工程版发布
    如何让搜索引擎抓取AJAX内容?
  • 原文地址:https://www.cnblogs.com/CeleryCabbage/p/5278837.html
Copyright © 2011-2022 走看看