PC端:
大致流程为
1、请求创建订单接口传递正确参数(例如openid、金额、开始结束时间等),此接口会返回一个图片,或网络图片,或base64图片,这个图片是一张二维码;
2、前端拿到这个二维码渲染到屏幕上并开始启动定时器,每过一秒请求一次查询支付结果接口,查询是否支付成功;
3、支付宝支付可能会给一个跳转链接,直接跳转进入,其中有一个二维码,扫码可完成支付,支付成功或中断的url地址都是在微信商户平台后台配置的;
4、支付成功清除定时器,跳转结果页;
注:正常而言后端会给查询支付结果接口,如果不给就去看微信的官方文档,并找后端要相应的参数进行查询;
PC微信支付宝支付代码:
// 下单逻辑
async orderAdd(data) {
//请求下单接口
let res = await orderAdd(data);
if (res.status == 200) {
//清空上一次的base64或网络图片地址
this.payCode = '';
//判断当前为支付宝支付还是微信支付
if ('当前是支付宝支付') {
//通过window对象打开外链链接,这里用的是跳转外链完成支付
window.open(res.data.pay_img);
} else {
//如果当前是微信支付
// 每次在开启定时器前,先把上一个定时器关了
clearInterval(this.time);
//渲染图片(当前为base64示例)
this.erweiCode = 'data:image/png;base64,' + res.data.pay_img;
// 每秒轮询一次
this.time = setInterval(() => {
//请求订单查询接口,这块的逻辑就是如果返回数据为‘已支付’就清除定时器,然后跳转结果页面
this.orderQuery(‘你的订单号’);
}, 1000);
}
}
}
移动端
微信支付大致流程为:
在微信浏览器外部支付,后端会给一个链接,这个链接是经过微信特别处理的,用户打开这个链接就会自动拉起手机设备中的微信app,然后进入微信支付;
在微信浏览器内部支付,需要调用微信浏览器底层内置的sdk,可以通过插件简化调用流程,
支付宝支付大致流程为:
支付宝支付一般都是后端返回一个已经填写完毕的表单,前端将这个表单渲染出来并且利用javascript来获取元素对象,表单的元素对象自带一个submit方法。只要用这个方法把表单进行提交给支付宝服务器即可,支付宝会自动拉起手机设备中的支付宝app,完成支付;
因为渲染和提交都是直接进行的,用户的感知就是点击支付按钮直接拉起了支付宝app进行支付,看不到表单;
移动端代码:
微信支付:
1、微信浏览器内支付
首先通过npm下载插件
npm init -y
npm install jweixin-module --save
然后进行全局参数配置、预请求、微信支付请求:
let ua = navigator.userAgent.toLowerCase();
//判断当前是否为微信浏览器
if (ua.match(/MicroMessenger/i) == "micromessenger") {
// 是微信浏览器
// 使用微信支付
let self = this;
jweixin.config({
//全局参数配置
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: res.data.appId, // 必填,公众号的唯一标识
timestamp: res.data.timeStamp, // 必填,生成签名的时间戳
nonceStr: res.data.nonceStr, // 必填,生成签名的随机串
signature: res.data.paySign, // 必填,签名,见附录1
jsApiList: ["chooseWXPay"], // 必填
});
jweixin.ready(function () {
//预请求,看能否发起微信支付
jweixin.checkJsApi({
//判断当前版本是否支持指定js接口
jsApiList: ["chooseWXPay"], // 需要检测的JS接口列表
success: function (res) {
console.log("成功信息1");
console.log(res);
},
fail: function (res) {
console.log("失败信息1");
console.log(res);
},
});
jweixin.chooseWXPay({
//发起一个微信的支付请求
timestamp: res.data.timeStamp, // 支付签名时间戳
nonceStr: res.data.nonceStr, // 支付签名随机串,不长于 32 位
package: res.data.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
signType: res.data.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: res.data.paySign, // 支付签名,与签名是一个东西
success: async function (res) {
console.log(res, "成功信息2");
},
cancel: function (res) {
console.log(res, "取消信息2");
},
fail: function (res) {
console.log(res, "失败信息2");
},
});
});
jweixin.error(function (res) {
console.log(res, "失败信息3");
});
}
这一块可以参考这位的博客,说的也很详细:
uniapp h5的支付宝,微信支付_uniapp支付宝h5支付_F_cy的博客-CSDN博客
结果:
在上面代码执行正常以后,会调起微信支付的弹框,要求用户输入密码以完成支付,在支付完成后会自动返回原页面;
无法调起微信支付问题排查:
1、参数传递错误,一般而言后端给什么参数,前端直接把后端给的参数传递过去即可,除非是package参数, 统一支付接口返回的prepay_id参数值,提交格式需要为:prepay_id=***;
2、将jweixin.config的debug改为true,排查弹框看是什么弹框出错;
3、微信商户平台配置支付完成或中断支付的url错误;
4、如果前面几项都排除,参数没有漏传或错传,那就是后端的签名等返回字段本身的错误,导致无法拉起微信支付;
2、微信浏览器外支付(H5支付):
//不是微信浏览器,使用微信的h5支付,直接使用document.location.href跳转后端返回的链接即可
document.location.href = res.data.mweb_url;
如果需要跳转结果页面进行查询当前是否支付成功:
//如果需要跳转指定页面,将url给encode化,然后拼接跳转
function urlencode (str) {
str = (str + '').toString();
return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').
replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
}
//跳转过后在这个页面使用定时器查询当前是否支付成功,给出对应业务逻辑即可
document.location.href = res.data.mweb_url+`?redirect_url=${urlencode('带http或https的完整路径结果页')
}
支付宝支付:
由于uniapp的特性,我们无法直接获取页面上的表单元素,但是后期手动添加渲染的可以,因此,可以完成以下代码
// 支付宝支付,这里只要提交表单
// 创建一个新的div元素
const div = document.createElement('div');
// 渲染这个div中的表单(res.data.pay_img就是后端返回的表单)
div.innerHTML = res.data.pay_img;
// 进行元素追加渲染
document.body.appendChild(div);
// 提交表单(alipaysubmit这个名字是和表单上的name一致的,要注意别搞错了)
document.forms['alipaysubmit'].submit();
其实用document.body.innerHTML=‘表单’,然后进行提交也行,但是这样的话,如果在H5中,用户点击返回,原本的支付页面会变成白屏(因为已经被整体重写了,而表单数据已经被提交),所以最好使用创建,渲染,追加,提交这样的方式;
结果:
在上面代码执行正常以后,会调起支付宝app,进入支付流程(就和你平时付款一样的);
关于在微信浏览器进行支付宝支付:
在微信浏览器中提交表单不会拉起支付宝,但是会有支付宝的第三方自带页面引导用户打开外部浏览器,由于参数已经发到支付宝服务器,用户打开外部浏览器后一样会拉起支付宝,无需重复登录和点击支付,同样可以直接完成支付操作,前端不需要在意当前是否为微信浏览器,只需要直接提交表单即可;
关于支付宝支付完成后的逻辑:
支付宝支付在商户平台后台可以配置当前支付完成或支付中断返回不同的url页面,也就是说,如果支付完成,在后台配置的url地址就为支付成功结果页,支付失败或中断,后台配置的地址就填入购买商品的待支付页即可
注意:
1、支付逻辑,创建订单接口一定要加防抖节流,否则后端可能会出现异常,或后期容易出现意外的BUG;
2、关于创建订单的开始与结束时间:
①、规范语法,创建订单接口传递参数时,如果是需要前端转化时间戳,那么时间格式应该是2023/05/03进行转化,而非2023-05-03或2023 05 03这些格式,因为js创建时间对象的方法new Date(),在android上使用不标准语法依旧可以正常创建,而在ios上,会报错,因此,建议在创建时间对象时,就把日期直接转化为标准格式即“xxxx/xx/xx”;
②、注意js转化时间戳的特性为毫秒(getTime方法),这个点要注意,需要询问后端到底是需要什么格式的时间戳,是秒还是毫秒,如果是以秒转化的时间戳,前端就需要除以1000
时间戳转化,加上语法规范的代码为:
new Date(初始时间(年-月-日).replace(/-/g,'/')).getTime() / 1000;//规范语法,以秒为单位
3、微信支付必需参数之一是openid,在网页上通过网页授权的方式获取,具体可以参考我的这篇博客:
uniapp h5的支付宝,微信支付_uniapp支付宝h5支付_F_cy的博客-CSDN博客
附录
参考文档博客:
uniapp h5的支付宝,微信支付_uniapp支付宝h5支付_F_cy的博客-CSDN博客