8.16 解决业务bug 营销订单可能未付款,这种情况下退单也调用了支付宝退单接口

This commit is contained in:
zhangsan 2025-08-16 12:25:40 +08:00
parent 7fc2af3327
commit e00c94f982
2 changed files with 58 additions and 66 deletions

View File

@ -147,79 +147,31 @@ public class OrderService extends AbstractOrderService{
}
/**
* 预备退单
* 公共退款逻辑根据订单状态决定退单方式
*/
@Override
public boolean preRefundOrder(String userId, String orderId) {
// 1. 查单
OrderEntity orderEntity = repository.queryOrderByUserIdAndOrderId(userId, orderId);
if (orderEntity == null) {
log.warn("退单失败,订单不存在或不属于该用户 userId:{} orderId:{}", userId, orderId);
return false;
}
private boolean doRefund(OrderEntity orderEntity) {
String userId = orderEntity.getUserId();
String orderId = orderEntity.getOrderId();
String status = orderEntity.getOrderStatusVO().getCode();
// 已关闭直接拒绝
if (OrderStatusVO.CLOSE.getCode().equals(status)) {
log.warn("退单失败,订单已关闭 userId:{} orderId:{} status:{}", userId, orderId, status);
return false;
}
// 2. 营销锁单走营销通道 + 统一改库
int marketType = orderEntity.getMarketType(); // 建议后续用枚举替代裸常量
if (marketType == 1) {
try {
port.refundMarketPayOrder(userId, orderId);
} catch (Exception e) {
// 这里按你的容忍度决定是否直接返回 false
log.error("营销退单通道异常 userId:{} orderId:{} err:{}", userId, orderId, e.getMessage(), e);
return false;
}
boolean result = repository.refundMarketOrder(userId, orderId);
if (result) {
log.info("营销退单成功(已改库) userId:{} orderId:{}", userId, orderId);
} else {
log.warn("营销退单失败(改库失败) userId:{} orderId:{}", userId, orderId);
}
return result;
}
// 3. 普通订单分未付款 / 已付款
// 1. 未付款仅改库
if (OrderStatusVO.CREATE.getCode().equals(status)
|| OrderStatusVO.PAY_WAIT.getCode().equals(status)) {
// 未付款仅改库
boolean result = repository.refundOrder(userId, orderId);
if (result) {
log.info("普通未付款退单成功(仅改库) userId:{} orderId:{}", userId, orderId);
log.info("退款成功(未付款订单,仅改库) userId:{} orderId:{}", userId, orderId);
} else {
log.warn("普通未付款退单失败(改库失败) userId:{} orderId:{}", userId, orderId);
log.warn("退款失败(未付款订单改库失败) userId:{} orderId:{}", userId, orderId);
}
return result;
} else {
// 已付款三方退款 + 改库用你已有的方法
return refundPayOrder(userId, orderId);
}
}
/**
* 真正的退钱关闭订单逻辑
*/
@Override
public boolean refundPayOrder(String userId, String orderId) /* throws AlipayApiException */ {
// 1. 查询订单信息验证订单是否存在且属于该用户
OrderEntity orderEntity = repository.queryOrderByUserIdAndOrderId(userId, orderId);
if (orderEntity == null) {
log.warn("退款失败,订单不存在或不属于该用户 userId:{} orderId:{}", userId, orderId);
return false;
}
boolean dbOk = false; // 以落库结果为最终返回
// 2. 已付款三方退款 + 改库
boolean dbOk = false;
try {
// 2. 调用支付宝退款沙箱里允许失败
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
AlipayTradeRefundModel refundModel = new AlipayTradeRefundModel();
refundModel.setOutTradeNo(orderEntity.getOrderId());
refundModel.setOutTradeNo(orderId);
refundModel.setRefundAmount(orderEntity.getPayAmount().toString());
refundModel.setRefundReason("交易退单");
request.setBizModel(refundModel);
@ -228,16 +180,13 @@ public class OrderService extends AbstractOrderService{
if (resp.isSuccess()) {
log.info("支付宝退款成功 userId:{} orderId:{}", userId, orderId);
} else {
// 不影响后续改库
log.warn("支付宝退款失败(沙箱忽略) code={}, subCode={}, msg={}",
resp.getCode(), resp.getSubCode(), resp.getSubMsg());
}
} catch (Exception e) {
// 捕获所有异常避免抛出导致 MQ 重试
log.error("调用支付宝退款异常(沙箱忽略) userId:{} orderId:{} err:{}",
userId, orderId, e.getMessage(), e);
} finally {
// 3. 必须执行状态变更你要求的必须执行
try {
dbOk = repository.refundOrder(userId, orderId);
if (dbOk) {
@ -246,14 +195,57 @@ public class OrderService extends AbstractOrderService{
log.warn("订单状态更新失败 userId:{} orderId:{}", userId, orderId);
}
} catch (Exception de) {
// 落库异常要打日志并返回 false交由上层决定是否重试/告警
log.error("订单状态更新异常 userId:{} orderId:{} err:{}",
userId, orderId, de.getMessage(), de);
dbOk = false;
}
}
// 返回以数据库落库为准支付宝失败在沙箱场景被忽略
return dbOk;
}
/**
* 预备退单
*/
@Override
public boolean preRefundOrder(String userId, String orderId) {
OrderEntity orderEntity = repository.queryOrderByUserIdAndOrderId(userId, orderId);
if (orderEntity == null) {
log.warn("退单失败,订单不存在或不属于该用户 userId:{} orderId:{}", userId, orderId);
return false;
}
String status = orderEntity.getOrderStatusVO().getCode();
if (OrderStatusVO.CLOSE.getCode().equals(status)) {
log.warn("退单失败,订单已关闭 userId:{} orderId:{} status:{}", userId, orderId, status);
return false;
}
int marketType = orderEntity.getMarketType();
if (marketType == 1) {
try {
port.refundMarketPayOrder(userId, orderId);
} catch (Exception e) {
log.error("营销退单通道异常 userId:{} orderId:{} err:{}", userId, orderId, e.getMessage(), e);
return false;
}
return repository.refundMarketOrder(userId, orderId);
}
// 普通订单走统一逻辑
return doRefund(orderEntity);
}
/**
* 真正的退款逻辑 MQ 或别的地方直接调
*/
@Override
public boolean refundPayOrder(String userId, String orderId) {
OrderEntity orderEntity = repository.queryOrderByUserIdAndOrderId(userId, orderId);
if (orderEntity == null) {
log.warn("退款失败,订单不存在或不属于该用户 userId:{} orderId:{}", userId, orderId);
return false;
}
return doRefund(orderEntity);
}
}

View File

@ -14,8 +14,8 @@ public class ProductRPC {
public ProductDTO queryProductByProductId(String productId){
ProductDTO productVO = new ProductDTO();
productVO.setProductId(productId);
productVO.setProductName("MyBatisBook");
productVO.setProductDesc("MyBatisBook");
productVO.setProductName("早晨从中午开始");
productVO.setProductDesc("早晨从中午开始");
productVO.setPrice(new BigDecimal("100.00"));
return productVO;
}