2018年一月本人有幸给公司做了一个对接支付宝支付与微信支付的项目,先做的支付宝支付,然后做的微信支付;这里不得不说支付宝真的是强,api文档清晰,说明准确,测试环境(沙箱)好用,你在支付宝开通商户账户后支付宝会分配相应的沙箱商户账户和用户账户,测试方便。微信可就不那么方便了,简直是满地的坑啊。在微信支付文档上已经有写明的我就不说的,有兴趣的可以去看:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_1,下面都是我在开发过程中遇到的坑:
1、微信支付也提供沙箱环境,但是它的沙箱环境跟真实环境完全是不一样,https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=21_2,这是微信官网关于沙箱环境的文档,傻傻的根据它的文档一步一步操作会出现以下问题:
a、根据文档将请求路径前加/sandbox/然后请求,首先会报沙箱秘钥没有;
b、百度之后得知获取微信沙箱秘钥的地址是 : https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey 请求方式POST
需要参数 mch_id-商户号,nonce_str-随机字符串,sign-签名,前面两个参数好说,后面的 sign看得我是一脸懵逼,经过 几 次测试最后得到sign的代码是这样的:
SortedMap
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
datas.put("mch_id", "你的商户号");
datas.put("nonce_str", uuid);
String sign = WXPayUtil.generateSignature(datas, "这里传商户秘钥");
WXPayUtil这个类可以直接在微信支付官网上的demo里面找到,我就懒得贴了
最后得到沙箱秘钥的代码是这样的:
CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/sandbox/pay/getsignkey");
SortedMap
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
datas.put("mch_id", "你的商户号");
datas.put("nonce_str", uuid);
String sign = WXPayUtil.generateSignature(datas, "这里传商户秘钥");
datas.put("sign", sign);
String reqeustXml = WXPayUtil.mapToXml(datas);
StringEntity postEntity = new StringEntity(reqeustXml, "UTF-8");
httpPost.addHeader("Content-Type", "text/xml");
httpPost.setEntity(postEntity);
//httpPost.setConfig(requestConfig);
CloseableHttpResponse httpResponse = closeableHttpClient.execute(httpPost);
int statusCode = httpResponse.getStatusLine().getStatusCode();
if(statusCode == 200) {
EntityUtils.toString(httpResponse.getEntity(), UTF8); //这里面返回的sign就是沙箱秘钥
}
c、好现在我们已经成功的获取了沙箱秘钥,根据微信支付文档需要先调用微信统一下单接口:https://api.mch.weixin.qq.com/pay/unifiedorder,因为是沙箱环境所以是这样的:https://api.mch.weixin.qq.com/sandboxnew/pay/unifiedorder,如果一切顺利的话,会返回一个xml的字符串,用WXPayUtil里面的方法解出来,如果下单成功会返回 result_code SUCCESS,根据文档因为是h5支付,到这一步还没有结束,还要调微信支付的页面去付款,根据文档就是 mweb_url 这个参数,所以楼主就在返回参数中傻傻的找这个参数,测了 几十遍啊,就是没有,是的没有,我记得在这个地方卡了一天吧大概,打过客服,微信客服实在是太坑,都是泪啊;后面忽然脑洞大开,怀疑沙箱环境压根就不会返回mweb_url;为了印证我这个想法,就又写了一个微信支付的查询订单的方法 :https://api.mch.weixin.qq.com/pay/orderquery 沙箱环境是这样的: https://api.mch.weixin.qq.com/sandboxnew/pay/orderquery,根据文档传相关的参数,一查果然,订单已经显示支付成功了,到这一步我真的泪奔啊。。。。;总结就是微信支付沙箱环境是不会跳支付页面的,你调沙箱的下单接口,直接就支付成功。当然这个地方因为楼主是先做的支付宝支付,它的沙箱环境跟真实环境是一样的,都是要支付的,有点先入为主了,想当然的以为微信也是这样的
d、这个地方有一个需要注意的就是因为微信支付沙箱环境与真实环境不一样,同步接口需要根据沙箱环境还是真实环境进行处理,微信支付真实环境你需要把同步回调的接口地址加到mweb_url后面,微信支付成功后会回调这个地址,我的是这样写的:
String mweb_url = resultMap.get("mweb_url");
StringBuilder redirectUrlSb = new StringBuilder();
redirectUrlSb.append(mweb_url)
.append("&")
.append("redirect_url")
.append("=") .append(URLEncoder.encode(properties.getWeixinpay().getPayReturnUrl(),"UTF-8"));
response.sendRedirect(redirectUrlSb.toString());
e、微信正式环境中,支付也有些问题,具体请参考:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_4,微信支付文档实在是太乱,这里放一点,那里放一点。
f、还有其他的可能遇到的问题:沙箱环境是没有异步回调的、沙箱环境支付金额貌似只能是 1.01 * 100,1.02*100,微信的RMB单位是分,传其他金额,退款貌似有问题
楼主第一次写博文,也是在写微信H5支付的时候看到网上关于微信h5支付遇到的问题相关的文章比较少,写的并没什么条理,就是想到哪写到哪,请多多包涵。如有问题可联系微信: