开发的业务中可能会有支付完成后,需要进行退款的情况,我最近开发也遇到了,于是呢就对接了一下微信和支付宝的退款的接口
1、支付宝退款,支付宝退款还是很简单的
Map<String, String> websitemap = getAlipayInfo();// 获得支付宝配置
String appId = websitemap.get("alipayAppid"); // 支付宝合作伙伴id
String privateKey = websitemap.get("privatekey");//支付宝的私钥
String publicKey = websitemap.get("publickey");//支付宝的公钥
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
appId, privateKey, "json", "UTF-8", publicKey, "RSA2");
//请求参数
AlipayTradeRefundModel refundModel = new AlipayTradeRefundModel();
refundModel.setTradeNo(order.getExternalOrderNo());
refundModel.setOutTradeNo(order.getOrderNo());
refundModel.setRefundAmount(String.valueOf(order.getRealPrice()));
refundModel.setRefundReason("商品退款");
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
request.setBizModel(refundModel);
AlipayTradeRefundResponse response = alipayClient.execute(request);
if (response.isSuccess()) {
System.out.println("调用成功");
//退款账户
refundAccount = response.getBuyerLogonId();
} else {
System.out.println("调用失败");
}
退款回来,需要记录下退款的账号,一般是手机号或者你得邮箱号码
2、微信退款,微信退款会比较麻烦一下,需要在微信商户平台下载证书

需要这三个证书参与,才能正常调用,不让会报ERROR: api.mch.weixin.qq.com:443 failed to respond [微信退款],直接上代码
Map<String, String> websitemap = getWxpayInfo();//获得微信支付配置
//退款链接
String mchId = websitemap.get("mchid");
String appId = websitemap.get("appid");
String payKey = websitemap.get("payKey");
//随机字符串
String nonceStr = PackageUtil.getNonceStr();// 随机字符串
// 设置package订单参数
SortedMap<String, String> packageParams = new TreeMap<String, String>();
// 必须字段
// 公众平台appid
packageParams.put("appid", appId);
packageParams.put("mch_id", mchId); // 商户号id
packageParams.put("nonce_str", nonceStr);
packageParams.put("transaction_id", order.getExternalOrderNo());
packageParams.put("out_refund_no", order.getOrderNo()); // 退款订单号
//价格乘100
BigDecimal realPrice = new BigDecimal(order.getRealPrice()).multiply(new BigDecimal("100"));
packageParams.put("total_fee", String.valueOf(realPrice.intValue())); // 总金额
packageParams.put("refund_fee", String.valueOf(realPrice.intValue())); // 退款金额
// sign签名
String sign = PackageUtil.createSign(packageParams, payKey);
// 统一支付请求参数xml
String xmlPackage = XMLParse.refundPackage(packageParams, sign);
logger.info("xmlPackage" + xmlPackage);
// 预支付订单创建结果
String resultXmlStr = wxRefundLink(xmlPackage, mchId, request);
Map<String, String> resultMap = MessageUtil.parseStringXml(resultXmlStr);
logger.info("返回的resultMap" + resultMap);
// 通信标识返回状态码
String returnCode = resultMap.get("return_code");
// 返回状态消息
String returnMsg = resultMap.get("return_msg");
logger.info("returnCode为" + returnCode);
logger.info("returnMsg为" + returnMsg);
XMl解析:
/**
* 微信支付package
* @param packageParams
* @param sign
* @return
*/
public static String refundPackage(SortedMap<String, String> packageParams,String sign) {
String xmlPackage="";
try {
xmlPackage = "<xml>"
+ "<appid>"+packageParams.get("appid")+"</appid>"
+ "<mch_id>"+packageParams.get("mch_id")+"</mch_id>"
+ "<nonce_str>"+packageParams.get("nonce_str")+"</nonce_str>"
+ "<out_refund_no>"+packageParams.get("out_refund_no")+"</out_refund_no>"
+ "<total_fee>"+packageParams.get("total_fee")+"</total_fee>"
+ "<refund_fee>"+packageParams.get("refund_fee")+"</refund_fee>"
+ "<transaction_id>"+packageParams.get("transaction_id")+"</transaction_id>"
+ "<sign>"+sign+"</sign>"
+ "</xml>";
} catch (Exception e) {
e.printStackTrace();
}
return xmlPackage;
}
/**
* 微信退款链接
*
* @param postDataXML
* @param mch_id
* @param request
* @return
* @throws Exception
*/
private String wxRefundLink(String postDataXML, String mch_id, HttpServletRequest request) throws Exception {
CloseableHttpClient httpClient = null;
CloseableHttpResponse httpResponse = null;
try {
String WX_REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
//获取微信退款证书
KeyStore keyStore = getCertificate(mch_id, request);
SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(keyStore, mch_id.toCharArray()).build();
SSLConnectionSocketFactory sslf = new SSLConnectionSocketFactory(sslContext);
httpClient = HttpClients.custom().setSSLSocketFactory(sslf).build();
HttpPost httpPost = new HttpPost(WX_REFUND_URL);//退款接口
StringEntity reqEntity = new StringEntity(postDataXML);
// 设置类型
reqEntity.setContentType("application/x-www-form-urlencoded");
httpPost.setEntity(reqEntity);
String result = null;
httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
if (ObjectUtils.isNotNull(httpEntity)) {
result = EntityUtils.toString(httpEntity, "UTF8");
EntityUtils.consume(httpEntity);
}
return result;
} finally {//关流
httpClient.close();
httpResponse.close();
}
}
/**
* @param mch_id
* @description: 获取微信退款证书
*/
private KeyStore getCertificate(String mch_id, HttpServletRequest request) {
//try-with-resources 关流
try (
FileInputStream inputStream = new FileInputStream(new File(request.getSession().getServletContext().getRealPath("/cert/apiclient_cert.p12")))) {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(inputStream, mch_id.toCharArray());
return keyStore;
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
需要放到服务器上进行测试,即可退款成功,退款不能记录退款人的信息,只是会展示是零钱还是退还银行卡的信息,这个在本平台记录的时候需要记录下
本文详细介绍了在实际业务场景中,如何使用微信和支付宝的退款接口进行退款操作。包括了支付宝退款的简单流程和微信退款的复杂过程,涉及证书下载、参数设置、签名生成及请求发送等关键步骤。
3726

被折叠的 条评论
为什么被折叠?



