最近做支付,我的坑啊,我就想说一句话:你不做微信支付,就不知道自己的才疏智浅!人家就说,文档在这,自己看,自己做,哪块不清楚,哪块有问题,自己搞;我也总算是出来了!!!记在这里希望对您有所帮助
总述
在做微信支付的时候,如果你没有使用官方给的SDK,那进坑的几率还是比较小,有坑也是自己种的,上几次做的时候就是自己做签名,自己发送请求,沙箱种没有出问题;这次有点懒,索性用了官方给的SDK,的确,如果这些坑你都知道,那么接入的速度很快,但是如果是盲目的,那么恭喜你,大部分情况下都会被微信支付装进去的。我建议大家在做微信支付的时候先去调通正式的环境,再去调试沙箱环境。总的支付逻辑我在思否上有提问,在这里也详细说明一下;
网上对微信支付感觉不太友好,难道微信支付就没有他的优点吗?至少我就发现了这点,支付宝支付的时候,各种场景需要我们自己去创造,而且不一定百分百的重现,有没有这种感觉?别说没有,如果没有说明你没有做过支付,但是微信的沙盒就提供了各种常见的场景,只要输入场景对应的的金额,那么该场景就会出现,避免我们去创造那些在平常很难把控的场景,这点上我给微信一个大大的赞!
业务处理逻辑以及解释
现在我把刷卡支付
整个支付逻辑梳理一下:
- 项目启动,客户端发起创建订单请求,服务器响应创建订单;
- 客户端发起支付请求,服务端开始处理支付请求;
- 服务端拼装支付参数:
- 如果是沙箱环境,那么参数sign的生成需要沙箱的API密钥,获取沙箱密钥:请求
https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey
获取沙箱的API密钥,这个密钥就是用来在沙箱环境下替换商户中设置的API密钥,这一点在官方文档中并没有明确的说明。 - 如果是正式环境,那么直接使用在商户平台上(账户中心→API安全→设置密钥)设置的API密钥即可。
- 如果是沙箱环境,那么参数sign的生成需要沙箱的API密钥,获取沙箱密钥:请求
- 使用获取到API密钥和前面的参数生成签名,具体的生成签名的规则可以在官网文档看到,可以在这个官网文档验证你的签名的正确性;
- 说明:有的盆友不知道为什么要这样,为什么请求这个什么沙箱密钥。曾经也被问道,所以研究了这个支付系统之后给出了我的理解。如下图所示,微信的支付系统是由一个Nginx服务器对我们的请求地址进行路由,进而把所有的沙箱请求全部路由到仿真测试系统中,实现了测试系统和线上的生产环境系统的分离。然而就是这个分离,就是我们需要请求一个沙箱API密钥的根源。由签名的算法可以看出来,这个API密钥的本质其实就是我们经常说的
加密中的加盐
中的盐
,当然了MD5也好,SHA256也好都是散列算法,不是真正意义上的加密。这个盐是在商户平台上设置的,那么在沙箱系统中为了良好的保密性,不需要使用线上的真正的API密钥,从而换成了另一套API密钥,即这两个系统是两套独立的系统,不同的是,这套沙箱的API密钥①需要发送请求沙箱得到,而不是自己设置的;②需要使用线上的API密钥换取这个沙箱API密钥(获取沙箱API密钥需要线上API密钥对请求参数做签名处理)
微信支付仿真测试系统
- 服务端拼装支付参数:
- 开始支付请求,
坑的位置
,如果你把沙箱支付和正式支付做到一块,那么这块就绝对是一个坑,如果想跳过这个坑,直接调用wxPay的requestWithoutCert,根据沙箱和正式传入不同的请求地址即可。- 这里又得絮叨几句了,我在这里栽了个大跟头。因为之前是这么做的,自己填充参数,什么app_id, mch_id, total_fee等等最后根据环境生成签名sign,添加到参数Map中(可查看思否中的代码),最后调用SDK的支付
wxPay.microPay(reqData)
,这个时候报错: 沙箱验证签名失败,请确认沙箱签名key是否正确(通过getsignkey调用生成),我真的是纳了闷了,签名我验证了十多次,每次在页面生成的sign和代码生成的sign都一致,也就是说签名是没问题的,然而却偏偏给我报错:签名失败。搞了我好长时间,最后忍不住去看了SDK的源码,千哪,里面直接使用API密钥再来一次加密,在生成一个sign,最终生成一个二次加密结果的sign,这能成功吗??成功就怪了!!!其实只要自己调用requestWithoutCser方法那么久可以解决这个问题。翻遍SDK的用法,没有说明用法,而是让用户自己猜怎么用,这个SDK的漏洞真的是好让人尴尬。当然了,正确的使用方法就是仍然使用官方SDK的前提下,自定义配置接口(com.github.wxpay.sdk.WXPayConfig),按照沙盒/线上环境返回对应的API密钥即可。
- 这里又得絮叨几句了,我在这里栽了个大跟头。因为之前是这么做的,自己填充参数,什么app_id, mch_id, total_fee等等最后根据环境生成签名sign,添加到参数Map中(可查看思否中的代码),最后调用SDK的支付
- 其他地方就没有什么坑了,但是也是有一些注意点的,我记录了下面几个,后面如果有就继续更新吧。
- INVALID_CHARACTER_ERR: An invalid or illegal XML character is specified. 这个错误呢,就是说你的参数key中有空格,去掉就OK了!
- {return_code=FAIL, retmsg=请确认请求参数是否正确total_fee, retcode=1},这个错误没有记录,忘记了应该还是参数的问题
- 沙箱被扫支付金额(x)无效,请检查需要验证的case。在微信的沙盒中只能输入几个固定的订单金额,而且每个订单金额的背后是一个场景。
- java.net.SocketException: Connection reset或者java.net.SocketException: Unexpected end of file from server,证书没有正确的加载
在做支付的时候,需要回调支付结果,可公司内网。。。所以必须做内网穿透,我就使用完全免费的natapp的方式实现,暂时就记在这里吧
官方网站:https://natapp.cn
教程:https://natapp.cn/article/natapp_newbie
网友评论