微信支付功能

具体流程(详见文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html)

1、前端提交申请获取用户授权

let ua = navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == "micromessenger") {   //判断是微信端
    window.location.href=`https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=http%3a%2f%2fm.test.demo.com%2fmoneyManage%2fwxpay&response_type=code&scope=snsapi_base&state=${this.moneyAmount}#wechat_redirect`
    } else{}

注:
appid是微信公众号里设置的
redirect_uri需要UrlEncode编码处理,redirect_uri路径所在的域需要和公众号里设置的一致,一定要一致。
state在授权过后微信返回给你的url中也会携带,可以用来传参

2、拿到微信返回给你的url并进行处理(注:获取授权成功后会自动跳转至url页面,即此url页面也是微信支付调起的页面,你的其他操作可以放在此页完成)

拿到的url格式如下
redirect_uri/?code=CODE&state=STATE。

提取url里的code和state
getQueryString(name){    
    let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");  
    let r = window.location.search.substr(1).match(reg);  
    if (r != null) return unescape(r[2]); 
    return null;              
}, 

3、拿到code后去请求后台的处理接口,拿到相关数据

getWxData(){
    let code=this.getQueryString("code")
    let money=this.getQueryString("state")
    let params=new FormData()
    params.append('money',money)
    params.append('bs',3)
    params.append('code',code)   //上传哪些参数看后台需要,但是code是必传的
    this.$axios.post(`${common.orderApi}/amstc/demowxpay`,params).then(res=>{
        if(res.data.code==200){
            this.payparams=JSON.parse(res.data.data)  //若后台返回的字符串格式,这里需要转为json格式

            //准备调用微信内置支付函数,拉取微信内部的支付功能
            //详情见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
            let funtimes=setTimeout(()=>{   //为什么要用定时器?为了延迟加载微信内置的支付函数,因为页面初始化时不一定能拿到此函数
                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 {    //拿到了内置的支付函数,则将从接口拿来的数据提交到微信内置的支付函数
                    this.onBridgeReady();
                }
                clearTimeout(funtimes)         
            },1000)
        }
    }).catch(err=>{})
},

4、微信内置的支付函数

//微信内部调起支付功能的函数,只有在微信app里才会生效,在微信开发工具也不会生效,所以测试时需要真机测试。
onBridgeReady(){
    WeixinJSBridge.invoke(
        'getBrandWCPayRequest', {
        "appId":this.payparams.appid,     //公众号名称,由商户传入     
        "timeStamp":this.payparams.time_stamp,         //时间戳,自1970年以来的秒数     
        "nonceStr":this.payparams.nonce_str, //随机串     
        "package":`prepay_id=${this.payparams.prepay_id}`,     
        "signType":"MD5",         //微信签名方式:     
        "paySign":this.payparams.sign //微信签名 
    },
    function(res){
        if(res.err_msg == "get_brand_wcpay_request:ok" ){  
            this,message='充值成功'
            this.isSuccess=1
        } else{
            this.message="未能完成充值"
            this.isSuccess=2
        }
    }); 
},

说一说坑

  • 微信浏览器内置的支付函数在vue的created()生命周期是拿不到的,所以可以设置定时器延迟加载该支付函数。或者在mounted里加载支付函数(没试过)
  • 沙箱环境是实现不了支付功能的,切记,微信测试只能实实在在的去付钱,测试莫得用。当然除了最后一步拉取支付函数,其他步骤还是可以测试测试的。
  • 公众号配置的域名一定要与前端的redirect_uri域名一致
posted @ 2019-12-20 17:48  huihuihero  阅读(371)  评论(0编辑  收藏  举报