用户退款回调问题修复

This commit is contained in:
yanglei 2025-12-18 11:13:37 +08:00
parent 7a6e27980a
commit e9198ae852
6 changed files with 102 additions and 15 deletions

View File

@ -6,14 +6,14 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 微信支付通知回调接口

View File

@ -3,6 +3,7 @@ package com.cdzy.payment.service;
import com.cdzy.payment.model.entity.EbikeRefund;
import com.mybatisflex.core.service.IService;
import com.wechat.pay.java.service.refund.model.Refund;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import java.util.List;
@ -31,4 +32,12 @@ public interface EbikeRefundService extends IService<EbikeRefund> {
*/
Boolean updateRefundStatus(Refund refund);
/**
* 更新退款回调通知
*
* @param refund 退款回调通知
* @return 更新成功返回true否则返回false
*/
Boolean updateRefundCallbackStatus(RefundNotification refund);
}

View File

@ -5,8 +5,8 @@ import com.ebike.feign.model.dto.FeignEbikeRefundDto;
import com.fasterxml.jackson.databind.JsonNode;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.model.Refund;
import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequest;
/**
* 微信支付服务类JSAPI支付小程序

View File

@ -9,6 +9,7 @@ import com.cdzy.payment.utils.StringUtils;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.wechat.pay.java.service.refund.model.Refund;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import com.wechat.pay.java.service.refund.model.Status;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
@ -64,6 +65,9 @@ public class EbikeRefundServiceImpl extends ServiceImpl<EbikeRefundMapper, Ebike
@Override
public Boolean updateRefundStatus(Refund refund) {
if (refund == null) {
return false;
}
EbikeRefund ebikeRefund = getByRefundOrderId(refund.getOutRefundNo());
ebikeRefund.setRefundStatus(refund.getStatus().ordinal());
if (Status.SUCCESS.equals(refund.getStatus())) {
@ -84,20 +88,93 @@ public class EbikeRefundServiceImpl extends ServiceImpl<EbikeRefundMapper, Ebike
return updateById(ebikeRefund);
}
@Override
public Boolean updateRefundCallbackStatus(RefundNotification refundNotification) {
if (refundNotification == null) {
return false;
}
EbikeRefund ebikeRefund = getByRefundOrderId(refundNotification.getOutRefundNo());
ebikeRefund.setRefundStatus(refundNotification.getRefundStatus().ordinal());
if (Status.SUCCESS.equals(refundNotification.getRefundStatus())) {
String refundTime = refundNotification.getSuccessTime();
ebikeRefund.setRefundTime(StringUtils.toLocalDatetime(refundTime));
// 转换为BigDecimal,避免精度损失
BigDecimal refundAmount = calculateRefundCallbackAmount(refundNotification);
ebikeRefund.setRefund(refundAmount);
}
Long refundOrderId = Long.valueOf(refundNotification.getOutTradeNo());
log.info("退款回调订单Id:{}, 退款回调订单状态:{}", refundOrderId, refundNotification.getRefundStatus().ordinal());
Long orderId = queryOrderId(refundOrderId);
// 更新订单退款状态
switch (refundNotification.getRefundStatus()) {
case PROCESSING, CLOSED -> ebikeOrderService.refund(orderId);
case SUCCESS -> ebikeOrderService.doneRefund(orderId);
case ABNORMAL -> ebikeOrderService.failRefund(orderId);
}
return updateById(ebikeRefund);
}
private BigDecimal calculateRefundAmount(Refund refund) {
if (refund == null || refund.getAmount() == null
|| refund.getAmount().getRefund() == null) {
log.warn("Refund amount information is incomplete");
private BigDecimal calculateRefundAmountInternal(Long refundInFen, String outRefundNo) {
if (refundInFen == null) {
log.warn("Refund amount is null for refund: {}", outRefundNo);
return BigDecimal.ZERO;
}
try {
BigDecimal refundInFen = BigDecimal.valueOf(refund.getAmount().getRefund());
return refundInFen.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
BigDecimal amount = BigDecimal.valueOf(refundInFen);
return amount.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
} catch (Exception e) {
log.error("Error calculating refund amount for refund: {}", refund.getOutRefundNo(), e);
log.error("Error calculating refund amount for refund: {}", outRefundNo, e);
return BigDecimal.ZERO;
}
}
/**
* 退款回调金额计算
*/
private BigDecimal calculateRefundCallbackAmount(RefundNotification refund) {
if (refund == null || refund.getAmount() == null) {
log.warn("RefundNotification amount information is incomplete");
return BigDecimal.ZERO;
}
Long refundInFen = refund.getAmount().getRefund();
return calculateRefundAmountInternal(refundInFen, refund.getOutRefundNo());
}
/**
* 退款金额计算
*/
private BigDecimal calculateRefundAmount(Refund refund) {
if (refund == null || refund.getAmount() == null) {
log.warn("Refund amount information is incomplete");
return BigDecimal.ZERO;
}
Long refundInFen = refund.getAmount().getRefund();
return calculateRefundAmountInternal(refundInFen, refund.getOutRefundNo());
}
/**
* 查询订单号
*
* @param refundOrderId 根据退款回调退款订单号查询订单号
*/
private Long queryOrderId(Long refundOrderId) {
if (refundOrderId == null) {
log.warn("退款订单ID为空无法查询主订单ID");
return null;
}
//查询退款中且状态为2的订单
QueryWrapper queryWrapper = QueryWrapper.create()
.where(EBIKE_REFUND.REFUND_ORDER_ID.eq(refundOrderId))
.where(EBIKE_REFUND.REFUND_STATUS.eq(RefundStatus.PROCESSED));
EbikeRefund ebikeRefund = this.mapper.selectOneByQuery(queryWrapper);
if (ebikeRefund == null) {
log.warn("未找到状态为'退款中'的退款记录退款单ID: {}", refundOrderId);
return null;
}
return ebikeRefund.getOrderId();
}
}

View File

@ -33,10 +33,10 @@ import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
@ -543,9 +543,9 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService {
// 验签并解析通知
NotificationParser parser = new NotificationParser((NotificationConfig) certificateConfig);
// 解析解密后的通知
Refund refund = parser.parse(requestParam, Refund.class);
RefundNotification refund = parser.parse(requestParam, RefundNotification.class);
// 更新状态
ebikeRefundService.updateRefundStatus(refund);
ebikeRefundService.updateRefundCallbackStatus(refund);
// 处理成功
result.setSuccess(true);
result.setMessage("success");

View File

@ -1,7 +1,8 @@
package com.cdzy.payment.utils;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;