一、接口链接:https://api.mch.weixin.qq.com/secapi/pay/refund
二、请求字段
三、注意事项
(1)需要证书:
(2)证书来源:
(3)证书获取
四、代码开发
/**
* 微信退款
* @throws Exception
*/
public static String refundFunction(Map<String, Object> map) throws Exception {
//这里的map主要有两个参数(商户号mchId和订单金额totalFee)
String result = "";//这里用于返回处理返回结果
//xml转换为map,这里用于方便自己后面取出打印结果
XmlToMap xmlToMap = new XmlToMap();
//这里是自己封装的一些配置文件,大家可以跳过这一步,下面用到这里会和大家说明
MyConfig config = null;
try {
//加载配置
config = new MyConfig();
} catch (Exception e) {
e.printStackTrace();
}
//获取商户订单号和订单金额
String mchId = map.get("mchId").toString();
//获取订单金额(退款金额默认全部)
//这里是自己做的一些格式的转换,有点笨拙,希望不影响大家的思路
String a = map.get("totalFee")+"";
String b = Double.valueOf(a) + "";
int lastindex = b.indexOf(".");
b = b.substring(0 , lastindex);
int c = Integer.parseInt(b);
// String d = c + "";
// System.out.println("refundMoney--------->"+refundMoney);
String totalFee = c + "";
//获取微信订单号
// String transactionId = map.get("transactionId").toString();
SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
parameters.put("appid", config.getAppID());//appid
parameters.put("mch_id", config.getMchID());//商户号
parameters.put("nonce_str", CreateNoncestr());//随机数
// parameters.put("transaction_id", transactionId);//微信支付单号
parameters.put("out_trade_no", mchId);//商户订单号
parameters.put("out_refund_no", CreateNoncestr());//我们自己设定的退款申请号,约束为UK
parameters.put("total_fee", totalFee) ;//订单金额 单位为分!!!这里稍微注意一下
parameters.put("refund_fee", totalFee);//退款金额 单位为分!!!
parameters.put("op_user_id", config.getMchID());//操作人员,默认为商户账号
String sign = createSign("utf-8", parameters);
System.out.println("sign---->"+sign);//签名
parameters.put("sign", sign);
//xml和map之间的转换
String reuqestXml = getRequestXml(parameters);
Map<String, Object> xmlMap = XmlToMap.xmlStr2Map(reuqestXml);
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(new File(config.certPath));//放商户证书的路径
try {
keyStore.load(instream, config.getMchID().toCharArray());//商户号
} finally {
instream.close();
}
//这里导包注意一下,可能会冲突
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, config.getMchID().toCharArray()).build();//商户号
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(config.refund_url);//退款接口
System.out.println("executing request" + httpPost.getRequestLine());
StringEntity reqEntity = new StringEntity(reuqestXml);
// 设置类型
reqEntity.setContentType("application/x-www-form-urlencoded");
httpPost.setEntity(reqEntity);
CloseableHttpResponse response = httpclient.execute(httpPost);
try {
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(),"UTF-8"));
System.out.println("bufferedReader.readLine()--->"+bufferedReader.readLine());
String text;
//这里是自己做的输出结果,方便查看错误原因
while ((text = bufferedReader.readLine()) != null) {
System.out.println(text);
if(!text.startsWith("</xml>")) {
text = "<xml>"+text+"</xml>";
Map<String, Object> xmlResultMap = XmlToMap.xmlStr2Map(text);
if(xmlResultMap.get("result_code") != null) {
result = xmlResultMap.get("result_code")+"";
}
}
}
}
EntityUtils.consume(entity);
} finally {
response.close();
}
} finally {
httpclient.close();
}
return result;
}