- 在微信商家后台中申请证书
2.会下载一个应用,跟着操作就好了,最后会得到一个压缩文件,解压之后会得到
3.你把这几个文件放到你项目的文件中,
就可以了
4.上述操作完成之后,附代码:
//url 微信退款请求地址 data 请求参数
public static String doRefund(String url, String data) throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
// 指定证书路径
String path = "/cert/apiclient_cert.p12";
ClassPathResource classPathResource = new ClassPathResource(path);
//读取项目存放的PKCS12证书文件
InputStream stream = classPathResource.getInputStream();
String mchId = "自己的商户id";
try {
//指定PKCS12的初始密码为商户ID
keyStore.load(stream, mchId.toCharArray());
} finally {
stream.close();
}
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchId.toCharArray()).build();
//指定TLS版本
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext,new String[] { "TLSv1"},null,SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
//设置httpclient的SSLSocketFactory
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 = EntityUtils.toString(response.getEntity(), "UTF-8");
EntityUtils.consume(entity);
return jsonStr;
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
/**
* 退款
* @param orderPrice 订单金额(分)
* @param refundPrice 退款金额(分)
* @param refundMark 退款备注
* @param out_trade_no 退款商家订单号
* @return
* @throws Exception
*/
public static String refund(Integer orderPrice,Integer refundPrice,String refundMark,String out_trade_no) throws Exception {
Map<String, String> params = new HashMap<>();
String outRefundNo = GenerateNum.getInstance().GenerateOrder();//可以自定义一个类来随机生成退款单号等等
params.put("appid", "小程序Appid");
params.put("mch_id", "商户号");
//商户订单号
params.put("out_trade_no", out_trade_no);
//商户退款单号
params.put("out_refund_no", outRefundNo);
//总金额
params.put("total_fee", String.valueOf(orderPrice));
//退款金额
params.put("refund_fee", String.valueOf(refundPrice));
//退款原因
params.put("refund_desc", refundMark);
//退款结果回调地址
params.put("notify_url", "回调域名");
//随机字符串
params.put("nonce_str", WXPayUtil.generateNonceStr());//使用微信随机字符串生成
//生成sign
String sign = WXPayUtil.generateSignature(params, "自己的商户密钥");
params.put("sign", sign);
//微信申请退款接口
String wx_refund_url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
String xmlStr = WXPayUtil.mapToXml(params);//转换成xml格式
System.out.println(xmlStr);
//发送双向证书请求给微信
String resultXmlStr = doRefund(wx_refund_url, xmlStr);
System.out.println(resultXmlStr);
// 将返回的字符串转成Map集合
Map<String, String> resultMap = WXPayUtil.xmlToMap(resultXmlStr);//转成map格式
Map<String, String> map = new HashMap<>();
if ("SUCCESS".equalsIgnoreCase(resultMap.get("result_code"))) {
System.out.println("------申请退款成功,正在退款中----");
//申请微信退款接口返回success,但是退款到账还需要时间;
map.put("success", "REFUNDS");
return "1";
} else {
map.put("success", resultMap.get("err_code_des"));
System.out.println("-------------退款失败-------------------" + resultMap.get("err_code_des"));
return "2";
}
}
/*
* 退款订单结果查询
* 生成签名的xml
* @return
* */
public static String selRefundOrder(String out_trade_no) {
// 封装需要的信息
Map<String, String> payMap = new HashMap<String, String>();
String nonceStr = WXPayUtil.generateNonceStr();
try {
// 1. 拼接下单地址参数
Map<String, String> param = new HashMap<String, String>();
param.put("appid", "小程序appid");
param.put("mch_id", "商户id");
param.put("out_trade_no", out_trade_no); // 随机字符串
param.put("nonce_str", nonceStr); // 账单类型
param.put("sign_type", "MD5"); // 签名类型
// 生成签名,官方默认MD5+商户秘钥+参数信息
String sign = WXPayUtil.generateSignature(param, "商户密钥");
param.put("sign", sign);
// 将所有参数转换为xml形式
String xmlParam = WXPayUtil.mapToXml(param);
// 2. 发送请求
HttpClient1 httpClient1 = new HttpClient1("https://api.mch.weixin.qq.com/pay/refundquery");
httpClient1.setHttps(true);// https协议
httpClient1.setXmlParam(xmlParam);
httpClient1.post();
// 获取结果
String xmlResult = httpClient1.getContent();
System.out.println(xmlResult);
if (xmlResult.indexOf("SUCCESS") != -1) { // 只要执行了下单接口,都会包含SUCCESS的
Map<String, String> map = WXPayUtil.xmlToMap(xmlResult);
if (map.get("refund_fee").equals(map.get("total_fee"))){
System.out.println(out_trade_no+"退款"+map.get("refund_fee")+"成功到"+map.get("refund_recv_accout_0"));
return "1";
}else {
System.out.println(out_trade_no+"退款"+map.get("refund_fee")+"部分到"+map.get("refund_recv_accout_0"));
return "2";
}
}else {
System.out.println(out_trade_no+"退款失败,不存在");
return "3";
}
} catch (Exception e) {
e.printStackTrace();
payMap.put("msg", out_trade_no+"签名生成错误");
return "签名失败";
}
}
代码中的**WXPayUtil **为微信支付官方的SDK
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>