uniapp VUE-H5页面微信公众号内使用微信JSAPI支付

发布时间 2023-09-15 11:51:36作者: 橙汁不加糖

注意看 本文主要讲解uniapp打包成h5页面并部署在公众号时使用JSAPI的微信支付问题
前期准备工作
.首先要有一个开通商户注册的公众号,我们需要他的appid;
.其次要开通商户公众号的公众号支付的功能并添加域名,开通完成后就可以基本开始我们的开发了

既然是jsapi开发 自然是要引入的
npm install weixin-jsapi
在页面引入文件
import wx from 'weixin-jsapi'
如果是html文件中可以script标签引入

再来就是熟悉一下流程
微信支付需要先跳转到微信指定的页面获取code ,这个code在跳到微信指定的页面时会把这个code自动添加到地址栏中
然后我们再把这个code传给后端拿到openid ,再之后把openid给到后端获取调起微信支付的一系列参数
以下为作者的个人的支付流程 大家可以自行参考
OK 第一步 获取code
这里作者采用了静默授权的方式获取code
首先 copy两段来自其他地方的代码以获取code

点击查看代码
function getUrlKey(name){//获取url 参数
	 return decodeURIComponent((new RegExp('[?|&]'+name+'='+'([^&;]+?)(&|#|;|$)').exec(window.location.href)||[,""])[1].replace(/\+/g,'%20'))||null;
	 }
此段代码为获取地址栏上参数名为name的值,后续我们会且只会传‘code’以获取地址栏上的code值
点击查看代码
function getCodeApi(state){//获取code 
	 let urlNow=encodeURIComponent(window.location.href);
	 let scope='snsapi_base'; //snsapi_userinfo //静默授权 用户无感知
	 let appid='你的appid';//可以自己写死在这或者让后端传给你 作者是直接在此处写死的
	 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.replace(url);
	}
这段代码为拼接地址,并跳转到微信的指定界面
然后作者在onshow生命周期内调用了上面提到的getUrlKey()函数来对地址栏的code进行提取
点击查看代码
//作者使用的是uniapp的VUE3版本 VUE2版本可自行调整
let WXcode = ref('')
onShow(()=>{
WXcode.value=getUrlKey("code");//获取url参数code
if(WXcode.value!==null){
console.log('拿到了code为',WXcode.value);
getOpenIdWXh5Api(WXcode.value).then(res=>{//此函数为上传code至后端获取openid
console.log('openid:')
console.log(res.data.data.result.openid);
if(res.data.status==1){
	let openid = res.data.data.result.openid;
	payByWXh5Api({order_sn: props.sn,openid:openid}).then(res=>{//此函数为上传订单编号与openid获取支付的相关参数 props.sn为作者在支付页面的父页面传递过来的订单编号参数
	console.log('订单参数:');
	console.log(res);
	let response = res.data.data.response; 
	//此处调用本文一开始引入的wxjsapi并进行初始化
	wx.config({
		debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 以下参数均为接口返回 直接填入即可接口没有就拷打你的后端
		appId: response.appId, // 必填,公众号的唯一标识 
		timestamp: response.timeStamp, // 必填,生成签名的时间戳
		nonceStr: response.nonceStr, // 必填,生成签名的随机串
		signature: response.paySign, // 必填,签名
		jsApiList: ['chooseWXPay'],
			});
	wx.ready(res=>{
		console.log('js-sdk初始化成功',res);
		wx.chooseWXPay({
		appId: response.appId,
		timestamp: response
		.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
		nonceStr: response.nonceStr, // 支付签名随机串,不长于 32
		package: response.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
		signType: response.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
		paySign: response.paySign, // 支付签名
		success: function(res) {
		console.log('付款成功!', res);
		uni.showToast({
		title: "付款成功!",
		duration: 1000
			})
			window.location.replace('https://xxx.com/x/#/x此处为支付完成后的跳转地址 对地址栏进行直接替换用以清除地址栏上的上一单的code参数,否则会影响onshow时获取code,使之第二次及之后获取的code都为第一次支付时的code,用此重复code去请求openid会报40029 即code无效 以下还有两处为取消支付,支付失败后的跳转地址,同样需要对地址进行整体替换')
				},
		cancel: function(res) {
		console.log('付款取消!', res);
		uni.showToast({
		title: "付款取消!",
		icon:'error',
		duration: 1000
			})
		window.location.replace('https://xxx.com/x/#/x')
		},
		fail: function(res) {
			console.log('付款失败!', res);
			uni.showToast({
			title: "付款失败!",
			icon:'error', 
			duration: 1000
		})
		window.location.replace('https://xxx.com/x/#/x')
		}
		});
	});
		wx.error(err=>{
			console.log('js-sdk初始化失败',err);
			});
		});
		}
	});
	} else {
			console.log('第一次进,没拿到');
		}
})

再之后 给你触发支付的函数调用前文提到的getCodeApi()函数

点击查看代码
payFun(){
	//此payfun为你的支付函数 由于作者的支付函数过于复杂 此处不便展示
	getCodeApi('123')//
	
}
怕你忘了 这个getCodeApi函数为拼接微信提供的地址 这个‘123’参数无实意 只是微信的拼接要求 也可以换成其他的 跳到指定界面后微信会给你的地址栏加上code参数之后会自动跳转回来 所以作者在onshow里写了判断地址栏是否含有code参数 有则直接调起支付流程 并在支付完成或失败后手动的对地址栏进行了覆盖以解决首次触发支付后再次触发时获取的code值为旧值 使用微信开发助手进行调试时此错误更加明显 可以观察上方的地址栏上在触发一次支付后地址栏会一直存在code参数