微信支付在微信内置浏览器(SDK)和外部浏览器的实现

794 阅读2分钟

一、功能准备

需要在相应的微信公众号(服务号)及微信商户平台开通支付功能,并配置支付域名。

微信公众平台地址:mp.weixin.qq.com

微信商户平台地址:pay.weixin.qq.com

微信支付文档地址:pay.weixin.qq.com/wiki/doc/ap…

例:打开公众号里的功能设置,配置JS接口安全域名,目的是能在微信内部浏览器使用微信支付

image.png

微信商户平台添加支付域名,目的是能在外部浏览器使用微信支付

image.png

二、具体实现

1.开发准备

值得注意的是,这里的demo项目用的vue框架

在项目中安装微信支付SDK: npm install weixin-js-sdk -s

在main.js挂载SDK:

import wx from 'weixin-js-sdk'
Vue.prototype.$wx = wx

SDK文档参考链接:developers.weixin.qq.com/doc/offiacc…, www.w3cschool.cn/weixinkaifa…

2.主要代码部分

1)内置浏览器支付(SDK)

即为微信公众号支付,是在微信内置浏览器中的支付,首先需要向微信获取code,然后在后续支付时传给后端,才能拿到SDK支付所需的签名、时间戳等参数。

值得注意的是,每个code只能用一次;即每次使用完后都要重新获取一次。

获取code的原理是通过访问带目的参数的URL后,自动跳转回携带code的原地址,code便可现有地址中取出,具体使用方法如下:

// 获取code函数
getWXCode(scope) {
    let urlNow = encodeURIComponent(this.funcUrlDel("code") || location.href);
    //应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息 )
    let appid = "wx46dasdmaskdmdasd;
    let state = "stylikaH5";
    let url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${urlNow}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`;
    window.location.href = url;
}

// 调用获取code
this.getWXCode("snsapi_base")


// 删除URL后面的query,返回原URL
funcUrlDel(name) {
    var loca = window.location;
    var baseUrl = loca.origin + loca.pathname + "?";
    var query = loca.search.substr(1);
    
    if (query.indexOf(name) > -1) {
        var obj = {};
        var arr = query.split("&");
        for (var i = 0; i < arr.length; i++) {
                arr[i] = arr[i].split("=");
                obj[arr[i][0]] = arr[i][1];
        }
        delete obj[name];
        var url = baseUrl + JSON.stringify(obj).replace(/[\"\{\}]/g, "").replace(/\:/g, "=").replace(/\,/g, "&");
        return url;
    }
}


//获取url 中的code
getUrlKey(name) {
    return (
        decodeURIComponent((new RegExp("[?|&]" + name + "=" + "([^&;]+?)(&|#|;|$)").exec(location.href) || [, ""])[1].replace(/\+/g, "%20")) || null
    );
}

// 调用获取URL中的code,若没有则返回null,可以用来判断是否已经获取
this.getUrlKey("code")

初始化配置信息,传给后端当前URL,获取初始化配置参数

getWXConfigData() {
    this.$iHttp.post("/api/get_sign/", {
        url: location.href.split("#")[0]
    }).then(res => {
        this.$wx.config({
                debugfalse, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                appId"wx46asndjasndjansd", // 必填,公众号的唯一标识
                timestamp: res.data.data.sign.timestamp, // 必填,生成签名的时间戳
                nonceStr: res.data.data.sign.noncestr, // 必填,生成签名的随机串
                signature: res.data.data.sign.signature, // 必填,签名
                jsApiList: [ // 需要获得的能力
                            "chooseWXPay",
                            "updateAppMessageShareData",
                            "updateTimelineShareData"
                ],
                success(res) {
                        // 初始化成功
                },
                fail(err) {
                        // 初始化失败
                }
        });
    });
}

支付部分,调用后台支付接口,将code以及其他支付参数传入,获取SDK支付所需参数,如下;

值得注意的是,code只能用一次,所以不管调用成功或失败都要再次重新获得!

// 执行支付

this.$wx.chooseWXPay({
    timestamp: res.data.data.res_data.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
    nonceStr: res.data.data.res_data.nonceStr, // 支付签名随机串,不长于 32位
    package: res.data.data.res_data.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
    signType: res.data.data.res_data.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
    paySign: res.data.data.res_data.paySign, // 支付签名
    successres => {
            //支付成功
    },
    errorerr => {},
    cancelfunction(cel) {},
    completefunction(col) {}
});

2)外部浏览器支付

外部浏览器支付操作很简单,即只要在微信公众平台配置好合法域名后,正常调用支付接口,使用后端返回来的跳转链接即可!

Tips:如果要在内部浏览器获取用户信息的话,只需要改变scope就行了,也就是正常的微信登录,如this.getWXCode("snsapi_userinfo")