zoukankan      html  css  js  c++  java
  • 【微信支付】公众号 JSAPI支付 HTML5(使用MUI前端框架)+WebApi 实现流程

    必要参数: 

        1) AppID,AppSecret : 在微信公众号后台管理—>(菜单栏)开发 —> 基本设置

     

     

        2)商户号 :在微信公众号后台管理—>(菜单栏)微信支付—> 商户号管理

          

         3)商户秘钥 :在微信商户平台(可直接点击上图的“查看”)商户平台 —> 产品中心 —> 开发配置  

     

     基本配置:

          1)IP白名单:a.测试电脑的ip地址,b.存放WebApi的服务器电脑ip地址

        2)商户平台-->产品中心-->开发配置-->支付配置-->公众号支付:支付授权目录

      

    注:  a.前端页面的地址 b.后台支付方法的地址(都是域名而不是IP)

     

     具体步骤:

        1)添加充值按钮

    <div class="mui-content-padded" style="margin-top: 6%;">            
        <button id='login' class="mui-btn mui-btn-block mui-btn-primary">充值</button>
    </div>
    View Code

          2)引用js

           获取当前设备的IP地址: <script type="text/javascript" src="http://pv.sohu.com/cityjson?ie=utf-8"></script>         

          3)获取code  ,openid      

    注:redirect_uri:是返回当前页面的 url,code的值会追加在这个地址后面,所以可以根据url的地址截取到需要的code值(如果有需要加的参数,可以直接写在后面,如标记的一样)
    (function($) {
                $.init();
                var url = location.search;
                var str = url.substr(1);            
                code = str.split('code=')[1].split('&')[0];           
               //页面加载时,判断code有没有值,没有就访问 获取if (code == 'null') {
                    var numberurl = cardnumber + "=" + id;
                    window.location.href =
                        "https://open.weixin.qq.com/connect/oauth2/authorize?appid=(是你的AppID&redirect_uri=http://llcz.jolinmind.com/taocan.html?number=" +
                        numberurl + "&id=" + id + "&response_type=code&scope=snsapi_base&state=STATE&connect_redirect=1#wechat_redirect";
                    
                } else {
                    var codeN = code;             
                    mui.ajax({
                        url: '……/api/pay/get?jsoncallback=?',
                        data: {
                            code: codeN
                        },
                        async: true,
                        dataType: 'json',
                        crossDomain: true, 
                        type: 'get',
                        timeout: 10000,
                        success: function(data) {
                            openid=data;
                         },
                     });
                }
                
            })(mui);

       后台Webapi:

       _appid =AppID ,_secret =AppSecret  

      public object Get(string code)
            {        
                string html = string.Empty;
                string url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+ _appid + "&secret="+ _secret + "&code="+ code + "&grant_type=authorization_code";
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
                request.Method = "GET";
                request.ContentType = "text/html;charset=UTF-8";
                HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                Stream ioStream = response.GetResponseStream();
                StreamReader sr = new StreamReader(ioStream, Encoding.UTF8);
                html = sr.ReadToEnd();
                sr.Close();
                ioStream.Close();
                response.Close();
                RepParamrepCode rep = JsonConvert.DeserializeObject<RepParamrepCode>(html);
                return rep.openid;
               
            }
    
            public class RepParamrepCode
            {
                public string access_token { get; set; }
                public string expires_in { get; set; }
                public string refresh_token { get; set; }
                public string openid { get; set; }
                public string scope { get; set; }
            }

           4)支付

        document.getElementById("login").addEventListener('tap', function() {
                getCode();
            });function getCode() {
                    mui.ajax({
                                url: '……/api/pay/get?jsoncallback=?',
                                data: {
                                    openid: openid,
                                    motto: returnCitySN.cip,(当前设备的IP地址)
                                    xufei: (支付金额)
                                },
                                async: true,
                                dataType: 'json',
                                crossDomain: true, 
                                type: 'get',
                                timeout: 10000,
                                success: function(res) {                         
    if (typeof WeixinJSBridge == "undefined") { if (document.addEventListener) { document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false); } else if (document.attachEvent) { document.attachEvent('WeixinJSBridgeReady', onBridgeReady); document.attachEvent('onWeixinJSBridgeReady', onBridgeReady); } } else { onBridgeReady(res) } } }); } } function onBridgeReady(data) {
    var list = JSON.parse(data);
    WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId": (你的AppId), "timeStamp": list['timeStamp'], //时间戳,自1970年以来的秒数 "nonceStr": list['nonceStr'], //随机串 "package": list['package1'], "signType": list['signType'], //微信签名方式: "paySign": list['paySign'] //微信签名 }, function(res) { if (res.err_msg == "get_brand_wcpay_request:ok") { 操作成功后,你自己的方法。 } else if (res.err_msg == "get_brand_wcpay_request:cancel") { mui.alert('取消支付!', '提示'); } else { mui.alert('支付失败!', '提示'); } }); }

      后台Webapi:

      public string Get(string openid, string motto, int xufei)
            {
                return Getprepay_id(_appid, _mch_id, GetRandomString(30),"抬头", getRandomTime(), xufei, motto, "http://……/api/OM/get(支付成功后验证数据库是否有数据的地址)", openid);
    
            }
            //微信统一下单获取prepay_id & 再次签名返回数据
            private static string Getprepay_id(string appid, string mch_id, string nonce_str, string body,string out_trade_no,int total_fee, string spbill_create_ip ,string notify_url, string openid)
            {
                var url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信统一下单请求地址
    
                string strA = "appid=" + appid + "&body=" + body + "&mch_id=" + mch_id + "&nonce_str=" + nonce_str + "&notify_url=" + notify_url + "&openid=" + openid + "&out_trade_no=" + out_trade_no + "&spbill_create_ip=" + spbill_create_ip + "&total_fee=" + total_fee + "&trade_type=JSAPI";
    
                string strk = strA + "&key=" + _key; //key为商户平台设置的密钥key(假)
                string strMD5 = MD5(strk).ToUpper();//签名
                var formData = "<xml>";
                formData += "<appid>" + appid + "</appid>";//appid  
                formData += "<body>" + body + "</body>";
                formData += "<mch_id>" + mch_id + "</mch_id>";//商户号  
                formData += "<nonce_str>" + nonce_str + "</nonce_str>";//随机字符串,不长于32位。
                formData += "<notify_url>" + notify_url + "</notify_url>";          
                formData += "<openid>" + openid + "</openid>";
                formData += "<out_trade_no>" + out_trade_no + "</out_trade_no>";
                formData += "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>";//终端IP --用户ip
                formData += "<total_fee>" + total_fee + "</total_fee>";
                formData += "<trade_type>JSAPI</trade_type>";//交易类型(JSAPI--公众号支付)
                formData += "<sign>" + strMD5 + "</sign>"; //签名
                formData += "</xml>";
                string v = sendPost(url, formData);            
                string prepay_id = v;
                //时间戳
                string _time = getTime().ToString();
               
                string strB = "appId=" + appid + "&nonceStr=" + nonce_str + "&package=prepay_id=" + prepay_id + "&signType=MD5&timeStamp=" + _time + "&key=" + _key;
                wx w = new wx();
                w.timeStamp = _time;
                w.nonceStr = nonce_str;
                w.package1 = "prepay_id=" + prepay_id;
                w.paySign = MD5(strB).ToUpper(); 
                w.signType = "MD5";           
                return JsonConvert.SerializeObject(w);           
            }
    
            private static string sendPost(string postUrl, string menuInfo)
            {
                string returnValue = string.Empty;
                byte[] byteData = Encoding.UTF8.GetBytes(menuInfo);
                Uri uri = new Uri(postUrl);
                HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(uri);
                webReq.Method = "POST";
                webReq.ContentType = "application/x-www-form-urlencoded";
                webReq.ContentLength = byteData.Length;
                //定义Stream信息
                Stream stream = webReq.GetRequestStream();
                stream.Write(byteData, 0, byteData.Length);
                stream.Close();
                //获取返回信息
                HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
                StreamReader streamReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                returnValue = streamReader.ReadToEnd();
                //关闭信息
                streamReader.Close();
                response.Close();
                stream.Close();
    
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(returnValue);
                XmlNodeList list = doc.GetElementsByTagName("xml");
                XmlNode xn = list[0];
                string prepay_ids = xn.SelectSingleNode("//prepay_id").InnerText;
                return prepay_ids;
               
            }
             /// <summary>
            /// MD5签名方法 
            /// </summary> 
            /// <param name="inputText">加密参数</param> 
            /// <returns></returns> 
            private static string MD5(string inputText)
            {
                MD5 md5 = new MD5CryptoServiceProvider();
                byte[] fromData = System.Text.Encoding.UTF8.GetBytes(inputText);
                byte[] targetData = md5.ComputeHash(fromData);
                string byte2String = null;
    
                for (int i = 0; i < targetData.Length; i++)
                {
                    byte2String += targetData[i].ToString("x2");
                }
    
                return byte2String;
            }
            /// <summary>
            /// 生成订单号
            /// </summary>
            /// <returns></returns>
            private static string getRandomTime()
            {
                Random rd = new Random();//用于生成随机数
                string DateStr = DateTime.Now.ToString("yyyyMMddHHmmssMM");//日期
                string str = DateStr + rd.Next(10000).ToString().PadLeft(4, '0');//带日期的随机数
                return str;
            }
            /// <summary>
            /// 生成随机串  
            /// </summary>
            /// <param name="length">字符串长度</param>
            /// <returns></returns>
            private static string GetRandomString(int length)
            {
                const string key = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
                if (length < 1)
                    return string.Empty;
    
                Random rnd = new Random();
                byte[] buffer = new byte[8];
    
                ulong bit = 31;
                ulong result = 0;
                int index = 0;
                StringBuilder sb = new StringBuilder((length / 5 + 1) * 5);
    
                while (sb.Length < length)
                {
                    rnd.NextBytes(buffer);
    
                    buffer[5] = buffer[6] = buffer[7] = 0x00;
                    result = BitConverter.ToUInt64(buffer, 0);
    
                    while (result > 0 && sb.Length < length)
                    {
                        index = (int)(bit & result);
                        sb.Append(key[index]);
                        result = result >> 5;
                    }
                }
                return sb.ToString();
            }
             /// <summary>
            /// 获取时间戳
            /// </summary>
            /// <returns></returns>
            /// 
            private static long getTime()
            {
                TimeSpan cha = (DateTime.Now - TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)));
                long t = (long)cha.TotalSeconds;
                return t;
            }

      

      微信支付接口签名验证工具:

      https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=20_1

         

  • 相关阅读:
    nanoPI kernel compile record
    Golang go get第三方库的坑
    Python解析Linux命令行
    Linux:dd命令
    Golang异常处理
    Golang自定义包导入
    Golang覆盖写入文件的小坑
    Golang数据类型总结及其转换
    ASP.NET学习之页面传值(8)_Application传值
    ASP.NET学习之页面传值(7)_Cookie传值
  • 原文地址:https://www.cnblogs.com/bonnie-w/p/11937509.html
Copyright © 2011-2022 走看看