大家好,又见面了,我是你们的朋友全栈君。
最近,在为公司支付平台接入微信支付,看似很简单的过程,却搞得有点焦头烂额,踩了不少坑!在此记录下来,方便大家在开发中快速绕过这些坑!
本文的涉及的接口都是微信支付的测试环境下开发,即仿真测试环境。
一、统一下单
沙盒测试URL:https://api.mch.weixin.qq.com/sandboxnew/pay/unifiedorder,跟生产环境的URL区别就是URL中多了sandboxnew
我直接使用https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1 ,官方提供例子的请求参数去请求接口:
<xml>
<appid>wx2421b1c4370ec43b</appid>
<attach>支付测试</attach>
<body>JSAPI支付测试</body>
<mch_id>10000100</mch_id>
<detail><![CDATA[{ "goods_detail":[ { "goods_id":"iphone6s_16G", "wxpay_goods_id":"1001", "goods_name":"iPhone6s 16G", "quantity":1, "price":528800, "goods_category":"123456", "body":"苹果手机" }, { "goods_id":"iphone6s_32G", "wxpay_goods_id":"1002", "goods_name":"iPhone6s 32G", "quantity":1, "price":608800, "goods_category":"123789", "body":"苹果手机" } ] }]]></detail>
<nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
<notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>
<openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid>
<out_trade_no>1415659990</out_trade_no>
<spbill_create_ip>14.23.150.211</spbill_create_ip>
<total_fee>1</total_fee>
<trade_type>JSAPI</trade_type>
<sign>0CB01533B8C1EF103065174F50BCA001</sign>
</xml>
结果返回:
<xml>
<return_code><![CDATA[FAIL]]></return_code>
<return_msg><![CDATA[沙箱验证签名失败,请确认沙箱签名key是否正确(通过getsignkey调用生成)]]></return_msg>
</xml>
我一直怀疑生成的沙箱签名key有问题(如何获取沙箱签名key?下文说明),于是各种尝试,却在无意间把请求参数中的中文换掉,才发现是中文字符的问题!
这里的中文生成签名值时得先进行UTF-8编码!往下走,又出现了另外一个错误
<xml>
<return_code><![CDATA[FAIL]]></return_code>
<return_msg><![CDATA[沙箱支付金额(1)无效,请检查需要验收的case]]></return_msg>
</xml>
于是找来官方的验收用例:
将请求参数total_fee改为:1.01,结果返回
<xml>
<return_code><![CDATA[FAIL]]></return_code>
<retmsg><![CDATA[请确认请求参数是否正确total_fee]]></retmsg>
<retcode><![CDATA[1]]></retcode>
</xml>
这个错误发生的原因是接口文档要求total_fee的单位是“分”,改为101,最终返回结果:
<xml>
<trade_type><![CDATA[JSAPI]]></trade_type>
<prepay_id><![CDATA[wx20181029123210624306]]></prepay_id>
<nonce_str><![CDATA[Vq4MJb2nmMecRUYAynmzZDkwNDOCVaaj]]></nonce_str>
<return_code><![CDATA[SUCCESS]]></return_code>
<err_code_des><![CDATA[ok]]></err_code_des>
<sign><![CDATA[48BDBFDC3D65DAEA5B5008B704BD8BB2]]></sign>
<mch_id><![CDATA[1496762762]]></mch_id>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[wx51216dba2xxxx1c]]></appid>
<device_info><![CDATA[]]></device_info>
<result_code><![CDATA[SUCCESS]]></result_code>
<err_code><![CDATA[SUCCESS]]></err_code>
</xml>
OK,这总算下单成功了!
上文提到如何获取沙箱签名key,这个官方文档写得很模糊,https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=23_1
这里直接贴出我的获取方法,代码中说明一下要注意的地方:
public String getSignKey() {
URI uri;
try {
uri = new URI("https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey");//**获取仿真测试环境验签秘钥API**
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);//**媒体类型`application/xml`**
Map<String, String> map = new HashMap<String, String>();
map.put("mch_id", wxPayConfig.getMchID());//商户号
map.put("nonce_str", WXPayUtil.generateNonceStr());**//随机字符串**
map.put("sign", WXPayUtil.generateSignature(map, wxPayConfig.getKey()));**//用生产环境的KEY对mch\_id、nonce\_str 请求参数签名**
HttpEntity<String> entity = new HttpEntity<String>(WXPayUtil.toXML(map), headers);**//其实请求的是xml格式,非key-value格式**
String responseXML = rt.postForObject(uri, entity, String.class);
Map<String, String> xmlToMap = WXPayUtil.xmlToMap(responseXML);
String sandbox\_signkey = xmlToMap.get("sandbox\_signkey");
return sandbox_signkey;**//这个就是沙箱签名key**
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
该key的作用就是替换生产环境的key,用来生成接口请求参数的签名。
官方签名算法说明:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3
生产环境key的获取方法:key设置路径:微信商户平台(pay.weixin.qq.com)–>账户设置–>API安全–>密钥设置
好了,先记录到这,后期有补充再补充!
Good Luck!
转载于:https://my.oschina.net/benz001/blog/2254001
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/107229.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...