记一次微信支付爬坑
微信支付-那些年填过的坑
由于最近项目需要用到微信支付,所以需要研究微信支付相关内容,微信支付本身不是什么问题,只是过程比较繁琐,前提工作需要准备充足方可开工,不然你会一个坑接着一坑的掉。
由于业务需要,需要pc端扫码支付(扫码支付)、微信公众号端支付(公众号支付)、app支付三种场景的支付,扫码支付和公众号支付都是可以支付到不同商户,而app由于appid的限制无法支付到不同商户(这里的appid和商户appid不是同一个概念)所以转而研究h5支付,现在将这三种支付模式以及在支付中遇到的坑详述如下。
首先说说微信支付时的准备工作。
(https://pay.weixin.qq.com/wiki/doc/api/index.html 微信支付官方文档中心)
(https://mp.weixin.qq.com/ 微信开放平台)
这两个地址后续会用到我这里先给出。
微信支付功能需要到微信开放平台上面开通之后方可使用,进入微信开放平台如下图所示可以看见微信支付菜单栏
点击微信支付可以看到微信支付商户号详细信息(这里是已开通的微信支付)如下图所示:
微信支付开通这里就不累述了,申请微信支付按照步骤一步一步进行即可,到这里算是开通微信支付功能了,算是迈出微信支付第一步后面还有九十九步等着你去趟。
接下来登录微信商户平台(在成功申请微信支付之后,微信会给你发送一份邮件,邮件里面包含商户号、商户登录密码以及其他信息),登录微信商户平台的地址如下(https://pay.weixin.qq.com )登录名和密码都可以在邮件中找到,登录之后需要验证一些列信息,按照操作即可,这里需要注意的两点:
- 验证商户
微信支付申请成功之后微信会给申请时用的公司公户打一笔钱,一般是几毛到几分钱不等,在会计或出纳那里查到验证即可
- 设置api安全首先需要安装操作证书,其次是设置api秘钥,这个我本人感觉就比较坑,32位api秘钥需要你手动输入,而且还不能重复比如223322这种安全码是不可以的,即使设置成功但在后续签名时同样会碰到签名失败问题,所以这里最好是字母和数据组合不重复
接下来需要到
产品中心->开发配置中配置相应支付的支付条件
微信公众号配置需要配置到你微信开发服务器对应的域名下,注意这里的域名必须通过icp备案,不然无法添,扫码支付和h5支付同样需要icp备案域名不然无法添加。做完以上步骤算是走完微信支付的一半工作内容,剩下就是码码代码即可。
首先大家可以在https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1下载支付服务端demo,java\php\c#都有
扫码支付相对于其他几种支付算是最简单的一种,在做扫码支付的时候是一把梭哈。扫码支付文档地址:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1 ,查找扫码支付文档你可以轻松完成,
扫码支付有两种模式,我选择了第二种支付模式,
就是在调用统一下单之后,直接返回调起支付的url,在信息都正确之后调起统一下单接口URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder ,接口会返回
图中红线圈住的就是调起微信支付的地址,只需要生成二维码,打开微信支付扫一扫功能即可完成支付
扫码支付需要注意的就是签名错误问题,https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=20_1 这个地址是验证签名是否正确,
这里签名错误可能有三种原因
- 商户号和商户appid错误
- 设置的key也就是api秘钥不正确,api密码不正确也有两种情况
- 设置本身有问题,比如设置重复字符111222333之类的
- 在签名时的key不对或者压根就没有添加key
- 参数传递有误。参数一般传递错误会出现以下几种情况
- 终端IP spbill_create_ip APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。
- 交易类型 trade_type JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,
- 商品ID product_id trade_type=NATIVE时(即扫码支付),此参数必传。此参数为二维码中包含的商品ID,商户自行定义。
以上三点在做扫码支付时需要重视,不然坑你没商量,到此微信支付扫码支付算是搞定,后续还需要完善。
接下来讲一下公众号支付
因为公众号本来就是在微信里面,所以公众号支付也相对比较简单,也不存在分账问题,只是需要开通一个商户需要申请一个微信商户平台,比较麻烦,后续公司要是有时间可以自行开发微信支付后台,统一管理商户,实行划账。
微信公众号支付需要先申请微信服务号,唯有微信服务号才可以开通微信支付功能,其他暂时无法实现。申请微信服务号这里就不在讲述,公众号支付配置前面也讲过了,需要配置支付安全目录
也就是在开发微信公号时绑定的域名。从下载的demo中找到相对应的代码复制粘贴,复制粘贴,复制粘贴即可完成支付那是不可能的。这里坑就比较多了,首先需要获取openid,每一个微信公众号对应的用户的openid是不一样的,之前一直存在误区,还以为一个openid可以应对所有微信公众号,知道后来才发现并不是想象中那么美好,微信为了区分用户,openid和微信公众号是一一对应的,也就是说一个微信公众号对应一个openid,这个坑差点没坑吐我,我还在傻傻的用光放demo提供的案例在支付,直到后来公司前端(穆帅)出手相助,我才发现世界还是挺美好的。
我先将公众号支付业务流程贴出来
业务流程也比较简单,我就不详细讲解了。
首先调微信统一下单接口URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder
在所有信息都正确之后,微信会返回以下参数:
用返回的参数构造如下参数返回给微信公众号端
参数大小写,参数顺序不可随意变更(这里是用c#编写的代码)
注意微信公众号支付的坑比较多,大致有一下几点
- openid获取不正确,导致签名失败
- 未设置正确的支付授权目录、导致签名失败
- 未设置正确的api安全码(key)、导致签名时报
- Package格式错误 package 的value必须为prepay_id=xxx
- 返回参数大小写和官方给出文档不一致,导致签名错误
- 微信公众号支付需要两次签名,一次是在统一下单时,一次是在给客户端返回订单信息时
以上几点大致就是在做微信公众号支付是遇到的坑,可能坑不是很全乎,大家在具体做的时候在具体对待吧
最后一种h5支付
H5支付不像其他那些支付,申请好微信支付动手做就ok了,h5支付需要在微信商户平台开通h5支付功能之后才可以动手做,所以这里就比较坑了,为啥不一次性开通,还的在花费三四天时间开通呢?
在开通h5支付的时候需要提供h5相关页面,同样也需要是icp备案过后的域名才行,这里又坑四五天时间,所以说微信支付功能原本工作量比较小,但是东开通这,西开通那花费时间就不可估量了,由于h5支付在手机app上是不存在分账的,所以就用h5开发了。注意在申请h5支付的时候所有信息都必须和之前申请微信公众号的信息一致,网站主体、兜售信息、域名信息都必须和申请微信公众号的信息一致,不然无法通过h5申请,在申请好h5支付之后就可以开始动手做事了。
按照官方给出的demo,调起统一下单接口,返回所需参数,这里在调起统一下单接口传递参数需要注意几点
- appid 这里的appid并不是应用appid 而是微信公众号appid
- spbill_create_ip 必须传正确的用户端IP,详见获取用户ip指引
- scene_info
//安卓移动应用
{"h5_info": {"type":"Android","app_name": "王者荣耀","package_name": "com.tencent.tmgp.sgame"}}
注意 type 为需要填写ios
第四、trade_type H5支付的交易类型为MWEB
在所有信息都正确之后微信会返回一下参数
其中红线所圈为调起微信支付的链接地址,在返回改地址之后只需要调用该地址完成支付便可,这里又有一个坑需要注意一下,手机端在调起支付时需要构建referer头部请求不不然无法调起微信支付,在mui中构建如下代码所示:
这里同样需要注意:referer的值为在申请h5支付时候的icp备案域名地址,如若填写不正确,构建不成功
在做h5支付一般会遇见如下问题
- 网络环境未能通过安全验证,请稍后再试
1. 商户侧统一下单传的终端IP(spbill_create_ip)与用户实际调起支付时微信侧检测到的终端IP不一致导致的,这个问题一般是商户在统一下单时没有传递正确的终端IP到spbill_create_ip导致,详细可参见客户端ip获取指引
2. 统一下单与调起支付时的网络有变动,如统一下单时是WIFI网络,下单成功后切换成4G网络再调起支付,这样可能会引发我们的正常拦截,请保持网络环境一致的情况下重新发起支付流程
第二、商家参数格式有误,请联系商家解决
1. 当前调起H5支付的referer为空导致,一般是因为直接访问页面调起H5支付,请按正常流程进行页面跳转后发起支付,或自行抓包确认referer值是否为空
2. 如果是APP里调起H5支付,需要在webview中手动设置referer,如(
Map extraHeaders = new HashMap();
extraHeaders.put("Referer", "商户申请H5时提交的授权域名");//例如 http://www.baidu.com ))
第三、商家存在未配置的参数,请联系商家解决
1,当前调起H5支付的域名(微信侧从referer中获取)与申请H5支付时提交的授权域名不一致,如需添加或修改授权域名,请登陆商户号对应的商户平台--"产品中心"--"开发配置"自行配置
2,如果设置了回跳地址redirect_url,请确认设置的回跳地址的域名与申请H5支付时提交的授权域名是否一致
- 请在微信外打开订单,进行支付
-
IOS:签名验证失败
安卓:系统繁忙,请稍后再试
-
请确认同一个MWEB_URL只被一个微信号调起,如果不同微信号调起请重新下单生成新的MWEB_URL
2,如MWEB_URL有添加redirect_url,请确认参数拼接格式是否有误,是否有对redirect_url的值做urlencode,可对比以下例子格式:
https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096&redirect_url=https%3A%2F%2Fwww.wechatpay.com.cn
到此微信支付三种场景的应用算是基本完成,自己挖的坑自己跪着也要填平,刚开始做的时候的确是一头雾水,后来在各位大神的帮助下恍然大悟,所以说在难得事只要敢于摸索,敢于探究就没有解决不了的问题。自己做微信支付开发的一点经验,如若有错还恳请各位批正。