由于公司内开发的h5网页需要开始对接多种支付方式(微信支付、h5支付、线下转账、银联转账业务),后续可能还要对接更多方式,目前先总结下微信H5支付方式,由于微信小程序的方式很简单,看文档即可,微信H5支付分为两种情况,1.微信内H5支付 2. 普通浏览器H5微信支付。以前做了支付,但是久都没有做微信支付了,这次就算是记录一下之前的技术债。
1.微信内H5支付业务流程
提示:在开发之前最好是配置好对应的授权域名、防止在调试的时候报错
(1).跳转到指定的微信URL获取微信code
window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect`;
上述跳转链接参数解释
| 参数名 | 释义 |
|---|---|
| appid | 公众号ID |
| redirect_uri | 重定向URL,跳转当前URL后,微信会自动跳转你指定的URL地址,并且在地址后面拼接微信code |
| response_type | 相应类型,即跳转当前URL地址是为了获取code信息 |
| scope | 当前值有两种,1.snsapi_userinfo:静默授权,一般微信支付选择静默授权,且用户无感知 2.snsapi_userinfo:需要用户手动点击同意(会有提示框) |
| state | 固定值:123#wechat_redirect |
(2).通过code获取当前用户的openId,前端可调用后端写的接口获取当前用户的openId
提示:由于一个手机号在同一个微信公众号里面的openId是固定的,所以此处在获取到openId,可以将当前用户的openId缓存下来,
后面在做支付的时候,直接走openId后面的流程、无须在重新获取openId,可以减少当前用户跳转的步骤,更快的进入支付,
提示需要在当前token失效的时候清除openId,防止当前用户openId错乱
(3).根据openId获取当前微信公众号的配置信息,主要有以下几个参数timeStamp、nonceStr、package、signType、paySign、appId(一般都会返回回来)
(4).拿到上述信息之后,开始最后一步发起微信支付
WeixinJSBridge.invoke('getBrandWCPayRequest', {
appId: '',
timeStamp: '',
nonceStr: '',
package: '',
signType: '',
paySign: ''
}, function(res) {
if (res.err_msg == 'get_brand_wcpay_request:ok') {
// 支付成功
}
//但是由于上述的判断微信官方文档提示了,并不完全可靠,所以我们通常的做法是跳转到一个新的过渡页面,
//在过渡页面去轮询当前订单是否已经支付完成,最后跳转到对应的支付成功或者是支付失败的页面
})
2.普通浏览器H5支付业务流程
提示:在开发之前最好是配置好对应的授权域名、防止在调试的时候报错
(1).引入微信SDK
1.普通html,可以引入 <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
2.npm 包模块。引入 weixin-js-sdk 包
(2).给当前应用进行微信授权,因为授权涉及到接口需要损耗时间,所以会在进入当前页面或者是更早之前进行用户授权,防止授权微信支付因为未授权导致微信支付失败
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [
'updateAppMessageShareData',
'updateTimelineShareData',
'onMenuShareWeibo',
'onMenuShareQZone',
'startRecord',
'stopRecord',
'onVoiceRecordEnd',
'playVoice',
'pauseVoice',
'stopVoice',
'onVoicePlayEnd',
'uploadVoice',
'downloadVoice',
'chooseImage',
'previewImage',
'uploadImage',
'downloadImage',
'translateVoice',
'getNetworkType',
'openLocation',
'getLocation',
'hideOptionMenu',
'showOptionMenu',
'hideMenuItems',
'showMenuItems',
'hideAllNonBaseMenuItem',
'showAllNonBaseMenuItem',
'closeWindow',
'scanQRCode',
'chooseWXPay',
'openProductSpecificView',
'addCard',
'chooseCard',
] // 必填,需要使用的JS接口列表
},
wx.error(function(res){
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
);
(3).调用后端接口进行微信支付,后台接口会返回一个mwebUrl 或者是其他参数名的URl,然后在当前页面重定向到URL,
const currentUrl = encodeURIComponent('需要跳转的URL地址')
window.location.href = `${mwebUrl}` + '&redirect_url=' + currentUrl
3.h5接入支付宝支付
1.直接调用后台的支付接口
const params = {}
alipay(params).then(res => {
const { data } = res
if (!data.alipay_trade_wap_pay_response) {
document.querySelector('body').innerHtml = res.data;
document.forms[0].submit()
} else {
console.log('支付宝支付失败');
Toast(data.alipay_trade_wap_pay_response.msg)
}
})
4.h5接入云闪付支付业务流程
// nginx 需要增加如下配置信息
location /order {
proxy pass http://xxx:8000/order; proxy method GET;
proxy redirect default;
proxy set header X-Real-IP $remote addr;
proxy set header X-Scheme $scheme;
proxy set header X-Forwarded-For $proxy add x forwarded for;
proxy set header Host $proxy host;
default type text/html;
}
(1).隐藏表单信息(表单的信息可能略微有差异,总是使用方式是一样的)
{/*银联支付隐藏Form表单内容*/}
<form id="unionpayForm" method="post">
<input type="hidden" id="BusiType" name="BusiType" value="" />
<input
type="hidden"
id="CommodityMsg"
name="CommodityMsg"
value=""
/>
<input type="hidden" id="CurryNo" name="CurryNo" value="" />
<input type="hidden" id="MerBgUrl" name="MerBgUrl" value="" />
<input type="hidden" id="MerId" name="MerId" value="" />
<input
type="hidden"
id="MerOrderNo"
name="MerOrderNo"
value=""
/>
<input type="hidden" id="OrderAmt" name="OrderAmt" value="" />
<input type="hidden" id="RemoteAddr" name="RemoteAddr" value="" />
<input type="hidden" id="Signature" name="Signature" value="" />
<input type="hidden" id="TranDate" name="TranDate" value="" />
<input type="hidden" id="TranTime" name="TranTime" value="" />
<input type="hidden" id="TranType" name="TranType" value="" />
<input type="hidden" id="Version" name="Version" value="" />
<input type="hidden" id="PayTimeOut" name="PayTimeOut" value="" />
<input type="hidden" id="MerPageUrl" name="MerPageUrl" value="" />
</form>
{/*银联支付隐藏Form表单内容*/}
(2).调用后台接口获取信息并且填写到表单里面进行提交
unionPay(params).then(res => {
console.log('res', res)
if (res?.code !== 0) {
Toast.fail('发起云闪付失败,请重试!')
return
}
const data = res.data;
const payForm = JSON.parse(data.payForm);
const form = document.getElementById('unionpayForm');
_this.changeInputValue('BusiType', payForm.BusiType);
_this.changeInputValue('CommodityMsg', payForm.CommodityMsg);
_this.changeInputValue('MerBgUrl', payForm.MerBgUrl);
_this.changeInputValue('CurryNo', payForm.CurryNo);
_this.changeInputValue('MerId', payForm.MerId);
_this.changeInputValue('MerOrderNo', payForm.MerOrderNo);
_this.changeInputValue('OrderAmt', payForm.OrderAmt);
_this.changeInputValue('RemoteAddr', payForm.RemoteAddr);
_this.changeInputValue('Signature', payForm.Signature);
_this.changeInputValue('TranDate', payForm.TranDate);
_this.changeInputValue('TranTime', payForm.TranTime);
_this.changeInputValue('TranType', payForm.TranType);
_this.changeInputValue('Version', payForm.Version);
_this.changeInputValue('PayTimeOut', payForm.PayTimeOut);
_this.changeInputValue('MerPageUrl', payForm.MerPageUrl);
form.action = payForm.url;
console.log('url', payForm.url);
// form.target = '_blank';
form.submit();
})
function changeInputValue (name, value) {
let tep = document.getElementyId(name)
tmp.value = value
}
总结: 以上就是我最近做的接入第三方支付的所有内容了,实际上还有一个线下转账,但是这个就是上传图片,然后后台人工审核转账信息,比较简单,所以没有写,希望以后能记录下自己所有想要记录的重要的知识点。
如果我的文章对你有用,请你点个赞,哈哈哈哈哈
努力总会有回报的,加油