应用场景
当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后,按照退款规则将支付款按原路退到买家帐号上。
注意:
1、交易时间超过一年的订单无法提交退款;
2、微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。
1.首先我们需要准备以下参数:
// 商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔 String out_refund_no = "4003832001201605045494929094"; // 商户侧传给微信的订单号 String out_trade_no = "C70E285B10B000011C8312B2D82011F4"; // 总金额 String total_fee = "1"; // 退款金额 String refund_fee = "1"; // 随机字符串 String nonce_str = "C70E285B10B000011C8312B2D82011F4"; //微信商户id String mch_id = "1230177801"; //就是MCHID String op_user_id = "1230177801"; //微信公众号apid String appid = "wx832f85feb2e76b14"; String appsecret = "43cab6b2766381683f6cb1b4ee6db27a"; String partnerkey = "be9aded460e78703b889f18e2915ea6b";
2.用appid、appsecret、partnerkey生成签名
详情可参考微信签名生成API或者参考附件方法
3.执行退款请求
//参数
String data= "<xml>" + "<appid>" + appid + "</appid>" + "<mch_id>"
+ mch_id + "</mch_id>" + "<nonce_str>" + nonce_str
+ "</nonce_str>" + "<sign><![CDATA[" + sign + "]]></sign>"
+ "<out_trade_no>" + out_trade_no + "</out_trade_no>"
+ "<out_refund_no>" + out_refund_no + "</out_refund_no>"
+ "<total_fee>" + total_fee + "</total_fee>"
+ "<refund_fee>" + refund_fee + "</refund_fee>"
+ "<op_user_id>" + op_user_id + "</op_user_id>" + "</xml>";
//响应头信息
String url= "https://api.mch.weixin.qq.com/secapi/pay/refund";
/**
* 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的
*/
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(new File("D:/refund/apiclient_cert.p12"));//P12文件目录
try {
keyStore.load(instream, "1230177801".toCharArray());//这里写密码..默认是你的MCHID
} finally {
instream.close();
}
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, "1230177801".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 httpost = new HttpPost(url); // 设置响应头信息
httpost.addHeader("Connection", "keep-alive");
httpost.addHeader("Accept", "*/*");
httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
httpost.addHeader("Host", "api.mch.weixin.qq.com");
httpost.addHeader("X-Requested-With", "XMLHttpRequest");
httpost.addHeader("Cache-Control", "max-age=0");
httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
httpost.setEntity(new StringEntity(data, "UTF-8"));
CloseableHttpResponse response = httpclient.execute(httpost);
try {
HttpEntity entity = response.getEntity();
String jsonStr ="";
if (entity != null) {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(entity.getContent());
Element rootElt = document.getRootElement();
// 结果码
String returnCode = rootElt.elementText("return_code");
String resultCode = rootElt.elementText("result_code");
if ("SUCCESS".equals(returnCode)&&"SUCCESS".equals(resultCode)) {
String strResponse=returnCode;
System.out.println(strResponse);
jsonStr="退款成功";
}else {
String strResponse=rootElt.elementText("err_code_des");
System.out.println(strResponse);
jsonStr="退款失败";
}
}
/* String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
EntityUtils.consume(entity);*/
return jsonStr;
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
评一波