spring boot 申请微信退款
一、需要API证书(apiclient_cert.p12证书的,在微信公众号上下载–注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的 。)
java用的是.12格式的证书
保存相关配置工具类
// 微信号,
public static String APP_ID = "";
// 应用对应的凭证
public static String APP_SECRET = "";
// 商户密钥
public static String API_KEY = "";
// 商业号
public static String MCH_ID = "";
//退款地址
public static String REFUND_URL= "";
//证书路径
public static String API_URL= "e:\\apiclient_cert.p12";
退款类
package com.gxkj.gx.admin.service.controller;
import com.gxkj.gx.admin.service.utils.WXPayConstants;
import com.gxkj.gx.admin.service.utils.WXPayUtil;
import com.gxkj.gx.common.utils.PayConfig;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.security.KeyStore;
import java.util.*;
public class WxController extends WorkController{
private static final Logger logger = LoggerFactory.getLogger(WxController.class);
/**
* 申请微信退款
* @param order
* @param wxorder
* @param money
* @param sumMoney
* @return
*/
public static String wxReFund(String order,String wxorder,double money,double sumMoney) {
try {
Map<String, String> reqData = new HashMap<>();
reqData.put("appid", PayConfig.APP_ID);
reqData.put("mch_id", PayConfig.MCH_ID);
reqData.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串
reqData.put("sign_type", "MD5");
reqData.put("transaction_id",wxorder);//付款微信订单号
reqData.put("out_refund_no",order);//退款订单号
Double price = money * 100;
Double sumMoneys = sumMoney * 100;
reqData.put("total_fee", String.valueOf(sumMoneys.intValue()));//订单总金额,单位为分
reqData.put("refund_fee", String.valueOf(price.intValue()));//退款总金额,单位为分
reqData.put("sign", WXPayUtil.generateSignature(reqData, PayConfig.API_KEY, WXPayConstants.SignType.MD5));
//微信统一下单
// 将所有参数转换为xml形式
String xmlParam = WXPayUtil.mapToXml(reqData);
String xmlStr = doRefund(REFUND_URL, xmlParam);
Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
if (map == null || !"SUCCESS".equals(map.get("return_code"))) {
//消息通知
System.out.println("-----退款发起失败-----"+map);
return null;
}else {//返回退款微信订单号
return map.get("refund_id");
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
/**
* 申请退款
*/
public static String doRefund(String url, String data) throws Exception {
StringBuilder sb = new StringBuilder();
try {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
//证书
FileInputStream instream = new FileInputStream(new File(API_URL));
String mchid = PayConfig.MCH_ID;
try {
keyStore.load(instream, mchid.toCharArray());
} finally {
instream.close();
}
// 证书
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, mchid.toCharArray())
.build();
// 只允许TLSv1协议
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[]{"TLSv1"},
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
//创建基于证书的httpClient,后面要用到
CloseableHttpClient client = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();
HttpPost httpPost = new HttpPost(url);//退款接口
StringEntity reqEntity = new StringEntity(data);
// 设置类型
reqEntity.setContentType("application/x-www-form-urlencoded");
httpPost.setEntity(reqEntity);
CloseableHttpResponse response = client.execute(httpPost);
try {
HttpEntity entity = response.getEntity();
System.out.println(response.getStatusLine());
if (entity != null) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
String text = "";
while ((text = bufferedReader.readLine()) != null) {
sb.append(text);
}
}
EntityUtils.consume(entity);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
}