这或许是你看到的最有效的微信H5支付几大问题的解决方案
因为项目中使用到了支付,当前国内支付无非就支付宝、微信、银联这几种方式,支付宝和银联支付今天暂时不讨论,搞过的都清楚,支付宝还是比较简单的,相对于前端来说,不会太复杂,几乎接近于完美(怎么说人也是做支付的),而微信就真的有很多坑了!
1.商家参数格式有误,请联系商家解决
说起来,真是欲哭为泪,尤其是使用vue react等单页面应用开发项目的,多少一开始都很头大,我一开始也遇到了这个问题,各种百度无果,最后还是研究文档发现了其中的问题!
首先,先看微信对于这个错误的解释:
我们直接看第一个提示1.当前调起H5支付的referer为空导致,一般是因为直接访问页面调起H5支付,请按正常流程进行页面跳转后发起支付,或自行抓包确认referer值是否为空。
先说这个问题的解决办法:
不管你是用的vue还是react ,找到你项目里的 index.html,一般在public文件夹下,
把index.html 中的
注释掉
这句代码的意思是 发起的请求将不会携带 referer。
那如何理解这个referer呢?
关于Referer
Referer是HTTP 请求header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器该网页是从哪个页面链接过来的,服务器因此可以获得一些信息用于处理。例如:你在百度搜索语雀,可以看到控制台网络,有Referer:https://www.yuque.com/dashboard 它表示一个来源。
Referer的作用我就不具体细说了,一般是作为防盗链,防止恶意请求的,下一期我可以单独出一个关于referer的介绍。
vue react一开始用脚手架生成的时候,默认referer是用不携带的,所以,涉及到支付的时候,一定要查看一下index.html!!!
2.商家存在未配置的参数,请联系商家解决
先看下微信文档的解释:
意思说的很明白就是域名没有配置正确, 这个问题是跟着上一个问题来的,当你配置好了referer,微信也能获取到你的源,也就能获取到你原地址中的域名,如果你在微信开放平台中授权H5的支付安全域名与referer中的不一致,就会报这个错误。
如果你能保证在微信开放平台中已经授权h5支付安全域名,且域名已经备案
,那大概率是不会出现这种问题。
在微信开放平台中, 授权h5支付安全域名的时候,一般它会告诉你,设置一级域名或者二级域名,一般来说,设置一级域名以后,二级域名 三级域名会自动通过,无需配置二级 三级域名,但能还是有部分人,分不清什么是一级域名和二级域名
一级域名和二级域名的区别
1、定义不同
顶级域(或一级域名),英语:Top-level domains,first-level domains(TLDs),也翻译为国际顶级域名。是互联网DNS等级之中7a686964616fe78988e69d8331333431373165的最高级的域;
二级域(或称二级域名;英语:Second-level domain;英文缩写:SLD)是互联网DNS等级之中,处于顶级域名之下的域。二级域名是域名的倒数第二个部分,例如在域名example.baidu.com中,二级域名是Baidu。
2、域名组成不同
一级域名是由一个合法的字符串+域名后缀组成,例如:lisp.com这种形式的域名才是一级域名,lisp是域名主体,.com是域名后缀,可以是.net也是域名后缀;
二级域名是一个一级域名下面的主机名,它是在一级域名前面加上一个字符串,比如asdx.lisp.com。
二级域名是依附在一级域名的存在而存在的,也就是说顶级域名消失了,二级域名也会不复存在,反而来说,二级域名网站不做了,主域名不受影响的。
3.同一订单号调用统一下单接口后未支付 再到另一个支付方式支付 报:201 重复下单 错误
这个错误一般发生在后台,php或者java端,微信在处理订单的时候和支付宝不同,例如你已经用native的方式,调用了统一下单接口,但是并未进行支付,这时,如果你拿同样的参数再去调用H5支付的统一下单接口,势必会报这个错误。
这个问题解决起来也好办,在调用统一下单接口给$out_trade_no赋值时 给它加上区别字符,如 :
$out_trade_no = 'MWEB'.$out_trade_no; //H5支付
$out_trade_no = 'WWEB'.$out_trade_no; //native支付
这样就不会报错了
注意: 在支付成功回调逻辑处理的时候 别忘记把 $out_trade_no 的前几位标识符 去掉
最后
在前端代码中获取到支付链接以后直接
window.location.href= MWEB_URL + '&redirect_url=' + encodeURIComponent(redirect_url);
完事,收工!