本文详解微信公众号H5页面集成微信支付与支付宝支付的前端实现。微信支付通过JS-SDK完成授权与支付,需先在路由拦截中获取code并生成openId。针对微信内无法直接唤起支付宝的问题,采用中间页跳转至外部浏览器的方式解决,确保支付流程顺畅。
整体技术方案概述
一、微信支付集成方案
鉴于微信环境下的用户授权机制,微信支付功能需依赖JS-SDK实现。
二、支付宝支付集成方案
核心难点在于,在微信浏览器完成H5授权后,无法直接在微信内部唤起支付宝的支付链接。
解决方案是引入一个中间跳转页面,引导用户跳转至手机默认浏览器完成支付操作。
具体实施步骤如下
一、微信支付详细实现
首先进行微信授权,需在项目入口文件main.js中配置路由拦截逻辑,以获取用户授权码code,相关实现代码见下方。
// main.js
router.beforeEach(async (to: RouteLocationNormalized,from: RouteLocationNormalized,next) => {
// 判断有没有openId 即授权了直接放行
if (store.state.openId) {
next()
} else {
// 没有授权去授权获取code 再放行
const code = await getCode()
await queryInfo(code)
next()
}
})
// 获取code
function getCode() {
const code = getUrlCode()?.code
if (!code) {
// 没有code 请求后端接口进行链接跳转获取code(链接值微信的授权链接,成功授权后会跳回 回调地址,在回调地址上 会携带code参数)
return getWxOauthUrl({
redirectUrl: window.location.href
}).then(async ({data}) => {
if (data.statusCode === 0) {
window.location.replace(data.msg)
}
})
} else {
return code
}
}
// 通过code 获取用户信息
function queryInfo(code: string) {
return getUserInfo([code]).then(({data}) => {
const result = data.data || {}
store.commit('getUserInfo', result)
store.commit('getUserOpenId', result.openId)
})
}
// 获取url 参数的通用方法
function getUrlCode() {
// 截取url中的code方法
const url = location.search;
const theRequest = new Object();
if (url.indexOf("?") !== -1) {
const str = url.substr(1);
const strs = str.split("&");
for (let i = 0; i < strs.length; i++) {
theRequest[strs[i].split("=")[0]] = strs[i].split("=")[1];
}
}
return theRequest;
}成功获取授权后,即可进入后续的支付环节。
核心代码实现
// 首先在index.html 中引入微信JS-SDK
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
// 然后在支付逻辑中添加以下代码即可~
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();
}
function onBridgeReady(result) {
WeixinJSBridge.invoke('getBrandWCPayRequest', {
"appId": , //公众号ID,由商户传入
"timeStamp": , //时间戳,自1970年以来的秒数
"nonceStr": , //随机串
"package": ,
"signType": , //微信签名方式:
"paySign":
},
function (res) {
if ((res.errMsg || res.err_msg) === "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
}
});
}至此,微信支付的完整流程已处理完毕。
二、支付宝支付详细实现
由于当前页面处于微信授权后的H5环境中,直接调用支付宝支付接口在微信浏览器内不可行。
因此,第一步操作是在用户点击支付按钮时,触发页面跳转至预设的中间页。
首先需定义一个中间页文件,命名为pay.html。
注意:该中间页文件必须放置于项目的publish发布目录下。
// 跳转中间页,把请求支付的参数一并带过去
window.open(`${location.origin}/pay.htm?params=${encodeURIComponent(JSON.stringify(params))}`)pay.html页面的核心逻辑如下所示
let getQueryString = function (url, name) {
let reg = new RegExp("(^|\\?|&)" + name + "=([^&]*)(\\s|&|$)", "i");
if (reg.test(url)) return RegExp.$2.replace(/\+/g, " ");
};
// 获取接口返回的表单 进行支付
function handlePayForm(data) {
const div = document.createElement("div");
div.setAttribute("id", "payContainer");
div.innerHTML = data
document.body.appendChild(div);
const payContainer = document.querySelector("#payContainer");
const submit = payContainer.querySelector(
'form[name="punchout_form"] input[type="submit"]'
);
submit.click();
setTimeout(function () {
div.remove();
}, 500);
};
if (location.hash.indexOf('error') !== -1) {
alert('参数错误,请检查');
} else {
// 判断当前的浏览器环境是不是微信浏览器
let ua = navigator.userAgent.toLowerCase();
let tip = document.querySelector(".weixin-tip");
let tipImg = document.querySelector(".J-weixin-tip-img");
const query = JSON.parse(decodeURIComponent(getQueryString(location.href, 'params')))
if (ua.indexOf('micromessenger') !== -1) {
// 如果是微信里的页面,做个指引(请通过浏览器进行支付)
// 这个页面自己定义即可
} else {
// 好的,这是外部浏览器,请求接口获取支付的from表单
axios({
url: '',
data: query,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then(({data}) => {
if (data.statusCode === 0) {
// 后端返回的form表单进行支付
if (data.data && data.data.returnCode === "SUCCESS") {
// data.data.result ==> 是一个支付的from表单
handlePayForm(data.data.result)
}
}
})
}
}通过上述配置,即可成功跳转至微信外部浏览器,从而正常完成支付功能。
总结
本文介绍了微信公众号H5环境下微信支付及支付宝支付的前端实现方法,更多公众号H5支付相关内容可参考本站往期文章或继续浏览后续内容,感谢支持。