zoukankan      html  css  js  c++  java
  • 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>
  • 相关阅读:
    java嵌套接口
    关于继承与多态
    重看Maven技术
    npm常用命令及参数总结
    vue.js和node.js的关系
    Invalid [xxx] in servlet mapping 、 <url-pattern>的匹配规则
    Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'name' in 'field list'
    关于中文词云生成报错
    easygui安装过程
    将写好的python软件打包成程序
  • 原文地址:https://www.cnblogs.com/Chaser-Eagle/p/9051919.html
Copyright © 2011-2022 走看看