我所在公司须要开发一款商城小程序,里面须要用到微信支付,我负责里面的下单功能,从小程序端到后台的支付流程都是我本身开发的,因为咱们组没有人有开发微信支付的经验,不少东西都还不怎么明白,可是没办法,只能我本身琢磨,写完以后总感受有bug,可是不知道该怎么改才合适,前先后后踩了很多的坑,本身有时间也研究了一下,改动了好几回以后,我以为目前的版本是最顺畅,安全性也是最高的,我把目前的作法流程记录一下,供他人参考。php
- 首先要拿到收款的微信商户号和支付秘钥
- 确保拿到用户的openid,获取用户的openid的流程大体是,在微信端使用wx.login获取到code,将code传到服务器换取openid,具体的流程可去官方文档查看获取openid
- 建立一个代付款的订单,获得该订单的单号
- 在服务端调用微信支付的统一下单接口微信支付统一下单,( 调用预下单接口的时候,要传入一个正确的通知地址,字段名称是notify_url,这个地址是咱们本身写的接口地址,用于接收微信支付结果通知,而后更新订单状态 ),进行预下单以后,获得一个prepay_id
- 用获得的prepay_id在js里调用发起支付微信小程序支付
- 支付结果,微信会经过服务端通知到统一下单的时候的通知地址,当收到微信支付结果通知以后,须要对接收到的信息进行签名验证,确保验证经过了,才更新订单的状态。
踩坑集合:html
- 最开始的版本是直接在小程序微信支付的js的success回调里,接收到了支付成功以后,再在js里调用修改订单状态的接口,这样作其实很不安全,由于别人一旦拿到小程序的源码,就能够直接跳过微信支付,直接调用修改订单付款状态的接口了,并且,若是客户在微信支付完成以后,没有点完成按钮,也不会进入js的success回调里面,因此须要经过服务端的通知接口,接收到支付结果通知以后,再在服务端修改订单付款状态,这样就没有问题了。
- 屡次通知付款结果的问题。付款结果通知,微信会发起屡次,一开始的时候,我发现同一个订单会有多条同样的付款日志,没找到问题,后面看了微信支付的官方文档以后,才知道,为了保证能接收到支付的结果,同一条订单的支付结果会通知屡次,须要开发者本身进行处理。
- 支付结果通知的安全性问题。由于支付结果通知接收的地址是对外开放的,因此一旦地址泄露出去,有可能会被有心人调用,按照必定的参数格式调用,就能修改订单的付款状态,形成假的支付通知。因此在收到支付结果通知的时候,须要对接收到的数据按照签名的规则进行签名校验,校验经过了,才更新订单的付款状态。签名须要用到支付秘钥,只要秘钥没有泄露,就不会有安全性问题。
- 微信支付的秘钥不要读到前端。由于咱们的接口分了好多地方读取,因此在进行微信统一下单的时候,有把支付秘钥在小程序的js页面里读出来,再在js里调统一下单的接口,从安全性的角度上来看,这样不够安全,支付秘钥的读取和传输应该只在后端操做,不该该读到前端,固然读到前端也没有问题,可是能够改的话最好改一下。
附:微信JSAPI支付流程
微信JSAPI支付流程和小程序的支付流程基本一致,须要注意两点:前端
- 须要在微信商户平台配置支付目录,只有跳转到了支付目录的地址,才能发起微信支付。
- 网页须要获取openid须要进行一次页面跳转,须要用户对网页受权以后,才能获取到code,获取到code以后,再使用code获取到openid,再进行统一下单预支付,其余流程就和小程序一致。由于在网页里要获取到openid必需要进行一次页面跳转才能获取到openid,因此我建议能够在订单确认页面,确认好信息以后,先下好待付款的订单,获得订单号以后再跳转,跳转到支付页面的时候,进行获取openid的操做,再进行下面的操做便可。
获取openid参考微信网页受权小程序