zoukankan      html  css  js  c++  java
  • 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有两个小时的有效期

  • 相关阅读:
    Elasticsearch的CURD、复杂查询、聚合函数、映射mappings
    Python操作Elasticsearch对象
    Python连接Elasticsearch
    Elasticsearch的分析过程,内置字符过滤器、分析器、分词器、分词过滤器(真是变态多啊!美滋滋)
    Elasticsearch的数据组织
    Elasticsearch背景初识
    Nginx之负载均衡
    linux常用命令
    百度地图API,定位您的当前位置
    使用gulp自动构建项目
  • 原文地址:https://www.cnblogs.com/zhyzhy/p/14786604.html
Copyright © 2011-2022 走看看