h5微信支付

h5调用微信支付相关记录

步骤流程

  1. 微信授权拿到code(https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html)
  2. 用code换取openid(这一步一般是后台提供接口)
  3. 用生成的openid去获取微信支付需要的参数(也是接口处理)
  4. 前端调用微信方法,拉起微信支付

根据上面的流程执行

  1. 添加微信授权逻辑,完成微信授权获取code,通过code拿到openid存在本地

    <!-- 先获取地址栏参数code -->
    const code = getUrlParam(‘code‘);

    <!-- 获取cookie,wx-openid为微信授权成功后,通过code向服务端接口获取到的openid,存入本地,两个小时后失效 -->
    const wxOpenid = getCookie(‘wx-openid‘);

    if(!wxOpenid){
        // 1.没有微信授权,需要先去授权
        if(!code){
            var link = window.location.href.split("?")[0];
            <!-- scope = snsapi_base 表示静默授权  -->
            var wxAuthUrl="https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的服务号id&redirect_uri="+link+"&response_type=code&scope=snsapi_base&state=code#wechat_redirect";
            location.href = wxAuthUrl;
        }else{
            // 地址栏里能取到code,且cookie里面没有wxOpenid,此时需要调用接口用code换取token
            codeToToken();
        }
    }
    
    // 用微信授权的code去接口换取token,并存入本地cookie
    function codeToToken(){
        $.ajax({
            type: "POST",
            dataType: "json",
            url: "http://111/111/111",
            data:{code:code},
            success: function (data) {
                console.log(data);//打印服务端返回的数据(调试用)
                if (data.code === 200) {
                    // 将取到的token存入cookie,1.8小时
                    setCookie("wx-openid",data.data,1.8);
                }
            }
        });
    }

    function getUrlParam(name) {
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
        var r = window.location.search.substr(1).match(reg);  //匹配目标参数
        if (r != null) return unescape(r[2]); return null; //返回参数值
    }

    function setCookie(objName, objValue, objHours) {
        var str = objName + "=" + escape(objValue); //编码
        if (objHours > 0) {//为0时不设定过期时间,浏览器关闭时cookie自动消失
            var date = new Date();
            var ms = objHours * 3600 * 1000;
            date.setTime(date.getTime() + ms);
            str += "; expires=" + date.toGMTString();
        }
        document.cookie = str;
    }

    function getCookie(key){
        var arr1=document.cookie.split("; ");//由于cookie是通过一个分号+空格的形式串联起来的,所以这里需要先按分号空格截断,变成[name=Jack,pwd=123456,age=22]数组类型;
        for(var i=0;i<arr1.length;i++){
            var arr2=arr1[i].split("=");//通过=截断,把name=Jack截断成[name,Jack]数组;
            if(arr2[0]==key){
                return decodeURI(arr2[1]);
            }
        }
    }

  1. 用生成的openid去获取微信支付需要的参数(也是接口处理)
    <!-- 引入微信js -->
    <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

    <!-- 这一步一般是用点击页面的按钮触发一个方法 -->
    // 判断是否有wx-openid,没有wx-openid就刷新页面重新开始微信授权和获取wx-openid(当进入页面时wx-openid没有过期,当准备支付时改cookie过期了)
    if(!getCookie(‘wx-openid‘)){
        location.href=window.location.href.split("?")[0];
    }

    let payParam = {}

    $.ajax({
        type: "POST",//方法类型
        dataType: "json",//预期服务器返回的数据类型
        async:false,
        url: "http://222/222/222" ,//url
        data:{"接口需要的参数":"根据接口需要提供的参数值"},
        success: function (date) {
            if (date.code == 200) {
                payParam = JSON.parse(date.data);
                weixinPay()
            }else {
                alert("接口调用失败,拉去微信授权失败")
            }
        },

    });


    function weixinPay() {
        if (typeof WeixinJSBridge !== ‘undefined‘) {
            onBridgeReady();
            return;
        }
        if (document.addEventListener) {
            document.addEventListener(‘WeixinJSBridgeReady‘, onBridgeReady, false);
        } else if (document.attachEvent) {
            document.attachEvent(‘WeixinJSBridgeReady‘, onBridgeReady);
            document.attachEvent(‘onWeixinJSBridgeReady‘, onBridgeReady);
        }
    }


    function onBridgeReady() {

        WeixinJSBridge.invoke(‘getBrandWCPayRequest‘, {
            appId:payParam.appId, // 公众号名称,由商户传入
            // timeStamp:时间戳,自1970年以来的秒数,需要传递string类型,测试过程中发现如果传递的是number类型,android拉起微信支付会报错,提示调用支付JSAPI缺少参数:timeStamp,ios正常可以拉起微信支付
            timeStamp:"" + payParam.timeStamp,
            nonceStr:payParam.nonceStr, // 随机串
            package: payParam.package,
            signType:payParam.signType, // 微信签名方式:
            paySign:payParam.paySign, // 微信签名
        }, res => {
            switch (res.err_msg) {
                case ‘get_brand_wcpay_request:ok‘:
                    alert("支付成功,可以在此添加支付成功的回调");
                    break;
                case ‘get_brand_wcpay_request:cancel‘:
                    alert("取消支付");
                    break;
                case ‘get_brand_wcpay_request:fail‘:
                    alert("失败");
                    break;
                default: break;
            }

            <!-- 好了,到此就已经拉起了微信支付了 -->
        });
    }

在开发中遇到的问题

  1. 微信授权获取code,这一步操作在调用接口http://222/222/222时,接口那边操作的,非前端处理
    这一步当时是行不通的,因为调用接口http://222/222/222时,接口响应的是this.ctx.redirect(‘https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的服务号id&redirect_uri="+link+"&response_type=code&scope=snsapi_base&state=code#wechat_redirect‘,302);
    但是我们需要接口响应的是json数据,通过抓包工具分析后,我们更换了方案,由前端来进行微信授权

  2. 前端微信授权,由于302来回跳转,页面有跳转记录,在ios的微信上,底部会出现回退操作栏,产品要求去掉
    找了很多方案,发现去不掉,最后使用了node渲染页面,在node层进行微信授权,发现可以解决这个问题

  3. 开发过程中,刚开始存入cookie的不是通过code获取的openid 而是code,当第一次授权成功,超过5分钟进入页面,从cookie里面拿到code,调起微信支付时,传给接口的是code,接口通过code去换取openid
    但是此时code已经过期,code只有5分钟有效期,openid有两个小时的有效期

h5微信支付

上一篇:Linux上安装微信开发者工具


下一篇:package