微信退款

This commit is contained in:
gong
2026-01-14 13:54:37 +08:00
parent f12e7f9802
commit e341630e82
4 changed files with 202 additions and 13 deletions

View File

@@ -1,6 +1,7 @@
package com.czg;
import com.czg.dto.req.PayParamsDto;
import com.czg.dto.req.RefundParamsDto;
import com.czg.exception.CzgException;
import com.czg.third.alipay.AlipayIsvPayManager;
import com.czg.third.wechat.WechatPayManager;
@@ -49,6 +50,32 @@ public class PayManager {
}
}
/**
* 查询订单状态
*/
public static Map<String, Object> queryOrderStatus(String platform, String orderNo, String subMerchantId) {
if (PayCst.Platform.WECHAT.equals(platform)) {
return WechatPayManager.queryOrder(null, orderNo, subMerchantId);
} else if (PayCst.Platform.ALIPAY.equals(platform)) {
return AlipayIsvPayManager.queryOrder(null, orderNo, subMerchantId);
} else {
throw new CzgException("不支持的支付平台");
}
}
/**
* 退款
*/
public static Map<String, Object> refund(String platform, RefundParamsDto paramsDto) {
if (PayCst.Platform.WECHAT.equals(platform)) {
return WechatPayManager.refundOrder(null, paramsDto);
} else if (PayCst.Platform.ALIPAY.equals(platform)) {
return AlipayIsvPayManager.refundOrder(null, paramsDto);
} else {
throw new CzgException("不支持的支付平台");
}
}
public static void main(String[] args) {
// jsapiPay(new PayParamsDto()
// .setPlatform(PayCst.Platform.ALIPAY)

View File

@@ -0,0 +1,69 @@
package com.czg.dto.req;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 退款参数
* @author yjjie
* @date 2026/1/14 11:37
*/
@Data
@Accessors(chain = true)
public class RefundParamsDto {
/**
* 【必填】
* 平台
* {@link com.czg.PayCst.Platform}
*/
private String platform;
/**
* 【必填】
* 订单号
*/
private String orderNo;
/**
* 【必填】
* 退款单号
*/
private String refundOrderNo;
/**
* 【必填】
* 退款金额
*/
private Long refundAmount;
/**
* 【必填】
* 订单原金额
*/
private Long orderAmount;
/**
* 【必填】
* 退款原因
*/
private String refundReason;
/**
* 【必填】
* 退款回调地址
*/
private String refundNotifyUrl;
/**
* 【选填】
* 微信商户号
*/
private String merchantId;
/**
* 【选填】
* 支付宝授权信息
*/
private String alipayAuthInfo;
}

View File

@@ -9,9 +9,9 @@ import com.alipay.v3.model.ExtendParams;
import com.alipay.v3.util.model.CustomizedParams;
import com.czg.PayCst;
import com.czg.dto.req.PayParamsDto;
import com.czg.dto.req.RefundParamsDto;
import com.czg.exception.CzgException;
import com.czg.third.alipay.dto.config.AlipayConfigDto;
import com.czg.third.wechat.dto.config.WechatPayConfigDto;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
@@ -27,6 +27,7 @@ public class AlipayIsvPayManager {
/**
* H5支付
*
* @param configDto 配置
* @param paramsDto 参数
*/
@@ -64,6 +65,7 @@ public class AlipayIsvPayManager {
/**
* 条码支付
*
* @param configDto 配置
* @param paramsDto 参数
*/
@@ -84,7 +86,11 @@ public class AlipayIsvPayManager {
}
public static Map<String, Object> queryOrder(AlipayConfigDto configDto, String orderNo, String subMerchantId) {
return new HashMap<>();
return new HashMap<>();
}
public static Map<String, Object> refundOrder(AlipayConfigDto configDto, RefundParamsDto paramsDto) {
return new HashMap<>();
}
/**

View File

@@ -4,13 +4,16 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.czg.PayCst;
import com.czg.dto.req.PayParamsDto;
import com.czg.dto.req.RefundParamsDto;
import com.czg.exception.CzgException;
import com.czg.third.wechat.dto.config.WechatPayConfigDto;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.cipher.Signer;
import com.wechat.pay.java.core.util.NonceUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.apache.bcel.generic.RET;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
@@ -99,6 +102,7 @@ public class WechatPayManager {
/**
* 条码支付
* 用户付款码规则18位纯数字前缀以10、11、12、13、14、15开头
*
* @param configDto 配置
* @param paramsDto 参数
*/
@@ -197,16 +201,17 @@ public class WechatPayManager {
/**
* 查询订单
* @param configDto 配置
* @param orderNo 订单号
*
* @param configDto 配置
* @param orderNo 订单号
* @param subMerchantId 子商户号
* SUCCESS支付成功
* REFUND转入退款
* NOTPAY未支付
* CLOSED已关闭
* REVOKED已撤销仅付款码支付会返回
* USERPAYING用户支付中仅付款码支付会返回
* PAYERROR支付失败仅付款码支付会返回
* SUCCESS支付成功
* REFUND转入退款
* NOTPAY未支付
* CLOSED已关闭
* REVOKED已撤销仅付款码支付会返回
* USERPAYING用户支付中仅付款码支付会返回
* PAYERROR支付失败仅付款码支付会返回
*/
public static Map<String, Object> queryOrder(WechatPayConfigDto configDto, String orderNo, String subMerchantId) {
try {
@@ -242,8 +247,81 @@ public class WechatPayManager {
}
}
/**
* 退款
*
* @param configDto 配置
* @param paramsDto 参数
* SUCCESS: 退款成功
* CLOSED: 退款关闭
* PROCESSING: 退款处理中
* ABNORMAL: 退款异常,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,可前往服务商平台-交易中心,手动处理此笔退款
*/
public static Map<String, Object> refundOrder(WechatPayConfigDto configDto, RefundParamsDto paramsDto) {
try {
if (configDto == null) {
configDto = WechatPayConfigDto.getDefaultConfig();
}
JSONObject refundParam = new JSONObject();
refundParam.put("sub_mchid", paramsDto.getMerchantId());
refundParam.put("out_trade_no", paramsDto.getOrderNo());
refundParam.put("out_refund_no", paramsDto.getRefundOrderNo());
refundParam.put("reason", paramsDto.getRefundReason());
refundParam.put("notify_url", paramsDto.getRefundNotifyUrl());
JSONObject amount = new JSONObject();
amount.put("total", paramsDto.getOrderAmount());
amount.put("refund", paramsDto.getRefundAmount());
amount.put("currency", "CNY");
refundParam.put("amount", amount);
String resp = WechatReqUtils.postReq(configDto, "/v3/refund/domestic/refunds", refundParam.toJSONString());
log.info("微信退款,订单号:{} 响应:{}", paramsDto.getOrderNo(), resp);
JSONObject object = JSONObject.parseObject(resp);
JSONObject res = new JSONObject();
res.put("mchRefundNo", object.getString("out_refund_no"));
res.put("refundOrderId", object.getString("refund_id"));
res.put("oriPayOrderId", object.getString("out_trade_no"));
res.put("mercNo", paramsDto.getMerchantId());
res.put("refundReason", paramsDto.getRefundReason());
res.put("payType", PayCst.Platform.WECHAT);
res.put("refundTime", object.getString("success_time"));
switch (object.getString("status")) {
case "SUCCESS":
res.put("status", "SUCCESS");
break;
case "CLOSED":
res.put("status", "CLOSED");
break;
case "PROCESSING":
res.put("status", "ING");
break;
case "ABNORMAL":
res.put("status", "INIT");
break;
default:
res.put("status", "FAIL");
break;
}
JSONObject resAmount = object.getJSONObject("amount");
if (resAmount != null) {
res.put("refundAmt", resAmount.getLong("refund"));
res.put("oriAmount", resAmount.getLong("total"));
}
return res;
} catch (Exception e) {
log.error("微信退款异常: orderNo = {}, e = {}", paramsDto.getOrderNo(), e.getMessage());
throw new CzgException("微信退款异常");
}
}
/**
* 将String转换为InputStream
*
* @param str 待转换的字符串
* @return 转换后的InputStream
*/
@@ -288,7 +366,16 @@ public class WechatPayManager {
// .setClientIp("127.0.0.1")
// .setBarCode("130013153082460022"));
Map<String, Object> sss1 = queryOrder(null, "sa101293120sss1", "1738216504");
System.out.println(sss1);
// Map<String, Object> sss1 = queryOrder(null, "sa101293120sss1", "1738216504");
// System.out.println(sss1);
refundOrder(null, new RefundParamsDto()
.setMerchantId("1738216504")
.setOrderNo("sa101293120sss1")
.setRefundOrderNo("sa101293120sss1")
.setOrderAmount(1L)
.setRefundAmount(1L)
.setRefundReason("测试")
.setRefundNotifyUrl("https://www.baidu.com"));
}
}