微信支付的那些事儿

前言

最近公司产品在做微信支付接入,有幸接触到微信支付开发这一块儿的任务,在整个支付接入过程中积累了一些经验(日常爬坑),就此和小伙伴们分享一下!(主要是前端)

流程

业务流程:
微信在支付页面输入金额,点击支付按钮,后台处理处理数据并获取到预支付ID(prepay_id),返回到前端的页面上。页面上通过js_sdk唤起微信支付的页面,弹出输入密码页面,用户输入密码后,由微信展示支付成功页面(微信自己实现),跳转到我们自己定义的页面,展示支付结果。

开发流程:

  1. 获取用户授权
    在生成预支付id的过程中需要获取用户授权,并且拿到用户的openid。可以直接参考官方文档:
    https://open.weixin.qq.com/cgibin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN

  2. 引入JSSDK
    在需要调用微信支付功能的页面引入的jssdk,直接放在HTML的head里面。

  3. H5唤起微信支付功能

  4. 使用微信jssdk中的wx.config配置方法注册支付功能

wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: json.appid._cdata, // 必填,公众号的唯一标识
timestamp: timestamp, // 必填,生成签名的时间戳
nonceStr: json.nonce_str._cdata, // 必填,生成签名的随机串
signature: Sign(arr1, 'SHA1'),// 必填,调用js签名,
jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表,这里只写支付的
});

  1. 在使用wx.choosePay唤起支付

wx.chooseWXPay({
timestamp: timestamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: json.nonce_str._cdata, // 支付签名随机串,不长于 32 位
package: "prepay_id=" + json.prepay_id._cdata, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
signType: "MD5", // 签名方式,默认为´SHA1´,使用新版支付需传入´MD5´
paySign: Sign(arr2, 'MD5'), // 支付签名
success: function (res) {
},
cancel: function (res) {
//alert(´取消支付´);
}
});

3.支付成功后,处理回调URL

官方解释:
支付完成后,微信会把相关支付和用户信息发送到商户设定的通知URL,验证签名,并回应微信。对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略(如30分钟共8次)定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。

主要是3步:

  1. 解析传过来的流信息,通过重新签名的方式验证流中包含的信息的正确性。就是判断这个信息到底是不是微信发的。
  2. return_code和result_code都是SUCCESS的话,处理商户自己的业务逻辑。就是订单的支付状态啊等一些信息。
  3. 告诉微信,我收到你的返回值了。不用在发了。

注意事项

  1. 获取预支付id的时候如果前后端是分离的,那么一定要都统一使用MD5签名,因为在生成预支付ID的时候可以使用MD5或者HMACSHA256,但是但是但是,新版支付中,在前端唤起支付的时候的签名只能使用MD5签名,当后台使用HMACSHA256的时候就会提示验签出错,如果你和后台人员没有事先商量过,那你很可能调试很久都不会发现这个问题。

  2. 因为微信获取授权,拿到(openid),是通过URL重定向拿到的,所以当你重定向到当前页面会造成页面的不断刷新,这个时候你需要判断用户是否是第一次进入这个页面,如果是重定向到当前页面,就不要再跳转了。我们使用的方法是利用cookie来做判断。

if(document.cookie.indexOf("a=one")==-1){
let t=new Date(new Date().getTime()+1000*5);
document.cookie="a=one; expires="+t.toUTCString();
window.location.href='//获取用户授权,拿到openid的链接'
}else{
let t=new Date(new Date().getTime()+1000);
document.cookie="a=two; expires="+t.toUTCString();
}

  1. 关于签名,利用jssdk唤起微信支付功能需要有两次签名,算上后端获取预支付ID的过程中也有一次签名,这就是3次签名。第一次签名是在wx.config中的signature,此处使用的是SHA1签名,生成预支付ID的sign和唤起支付功能的paySign使用的是MD5签名。在wx.choosePay中的签名的参数也有值得注意的一些地方,主要是参数的大小写。

signature中参与签名的字段
const arr1 = [
'noncestr='+ json.nonce_str._cdata,
'jsapi_ticket='+ json.wx_jsapi_ticket._cdata,
'timestamp='+ timestamp,
'url=授权目录 '
]

paySign中参数签名的字段
const arr2 = [
'nonceStr='+json.nonce_str._cdata,
'package=prepay_id='+json.prepay_id._cdata,
'signType=MD5',
'appId='+json.appid._cdata,
'timeStamp='+timestamp
]

结语

微信支付的接入过程中,最具参考价值的就是官方文档,一定要先对文档的内容有一个清晰的了解(就因为微信的文档会让人非常的抓毛,才会需要更加仔细的了解),还有在前后端一起开发的过程中,一定要多沟通,就如同上面的签名方式一样,如果没有事先商量,唤起支付的时候就很容易失败,然后自己的参数又是完全正确的,简直无从下手!团队开发一定要学会团队合作,这样才能事半功倍,不然只是徒增麻烦!

【海说软件接受各种技术咨询及开发业务】

END

你可能感兴趣的:(微信支付的那些事儿)