记一次微信支付爬坑

微信支付-那些年填过的坑

由于最近项目需要用到微信支付,所以需要研究微信支付相关内容,微信支付本身不是什么问题,只是过程比较繁琐,前提工作需要准备充足方可开工,不然你会一个坑接着一坑的掉。

由于业务需要,需要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密码不正确也有两种情况
  1. 设置本身有问题,比如设置重复字符111222333之类的
  2. 在签名时的key不对或者压根就没有添加key
  • 参数传递有误。参数一般传递错误会出现以下几种情况
  1. 终端IP spbill_create_ip  APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。
  2.  交易类型 trade_type  JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,
  3. 商品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:签名验证失败
    安卓:系统繁忙,请稍后再试
  1. 请确认同一个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

到此微信支付三种场景的应用算是基本完成,自己挖的坑自己跪着也要填平,刚开始做的时候的确是一头雾水,后来在各位大神的帮助下恍然大悟,所以说在难得事只要敢于摸索,敢于探究就没有解决不了的问题。自己做微信支付开发的一点经验,如若有错还恳请各位批正。

猜你喜欢

转载自blog.csdn.net/chang1611/article/details/81558573