微信退款
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user