对于付费类项目,必不可少的一步便是接入各种支付,目前国内比较流行的三方支付主要集中在支付宝,微信支付,京东支付等。这几家主流支付,各有各的要求,各有各的bug需要处理。因此在这里将会针对每种支付的支付流程,支付配置,支付异常处理,支付关键点等做一个统一的总结。
支付宝支付
支付流程
支付宝支付算是所有三方支付里最为简单的,不需要前端进行任何配置,它的支付流程如下:
-
前端将用户选择的商品以及数量提交服务端进行下单操作(此步操作仅由自己项目的服务端操作)
-
拿到服务端产生的orderId后,用orderId和returnUrl(支付回调路径)提交,服务端提交支付宝后台进行订单的创建,并返回支付代码
-
前端根据支付代码,拉起支付支付(优先调用客户端,调不起来的时候采用支付宝网页支付)
-
支付操作后,前端在回调页面进行查单操作
支付关键点
- 支付宝支付分为签约自动续费支付和非签约续费支付,两种支付返回给前端调起支付宝的方式不同。
-
自动续费的支付是返回前端一个拼接好url,前端直接页面重定向即可。
-
非自动续费的支付是返回前端一段form表单的html,前端将其append到页面上,并进行submit提交即可。
let ALIForm = document.createElement('div') ALIForm.innerHTML = result document.body.appendChild(ALIForm) document.forms[0].submit()
-
returnUrl是回调地址,无论成功失败都是回到这里,所以我们必须进行一次查单操作,确认是否支付完成。
-
支付成功后,支付宝是异步回调服务端,因此每次查单操作,应当前端调用服务端后,服务端到支付宝后台进行查单,不能简单的以支付宝的回调为准。
微信支付
微信分为微信支付(从微信外部拉起微信支付)和微信公众号支付(在微信内通过微信支付)
支付流程
微信支付的支付流程与支付宝签约续费支付相似,服务端下单,服务端提交微信产生订单并返回前端代码,前端拉起微信支付。
微信公众号支付相对麻烦一下,它的流程如下:
- 首先需要拉起公众号授权,拿到用户的openid,微信会校验openId和要支付的公众号的appId是否一致
- 前端提交商品信息进行下单(项目服务端生成订单orderId)
- 前端提交orderId与openId,服务端将订单信息和openId提交微信后台生成订单的prepay_id,并将所有参数返回,参数包括(公众号appId、时间戳timeStamp、随机串nonceStr、package(格式为prepay_id=123456789的字符串)、signType签名类型)以及利用签名五个参数进行的签名
- 前端利用微信提供的api,拉起公众号支付
if (typeof WeixinJSBridge == "undefined") { if (document.addEventListener) { document.addEventListener('WeixinJSBridgeReady', this.onBridgeReady, false) } else if (document.attachEvent) { document.attachEvent('WeixinJSBridgeReady', this.onBridgeReady) document.attachEvent('onWeixinJSBridgeReady', this.onBridgeReady) } } else { onBridgeReady(response) //response为服务端返回的各个参数 } function onBridgeReady(res) { //拉起微信支付 const self = this WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId": res.appId, "timeStamp": res.timeStamp, "nonceStr": res.nonceStr, "package": res.package, "signType": res.signType, "paySign": res.paySign }, function (res) { if (res.err_msg == "get_brand_wcpay_request:ok") { // 使用以上方式判断前端返回,微信团队郑重提示: //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 } else if (res.err_msg == "get_brand_wcpay_request:fail") { } else if (res.err_msg == "get_brand_wcpay_request:cancel") { } }) }
- 支付结束后,进入相应回调
支付配置
微信支付,需要将拉起支付的页面域名和回调域名都配置到后台H5支付目录
公众号支付,需要配置授权登录回调域名,支付目录(即要拉起公众号支付的前端页面url)信息
支付异常处理
微信支付
问题 | 解决 |
网络环境未能通过安全验证,请稍后再试 | 在支付过程中切换了网络或者是直接将微信返回的拉起支付url粘到一个浏览器尝试打开 |
商家参数格式有误,请联系商家解决 | 多数情况为H5支付授权域名未配置正确 |
请在微信外打开订单,进行支付 | 微信内部不允许自己拉起自己支付,只能通过公众号支付 |
公众号支付
问题 | 解决 |
redirect_url域名与后台配置不一致 | 授权回调域名未配置 |
当前页面的URL未注册 | 当前页面未配置到支付目录里 |
支付关键点
- 微信支付,务必配置H5支付目录
-
微信公众号支付提交的openId必须是商户公众号授权后获取的,不同公众号拿到的openId不一样,微信会校验
-
签名校验一定要让服务端做,前端没有那么强的加密能力,且appId会暴露。微信有相关的校验签名的接口可以调试。
-
授权回调目录和支付目录必须配置,跟H5支付目录不是一回事。
京东支付
分为京东支付和京东白条,白条包含了分期功能
支付流程
用户选择白条还是普通支付,如果选择白条支付的话,需要到京东后台拉取该商品允许的分期数以及手续费等信息
支付关键点
-
京东支付是前端调用京东接口,且京东接口只能通过form表单提交的方式调用
function JDpay(infos){ var dlform = document.createElement('form') dlform.style = "display:none;" dlform.method = 'post' dlform.action = 'https://h5pay.jd.com/jdpay/saveOrder'; dlform.target = '_parent' for (let key in infos) { var hdnFilePath = document.createElement('input') hdnFilePath.type = 'hidden' hdnFilePath.name = key hdnFilePath.value = infos[key] dlform.appendChild(hdnFilePath) } document.body.appendChild(dlform) dlform.submit() }
-
京东白条和京东分期分别对应两个参数,baitiao_one和baitiao_fen,需要服务端做下判断,传不同参数
-
京东白条分期需要金额大于10RMB