前置条件
对接微信沙箱环境也需要拥有正式的商户号和key,微信不像支付宝可以获取测试号,所以没有注册商户号无法对接沙箱环境。并且下载WXSDK。
请求方法
1、获取沙箱环境key
/**
* 获取沙箱key
* @return String 沙箱key
*/
public static String getSandboxSignKey(WxpayConf wxpayConf) {
Map<String, String> params = new HashMap<>();
params.put("mch_id", wxpayConf.getMchID()); //商户id
params.put("nonce_str", WXPayUtil.generateNonceStr()); //随机字符串
String key = "xxxxxxxxxxxxxxxxxxxxxxxxxxx"; //真实商户key
try {
params.put("sign", WXPayUtil.generateSignature(params, key));
} catch (Exception e) {
e.printStackTrace();
}
Map<String, String> result = sandboxResp("https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey", params);
if ("SUCCESS".equals(result.get("return_code"))) {
LOGGER.debug("沙箱key:{}", result.get("sandbox_signkey"));
return result.get("sandbox_signkey");
}else{
return result.get("return_msg");
}
}
2、自定义组装xml公共方法
由于沙箱环境与正式环境不同,xml的格式也不同,所以需要自己写一个生成沙箱环境的xml方式。
public static String sandboxMapToXml(Map<String, String> map) throws Exception {
String xmlResult = "";
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
for (String key : map.keySet()) {
String value = map.get(key);
sb.append("<" + key + ">" + value + "</" + key + ">");
}
sb.append("</xml>");
xmlResult = sb.toString();
LOGGER.info("沙箱环境请求XML:{}", xmlResult);
return xmlResult;
}
3、发起微信支付沙箱环境请求公共方法
由于很多sdk中不带有沙箱环境请求方法,而且沙箱环境只能用xml参数请求,所以需要自定义请求方式。
/**
* 沙箱环境发起请求公共方法
*
* @param urlInfo
* @param params
* @return
*/
public static Map<String, String> sandboxResp(String urlInfo, Map<String, String> params){
try {
URL url = new URL(urlInfo); //请求地址
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
con.setRequestMethod("POST");
con.addRequestProperty("Content-Type", "application/json");
con.setRequestProperty("accept", "*/*");
con.setRequestProperty("connection", "Keep-Alive");
OutputStreamWriter out = new OutputStreamWriter(con
.getOutputStream());
String xmlInfo = sandboxMapToXml(params);
out.write(new String(xmlInfo.getBytes("UTF-8")));
out.flush();
out.close();
BufferedReader br = new BufferedReader(new InputStreamReader(con
.getInputStream()));
String line = "";
String strXML = "";
for (line = br.readLine(); line != null; line = br.readLine()) {
strXML = strXML + line;
}
Map<String, String> result = WXPayUtil.xmlToMap(strXML);
//适配沙箱环境部分错误返回数据格式
if(StringUtils.isEmpty(result.get("return_msg"))){
result.put("return_msg", result.get("retmsg"));
result.remove("retmsg");
}
return result;
}catch (Exception e){
return null;
}
}
由于沙箱环境返回的msg信息也不同,所以还做了转换。
总结
有了这三步,再根据业务判断环境进行不同环境调用。总之,步骤就是:
1、获取沙箱环境的key
2、利用自定义map转xml函数,将请求参数转成沙箱环境xml
3、利用沙箱环境的key和请求参数进行签名
4、利用自定义请求方法,向沙箱环境发起请求。