//支付交易订单号,amount 退款金额,orderAmount 订单金额,refundSn 退货单号
public Map<String, Object> refunds(String orderSn, BigDecimal amount,BigDecimal orderAmount,String refundSn) throws Exception {
Map<String, Object> parameterMap = new TreeMap<>();
parameterMap.put("appid", getAppId());//公众账号ID
parameterMap.put("mch_id", getMchId());//商户号
parameterMap.put("nonce_str", DigestUtils.md5Hex(UUID.randomUUID() + RandomStringUtils.randomAlphabetic(30)));//随机字符串
parameterMap.put("out_refund_no",refundSn);//退单号
parameterMap.put("out_trade_no", orderSn);//支付单号
parameterMap.put("total_fee", orderAmount.intValue());//订单金额
parameterMap.put("refund_fee", amount.intValue());//退款金额
parameterMap.put("sign", generateSign(parameterMap));
//String result = WebUtils.post(service_url, XmlUtils.toXml(parameterMap));
String result = RefundRequest.ClientCustomSSL(XmlUtils.toXml(parameterMap), service_url, getMchId());
Map<String, String> resultMap = XmlUtils.toObject(result, new TypeReference<Map<String, String>>() {
});
String return_code = resultMap.get("return_code");
String return_msg = resultMap.get("return_msg");
String result_code = resultMap.get("result_code");
Map<String, Object> map = new HashMap<>();
if("SUCCESS".equals(return_code)&&result_code!=null&&"SUCCESS".equals(result_code)){
map.put("return_code", return_code);
map.put("return_msg", return_msg);
map.put("result_code", result_code);
map.put("out_refund_no", resultMap.get("out_refund_no"));
map.put("refund_fee", resultMap.get("refund_fee"));
}else{
map.put("return_code", return_code);
map.put("return_msg", return_msg);
}
return map;
}
XmlUtils.toXml
/**
* 将对象转换为XML字符串
*
* @param value
* 对象
* @return XML字符串
*/
public static String toXml(Object value) {
Assert.notNull(value, "[Assertion failed] - value is required; it must not be null");
try {
JacksonXmlModule module = new JacksonXmlModule();
module.setDefaultUseWrapper(true);
XmlMapper xmlMapper = new XmlMapper(module);
return xmlMapper.writer().withRootName("xml").writeValueAsString(value);
} catch (JsonProcessingException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
XmlUtils.toObject
/**
* 将XML字符串转换为对象
*
* @param xml
* XML字符串
* @param valueType
* 类型
* @return 对象
*/
public static <T> T toObject(String xml, Class<T> valueType) {
Assert.hasText(xml, "[Assertion failed] - xml must have text; it must not be null, empty, or blank");
Assert.notNull(valueType, "[Assertion failed] - valueType is required; it must not be null");
try {
return XML_MAPPER.readValue(xml, valueType);
} catch (JsonParseException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (JsonMappingException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
/**
* 生成签名
*
* @param parameterMap
* 参数
* @return 签名
*/
private String generateSign(Map<String, ?> parameterMap) {
return StringUtils.upperCase(DigestUtils.md5Hex(joinKeyValue(new TreeMap<>(parameterMap), null, "&key=" + getApiKey(), "&", true)));
}
getApiKey() 是获取商户账号里设置的密码
/**
* 连接Map键值对
*
* @param map
* Map
* @param prefix
* 前缀
* @param suffix
* 后缀
* @param separator
* 连接符
* @param ignoreEmptyValue
* 忽略空值
* @param ignoreKeys
* 忽略Key
* @return 字符串
*/
protected String joinKeyValue(Map<String, Object> map, String prefix, String suffix, String separator, boolean ignoreEmptyValue, String... ignoreKeys) {
List<String> list = new ArrayList<>();
if (map != null) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
String value = ConvertUtils.convert(entry.getValue());
if (StringUtils.isNotEmpty(key) && !ArrayUtils.contains(ignoreKeys, key) && (!ignoreEmptyValue || StringUtils.isNotEmpty(value))) {
list.add(key + "=" + (value != null ? value : StringUtils.EMPTY));
}
}
}
return (prefix != null ? prefix : StringUtils.EMPTY) + StringUtils.join(list, separator) + (suffix != null ? suffix : StringUtils.EMPTY);
}
RefundRequest.ClientCustomSSL
public static String ClientCustomSSL(String xmlStr,String path,String mchid) throws Exception{
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(SystemUtils.getWeiXinFile());
try {
keyStore.load(instream, mchid.toCharArray());
} finally {
instream.close();
}
// Trust own CA and all self-signed certs
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, mchid.toCharArray())
.build();
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[] { "TLSv1" },
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();
try {
HttpPost httpPost = new HttpPost(path);
StringEntity entityStr = new StringEntity(xmlStr);
entityStr.setContentType("text/xml");
System.out.println("entityStr--------------"+entityStr);
httpPost.setEntity(entityStr);
CloseableHttpResponse httpResponse = httpclient.execute(httpPost);
HttpEntity httpEntity = null;
try {
httpEntity = httpResponse.getEntity();
if (httpEntity != null) {
return EntityUtils.toString(httpEntity, "UTF-8");
}
EntityUtils.consume(httpEntity);
} finally {
EntityUtils.consume(httpEntity);
IOUtils.closeQuietly(httpResponse);
httpResponse.close();
}
} finally {
httpclient.close();
}
return null;
}