微信支付开发实记
微信支付分为JSAPI支付,扫码支付,APP支付,小程序支付等不同的支付方式。但大体的支付过程是一致的,本文以JSAPI支付,也就是微信内的H5支付为例,描述一下支付的整个开发流程。
配置
商户需要提前开通商户平台,并去公众平台或开放平台提交微信支付申请,获得商户号和秘钥。
支付流程
微信支付的流程图画的很完整,开发前要把整个流程研究清楚。
整个流程,服务端需要做的有三件事。
- 前端支付按钮被触发后,服务端要去调用 统一下单 接口,把预付单信息、支付参数和参数签名返回给前端。前端根据这些参数唤起支付。
- 当用户支付成功后,微信会给我们一个回调通知,告知我们支付结果。这一步要实现“完成订单”操作,标记用户已经成功支付,进入“发货”流程。
- 提供一个查询接口,让前端再次确认是否支付成功。
统一下单
在支付前,商户系统先调用该接口在微信支付后台生成预支付交易单,同样的,商户系统也需要在自己的表里记录一笔“未完成订单”。生成之后返回正确的预付单信息、支付参数和参数签名返回给前端。前端根据这些参数唤起支付。
接口
https://api.mch.weixin.qq.com/pay/unifiedorder
这里需要说明的一点是,我们在调用这个接口时,需要签一次名用来给微信做校验,微信也返回了一个新的签名用来给我们做校验,然后我们还要返回给前端一个签名,用来唤起支付。这三个签名都不是同一个。
我们不能直接把调用统一下单接口返回的签名返回给前端,而是根据前端唤起支付的参数去重新签名。
注意,是根据前端唤起支付的参数去重新签名,因为前端的参数名和后端的参数名会略微有差别,这里需要小心。
说明:签名的意图是用来校验身份,当前端把这些参数传给微信,微信会把调用参数除去签名后重新签名,用来校验签名的正确性,所以用来签名的参数名要和前端参数一致。
支付结果通知
在统一下单时我们填了一个参数叫 notify_url
,这是一个服务端的接口地址,微信在用户支付成功后,会回调这个地址,告知我们支付结果。
在这一步还是需要做多点校验的,免得被人有机可乘。
- 校验支付是否成功,不成功直接返回"FAIL"
- 校验签名和appid
- 校验订单是否完成(幂等校验,防止微信多次回调导致多次订单写入)
- 订单金额校验
一通校验完事之后就可以做业务相关的事了。记得所有操作结束后返回"SUCCESS",不然微信会不断发起回调。
总结
- 流程图描述的很清楚,要仔细阅读流程图。
- 调用完下单接口后要进行二次签名,签名的参数要看前端验签用哪些参数,即使是同一个参数,字段名也会跟第一次加签不一样。
- 前端支付完成之后微信会有一个回调,我们需要做以下几点校验:
- 做幂等处理(因为同样的通知微信可能发送多次)。
- 校验签名,校验APPID。
- 校验订单金额。
- 订单状态分为 0-未支付 1-支付完成 2-支付失败:
- 用户触发支付组件然后关闭或者杀掉进程微信不会给到后台任何回复,始终处于 0-未支付,所以这个状态也是一个支付失败状态。
- 支付失败比较少见(到现在没有遇到过),比如签名错误(发生在调试阶段)。
- 微信回执表尽量详细的记录微信传回的所有必有参数,以备出问题时排查。
- 至今还没有找到微信本地调试的方法。