优化退款逻辑
parent
9a5f085369
commit
5bf3045544
|
@ -3,3 +3,6 @@ CHANGE COLUMN `channel_notify_data` `channel_notify_data` VARCHAR(2048) CHARACTE
|
|||
|
||||
ALTER TABLE `ruoyi-vue-pro`.`pay_refund`
|
||||
CHANGE COLUMN `req_no` `req_no` VARCHAR(64) NULL COMMENT '退款单请求号' ;
|
||||
|
||||
ALTER TABLE `ruoyi-vue-pro`.`pay_refund`
|
||||
DROP COLUMN `req_no`;
|
||||
|
|
|
@ -607,7 +607,7 @@ CREATE TABLE `pay_order_extension` (
|
|||
`user_ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户 IP',
|
||||
`status` tinyint NOT NULL COMMENT '支付状态',
|
||||
`channel_extras` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '支付渠道的额外参数',
|
||||
`channel_notify_data` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '支付渠道异步通知的内容',
|
||||
`channel_notify_data` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '支付渠道异步通知的内容',
|
||||
`creator` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updater` varchar(64) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者',
|
||||
|
@ -720,7 +720,6 @@ COMMIT;
|
|||
DROP TABLE IF EXISTS `pay_refund`;
|
||||
CREATE TABLE `pay_refund` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '支付退款编号',
|
||||
`req_no` varchar(64) NOT NULL COMMENT '退款单请求号',
|
||||
`merchant_id` bigint NOT NULL COMMENT '商户编号',
|
||||
`app_id` bigint NOT NULL COMMENT '应用编号',
|
||||
`channel_id` bigint NOT NULL COMMENT '渠道编号',
|
||||
|
|
|
@ -43,7 +43,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
|
|||
public void testGetRefundPage() {
|
||||
// mock 数据
|
||||
PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到
|
||||
o.setReqNo("RF0000001");
|
||||
o.setMerchantId(1L);
|
||||
o.setAppId(1L);
|
||||
o.setChannelId(1L);
|
||||
|
@ -115,7 +114,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
|
|||
public void testGetRefundList() {
|
||||
// mock 数据
|
||||
PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到
|
||||
o.setReqNo("RF0000001");
|
||||
o.setMerchantId(1L);
|
||||
o.setAppId(1L);
|
||||
o.setChannelId(1L);
|
||||
|
|
|
@ -36,20 +36,6 @@ public class PayRefundDO extends BaseDO {
|
|||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 中的 out_refund_no
|
||||
* https://opendocs.alipay.com/apis alipay.trade.refund 中的 out_request_no
|
||||
* 退款请求号。
|
||||
* 标识一次退款请求,需要保证在交易号下唯一,如需部分退款,则此参数必传。
|
||||
* 注:针对同一次退款请求,如果调用接口失败或异常了,重试时需要保证退款请求号不能变更,
|
||||
* 防止该笔交易重复退款。支付宝会保证同样的退款请求号多次请求只会退一次。
|
||||
* 退款单请求号,根据规则生成
|
||||
* 例如说,R202109181134287570000
|
||||
* 废弃,使用 merchantRefundNo 做退款请求号
|
||||
*/
|
||||
@Deprecated
|
||||
private String reqNo;
|
||||
|
||||
/**
|
||||
* 商户编号
|
||||
*
|
||||
|
|
|
@ -6,6 +6,10 @@ import lombok.Data;
|
|||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.DecimalMin;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 退款申请单 Request DTO
|
||||
*/
|
||||
|
@ -16,15 +20,17 @@ import lombok.experimental.Accessors;
|
|||
@AllArgsConstructor
|
||||
public class PayRefundReqDTO {
|
||||
|
||||
// TODO @jason:增加下 validation 注解哈
|
||||
/**
|
||||
* 支付订单编号
|
||||
*/
|
||||
@NotNull(message = "支付订单编号不能为空")
|
||||
private Long payOrderId;
|
||||
|
||||
/**
|
||||
* 退款金额
|
||||
*/
|
||||
@NotNull(message = "退款金额不能为空")
|
||||
@DecimalMin(value = "0", inclusive = false, message = "退款金额必须大于零")
|
||||
private Long amount;
|
||||
|
||||
/**
|
||||
|
@ -35,8 +41,8 @@ public class PayRefundReqDTO {
|
|||
/**
|
||||
* 商户退款订单号
|
||||
*/
|
||||
// TODO @jason:merchantRefundNo=》merchantRefundId,保持和 PayOrder 的 merchantOrderId 一致哈
|
||||
private String merchantRefundNo;
|
||||
@NotEmpty(message = "商户退款订单号不能为空")
|
||||
private String merchantRefundId;
|
||||
|
||||
/**
|
||||
* 用户 IP
|
||||
|
|
|
@ -16,24 +16,6 @@ import lombok.experimental.Accessors;
|
|||
@AllArgsConstructor
|
||||
public class PayRefundRespDTO {
|
||||
|
||||
/**
|
||||
* 渠道返回结果
|
||||
* 退款处理中和退款成功 返回 1
|
||||
* 失败和其他情况 返回 2
|
||||
*/
|
||||
// TODO @jason:这个 result,可以使用 CommonResult 里呢
|
||||
private Integer channelReturnResult;
|
||||
|
||||
/**
|
||||
* 渠道返回 code
|
||||
*/
|
||||
private String channelReturnCode;
|
||||
|
||||
/**
|
||||
* 渠道返回消息
|
||||
*/
|
||||
private String channelReturnMsg;
|
||||
|
||||
/**
|
||||
* 支付退款单编号,自增
|
||||
*/
|
||||
|
|
|
@ -23,11 +23,11 @@ import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayRefundReqDT
|
|||
import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayRefundRespDTO;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.PayClient;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.dto.PayRefundNotifyDTO;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.dto.PayRefundUnifiedReqDTO;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.dto.PayRefundUnifiedRespDTO;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRefundRespEnum;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -88,11 +88,8 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService {
|
|||
if (Objects.equals(req.getAmount(), order.getAmount())) {
|
||||
refundType = PayRefundTypeEnum.ALL;
|
||||
}
|
||||
|
||||
PayOrderExtensionDO orderExtensionDO = payOrderExtensionCoreMapper.selectById(order.getSuccessExtensionId());
|
||||
PayRefundDO payRefundDO = payRefundCoreMapper.selectByTradeNoAndMerchantRefundNo(orderExtensionDO.getNo(), req.getMerchantRefundNo());
|
||||
// 构造渠道的统一的退款请求参数
|
||||
PayRefundUnifiedReqDTO unifiedReqDTO = new PayRefundUnifiedReqDTO();
|
||||
PayRefundDO payRefundDO = payRefundCoreMapper.selectByTradeNoAndMerchantRefundNo(orderExtensionDO.getNo(), req.getMerchantRefundId());
|
||||
if(Objects.nonNull(payRefundDO)){
|
||||
// 退款订单已经提交过。
|
||||
//TODO 校验相同退款单的金额
|
||||
|
@ -101,19 +98,10 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService {
|
|||
|| Objects.equals(PayRefundStatusEnum.CLOSE.getStatus(), payRefundDO.getStatus())) {
|
||||
//已成功退款
|
||||
throw exception(PAY_REFUND_SUCCEED);
|
||||
} else{
|
||||
// TODO @jason:这里不用 else,简洁一些
|
||||
// 保证商户退款单不变,重复向渠道发起退款。渠道保持幂等
|
||||
unifiedReqDTO.setUserIp(req.getUserIp())
|
||||
.setAmount(payRefundDO.getRefundAmount())
|
||||
.setChannelOrderNo(payRefundDO.getChannelOrderNo())
|
||||
.setPayTradeNo(payRefundDO.getTradeNo())
|
||||
.setRefundReqNo(payRefundDO.getMerchantRefundNo())
|
||||
.setReason(payRefundDO.getReason());
|
||||
}
|
||||
}else{
|
||||
// 新生成退款单。 退款单入库 退款单状态:生成
|
||||
// TODO @jason:封装一个小方法。插入退款单
|
||||
//可以重复提交,保证 退款请求号 一致,由渠道保证幂等
|
||||
}else {
|
||||
//成功,插入退款单 状态为生成.没有和渠道交互
|
||||
payRefundDO = PayRefundDO.builder().channelOrderNo(order.getChannelOrderNo())
|
||||
.appId(order.getAppId())
|
||||
.channelOrderNo(order.getChannelOrderNo())
|
||||
|
@ -121,7 +109,7 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService {
|
|||
.channelId(order.getChannelId())
|
||||
.merchantId(order.getMerchantId())
|
||||
.orderId(order.getId())
|
||||
.merchantRefundNo(req.getMerchantRefundNo())
|
||||
.merchantRefundNo(req.getMerchantRefundId())
|
||||
.notifyUrl(app.getRefundNotifyUrl())
|
||||
.payAmount(order.getAmount())
|
||||
.refundAmount(req.getAmount())
|
||||
|
@ -134,38 +122,21 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService {
|
|||
.type(refundType.getStatus())
|
||||
.build();
|
||||
payRefundCoreMapper.insert(payRefundDO);
|
||||
// TODO @jason:这块的逻辑,和已存在的这块,貌似是统一的?
|
||||
}
|
||||
PayRefundUnifiedReqDTO unifiedReqDTO = new PayRefundUnifiedReqDTO();
|
||||
unifiedReqDTO.setUserIp(req.getUserIp())
|
||||
.setAmount(payRefundDO.getRefundAmount())
|
||||
.setChannelOrderNo(payRefundDO.getChannelOrderNo())
|
||||
.setPayTradeNo(payRefundDO.getTradeNo())
|
||||
.setRefundReqNo(payRefundDO.getMerchantRefundNo())
|
||||
.setAmount(req.getAmount())
|
||||
.setChannelOrderNo(order.getChannelOrderNo())
|
||||
.setPayTradeNo(orderExtensionDO.getNo())
|
||||
.setMerchantRefundId(req.getMerchantRefundId())
|
||||
.setReason(req.getReason());
|
||||
}
|
||||
// 向渠道发起退款申请
|
||||
PayRefundUnifiedRespDTO refundUnifiedRespDTO = client.unifiedRefund(unifiedReqDTO);
|
||||
// 构造退款申请返回对象
|
||||
PayRefundRespDTO respDTO = new PayRefundRespDTO();
|
||||
if (refundUnifiedRespDTO.getChannelResp() == PayChannelRefundRespEnum.SUCCESS
|
||||
||refundUnifiedRespDTO.getChannelResp() == PayChannelRefundRespEnum.PROCESSING) {
|
||||
// 成功处理,在退款通知中处理, 这里不处理
|
||||
respDTO.setChannelReturnResult(PayChannelRefundRespEnum.SUCCESS.getStatus());
|
||||
respDTO.setRefundId(payRefundDO.getId());
|
||||
}else {
|
||||
// 失败返回错误给前端,可以重新发起退款,保证退款请求号(这里是商户退款单号), 避免重复退款。
|
||||
// TODO @jason:失败的话,是不是可以跑出 ServiceException 业务异常。这样就是成功返回 refundId,失败业务异常
|
||||
respDTO.setChannelReturnResult(PayChannelRefundRespEnum.FAILURE.getStatus());
|
||||
// 更新退款单状态
|
||||
PayRefundDO updatePayRefund = new PayRefundDO();
|
||||
updatePayRefund.setId(payRefundDO.getId())
|
||||
.setChannelErrorMsg(refundUnifiedRespDTO.getChannelMsg())
|
||||
.setChannelErrorCode(refundUnifiedRespDTO.getChannelCode())
|
||||
.setStatus(PayRefundStatusEnum.FAILURE.getStatus());
|
||||
payRefundCoreMapper.updateById(updatePayRefund);
|
||||
}
|
||||
respDTO.setChannelReturnCode(refundUnifiedRespDTO.getChannelCode())
|
||||
.setChannelReturnMsg(refundUnifiedRespDTO.getChannelMsg());
|
||||
return respDTO;
|
||||
PayCommonResult<PayRefundUnifiedRespDTO> refundUnifiedResult = client.unifiedRefund(unifiedReqDTO);
|
||||
//检查是否失败,失败抛出业务异常。
|
||||
//TODO 渠道的异常记录
|
||||
refundUnifiedResult.checkError();
|
||||
//成功在 退款回调中处理
|
||||
return PayRefundRespDTO.builder().refundId(payRefundDO.getId()).build();
|
||||
}
|
||||
|
||||
|
||||
|
@ -187,7 +158,7 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService {
|
|||
payRefundSuccess(refundNotify);
|
||||
} else {
|
||||
//TODO 支付异常, 支付宝似乎没有支付异常的通知。
|
||||
// TODO @jason:那这里可以考虑打个 error logger
|
||||
// TODO @jason:那这里可以考虑打个 error logger @芋艿 微信是否存在支付异常通知
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,22 +170,22 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService {
|
|||
throw exception(PAY_REFUND_NOT_FOUND);
|
||||
}
|
||||
|
||||
// 计算订单的状态。如果全部退款,则订单处于关闭。TODO @jason:建议这里按照金额来判断,因为可能退款多次
|
||||
Integer type = refundDO.getType();
|
||||
PayOrderStatusEnum orderStatus = PayOrderStatusEnum.SUCCESS;
|
||||
if (PayRefundTypeEnum.ALL.getStatus().equals(type)){
|
||||
orderStatus = PayOrderStatusEnum.CLOSED;
|
||||
}
|
||||
// 需更新已退金额
|
||||
// 得到已退金额
|
||||
PayOrderDO payOrderDO = payOrderCoreMapper.selectById(refundDO.getOrderId());
|
||||
Long refundedAmount = payOrderDO.getRefundAmount();
|
||||
|
||||
PayOrderStatusEnum orderStatus = PayOrderStatusEnum.SUCCESS;
|
||||
if(Objects.equals(payOrderDO.getAmount(), refundedAmount+ refundDO.getRefundAmount())){
|
||||
//支付金额 = 已退金额 + 本次退款金额。
|
||||
orderStatus = PayOrderStatusEnum.CLOSED;
|
||||
}
|
||||
// 更新支付订单
|
||||
PayOrderDO updateOrderDO = new PayOrderDO();
|
||||
updateOrderDO.setId(refundDO.getOrderId())
|
||||
.setRefundAmount(refundedAmount + refundDO.getRefundAmount())
|
||||
.setStatus(orderStatus.getStatus())
|
||||
.setRefundTimes(payOrderDO.getRefundTimes() + 1)
|
||||
.setRefundStatus(type);
|
||||
.setRefundStatus(refundDO.getType());
|
||||
payOrderCoreMapper.updateById(updateOrderDO);
|
||||
|
||||
// 更新退款订单
|
||||
|
|
|
@ -39,7 +39,7 @@ public interface PayClient {
|
|||
* @param reqDTO 统一退款请求信息
|
||||
* @return 各支付渠道的统一返回结果
|
||||
*/
|
||||
PayRefundUnifiedRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO);
|
||||
PayCommonResult<PayRefundUnifiedRespDTO> unifiedRefund(PayRefundUnifiedReqDTO reqDTO);
|
||||
|
||||
/**
|
||||
* 解析支付退款通知数据
|
||||
|
|
|
@ -43,7 +43,6 @@ public class PayRefundUnifiedReqDTO {
|
|||
*/
|
||||
private String payTradeNo;
|
||||
|
||||
// TODO @jason:这个字段,要不就使用 merchantRefundId,更直接
|
||||
/**
|
||||
* https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 中的 out_refund_no
|
||||
* https://opendocs.alipay.com/apis alipay.trade.refund 中的 out_trade_no
|
||||
|
@ -51,7 +50,7 @@ public class PayRefundUnifiedReqDTO {
|
|||
* 使用 商户的退款单号。{PayRefundDO 字段 merchantRefundNo}
|
||||
*/
|
||||
@NotEmpty(message = "退款请求单号")
|
||||
private String refundReqNo;
|
||||
private String merchantRefundId;
|
||||
|
||||
/**
|
||||
* 退款原因
|
||||
|
|
|
@ -18,22 +18,8 @@ import lombok.experimental.Accessors;
|
|||
@Data
|
||||
public class PayRefundUnifiedRespDTO {
|
||||
|
||||
// TODO @jason:可以合并下。退款处理中、成功,都是成功;其它就业务失败。这样,可以复用 PayCommonResult;这个 RespDTO 可以返回渠道的退款编号
|
||||
/**
|
||||
* 渠道的退款结果
|
||||
* 渠道退款单编号
|
||||
*/
|
||||
private PayChannelRefundRespEnum channelResp;
|
||||
|
||||
// TODO @json:channelReturnCode 和 channelReturnMsg 放到 PayCommonResult 里噶
|
||||
/**
|
||||
* 渠道返回码
|
||||
*/
|
||||
private String channelCode;
|
||||
|
||||
/**
|
||||
* 渠道返回信息
|
||||
*/
|
||||
private String channelMsg;
|
||||
|
||||
//TODO 退款资金渠 ???
|
||||
private String channelRefundId;
|
||||
}
|
||||
|
|
|
@ -103,19 +103,19 @@ public abstract class AbstractPayClient<Config extends PayClientConfig> implemen
|
|||
|
||||
|
||||
@Override
|
||||
public PayRefundUnifiedRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
|
||||
PayRefundUnifiedRespDTO resp;
|
||||
public PayCommonResult<PayRefundUnifiedRespDTO> unifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
|
||||
PayCommonResult<PayRefundUnifiedRespDTO> resp;
|
||||
try {
|
||||
resp = doUnifiedRefund(reqDTO);
|
||||
} catch (Throwable ex) {
|
||||
// 记录异常日志
|
||||
log.error("[unifiedRefund][request({}) 发起退款失败]", toJsonString(reqDTO), ex);
|
||||
throw exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR);
|
||||
resp = PayCommonResult.error(ex);
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
protected abstract PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable;
|
||||
protected abstract PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable;
|
||||
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
|||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.AbstractPayCodeMapping;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.dto.*;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRefundRespEnum;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum;
|
||||
import com.alipay.api.AlipayApiException;
|
||||
import com.alipay.api.AlipayConfig;
|
||||
|
@ -100,39 +100,32 @@ public abstract class AbstractAlipayClient extends AbstractPayClient<AlipayPayCl
|
|||
* @return 退款请求 Response
|
||||
*/
|
||||
@Override
|
||||
protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
|
||||
protected PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
|
||||
AlipayTradeRefundModel model=new AlipayTradeRefundModel();
|
||||
model.setTradeNo(reqDTO.getChannelOrderNo());
|
||||
model.setOutTradeNo(reqDTO.getPayTradeNo());
|
||||
model.setOutRequestNo(reqDTO.getRefundReqNo());
|
||||
model.setOutRequestNo(reqDTO.getMerchantRefundId());
|
||||
model.setRefundAmount(calculateAmount(reqDTO.getAmount()).toString());
|
||||
model.setRefundReason(reqDTO.getReason());
|
||||
AlipayTradeRefundRequest refundRequest = new AlipayTradeRefundRequest();
|
||||
refundRequest.setBizModel(model);
|
||||
PayRefundUnifiedRespDTO respDTO = new PayRefundUnifiedRespDTO();
|
||||
try {
|
||||
AlipayTradeRefundResponse response = client.execute(refundRequest);
|
||||
log.info("[doUnifiedRefund][response({}) 发起退款 渠道返回", toJsonString(response));
|
||||
if (response.isSuccess()) {
|
||||
//退款成功,更新为PROCESSING_NOTIFY, 而不是 SYNC_SUCCESS 通过支付宝回调接口处理。退款导致触发的异步通知,
|
||||
//退款导致触发的异步通知是发送到支付接口中设置的notify_url
|
||||
//TODO 沙箱环境 返回 的tradeNo(渠道退款单号) 和 订单的tradNo 是一个值,是不是理解不对?
|
||||
respDTO.setChannelResp(PayChannelRefundRespEnum.SUCCESS)
|
||||
.setChannelCode(response.getCode())
|
||||
.setChannelMsg(response.getMsg());
|
||||
//支付宝不返回退款单号,设置为空
|
||||
PayRefundUnifiedRespDTO respDTO = new PayRefundUnifiedRespDTO();
|
||||
respDTO.setChannelRefundId("");
|
||||
return PayCommonResult.build(response.getCode(), response.getMsg(), respDTO, codeMapping);
|
||||
}else{
|
||||
respDTO.setChannelResp(PayChannelRefundRespEnum.FAILURE)
|
||||
.setChannelCode(response.getSubCode())
|
||||
.setChannelMsg(response.getSubMsg());
|
||||
//失败。需要抛出异常
|
||||
return PayCommonResult.build(response.getCode(), response.getMsg(), null, codeMapping);
|
||||
}
|
||||
return respDTO;
|
||||
} catch (AlipayApiException e) {
|
||||
//TODO 记录异常日志
|
||||
log.error("[doUnifiedRefund][request({}) 发起退款失败,网络读超时,退款状态未知]", toJsonString(reqDTO), e);
|
||||
respDTO.setChannelResp(PayChannelRefundRespEnum.FAILURE)
|
||||
.setChannelCode(e.getErrCode())
|
||||
.setChannelMsg(e.getErrMsg());
|
||||
return respDTO;
|
||||
return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> {
|
|||
|
||||
|
||||
@Override
|
||||
protected PayRefundUnifiedRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
|
||||
protected PayCommonResult<PayRefundUnifiedRespDTO> doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
|
||||
//TODO 需要实现
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@ public class PayRefundController {
|
|||
PayRefundReqDTO req = PayRefundConvert.INSTANCE.convert(reqVO);
|
||||
req.setUserIp(getClientIP());
|
||||
//TODO 测试暂时模拟生成商户退款订单
|
||||
if(StrUtil.isEmpty(reqVO.getMerchantRefundNo())) {
|
||||
req.setMerchantRefundNo(PaySeqUtils.genMerchantRefundNo());
|
||||
if(StrUtil.isEmpty(reqVO.getMerchantRefundId())) {
|
||||
req.setMerchantRefundId(PaySeqUtils.genMerchantRefundNo());
|
||||
}
|
||||
return CommonResult.success( PayRefundConvert.INSTANCE.convert(payRefundCoreService.submitRefundOrder(req)));
|
||||
}
|
||||
|
|
|
@ -29,6 +29,6 @@ public class PayRefundReqVO {
|
|||
@ApiModelProperty(value = "商户退款订单号", required = true, example = "MR202111180000000001")
|
||||
//TODO 测试暂时模拟生成
|
||||
//@NotEmpty(message = "商户退款订单号")
|
||||
private String merchantRefundNo;
|
||||
private String merchantRefundId;
|
||||
|
||||
}
|
||||
|
|
|
@ -15,23 +15,6 @@ import lombok.experimental.Accessors;
|
|||
@AllArgsConstructor
|
||||
public class PayRefundRespVO {
|
||||
|
||||
/**
|
||||
* 渠道返回结果
|
||||
* 退款处理中和退款成功 返回 1
|
||||
* 失败和其他情况 返回 2
|
||||
*/
|
||||
private Integer channelReturnResult;
|
||||
|
||||
/**
|
||||
* 渠道返回code
|
||||
*/
|
||||
private String channelReturnCode;
|
||||
|
||||
/**
|
||||
* 渠道返回消息
|
||||
*/
|
||||
private String channelReturnMsg;
|
||||
|
||||
/**
|
||||
* 支付退款单编号, 自增
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue