Commit 888c48820662de70e8df18623f6660f179abd01c

Authored by YunaiV
1 parent 3f410c27

mall + pay:

1. 优化 PayClient 退款逻辑,返回业务失败 errorCode + errorMsg 错误码
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/refund/PayRefundStatusRespEnum.java
... ... @@ -25,4 +25,8 @@ public enum PayRefundStatusRespEnum {
25 25 return Objects.equals(status, SUCCESS.getStatus());
26 26 }
27 27  
  28 + public static boolean isFailure(Integer status) {
  29 + return Objects.equals(status, FAILURE.getStatus());
  30 + }
  31 +
28 32 }
... ...
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/refund/PayRefundStatusEnum.java
... ... @@ -25,4 +25,8 @@ public enum PayRefundStatusEnum {
25 25 return Objects.equals(status, SUCCESS.getStatus());
26 26 }
27 27  
  28 + public static boolean isFailure(Integer status) {
  29 + return Objects.equals(status, FAILURE.getStatus());
  30 + }
  31 +
28 32 }
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
... ... @@ -237,6 +237,7 @@ public class PayOrderServiceImpl implements PayOrderService {
237 237 TenantUtils.execute(channel.getTenantId(), () -> notifyPayOrder(channel, notify));
238 238 }
239 239  
  240 + // TODO 芋艿:事务问题
240 241 private void notifyPayOrder(PayChannelDO channel, PayOrderRespDTO notify) {
241 242 // 情况一:支付成功的回调
242 243 if (PayOrderStatusRespEnum.isSuccess(notify.getStatus())) {
... ... @@ -372,7 +373,7 @@ public class PayOrderServiceImpl implements PayOrderService {
372 373 throw exception(ORDER_NOT_FOUND);
373 374 }
374 375 if (!PayOrderStatusEnum.isSuccess(order.getStatus())) {
375   - throw exception(REFUND_PRICE_EXCEED);
  376 + throw exception(ORDER_STATUS_IS_NOT_SUCCESS);
376 377 }
377 378 if (order.getRefundPrice() + incrRefundPrice > order.getPrice()) {
378 379 throw exception(REFUND_PRICE_EXCEED);
... ... @@ -389,7 +390,10 @@ public class PayOrderServiceImpl implements PayOrderService {
389 390 updateObj.setStatus(PayOrderStatusEnum.CLOSED.getStatus())
390 391 .setRefundStatus(PayOrderRefundStatusEnum.PART.getStatus());
391 392 }
392   - orderMapper.updateByIdAndStatus(id, PayOrderStatusEnum.SUCCESS.getStatus(), updateObj);
  393 + int updateCount = orderMapper.updateByIdAndStatus(id, PayOrderStatusEnum.SUCCESS.getStatus(), updateObj);
  394 + if (updateCount == 0) {
  395 + throw exception(ORDER_STATUS_IS_NOT_SUCCESS);
  396 + }
393 397 }
394 398  
395 399 }
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java
... ... @@ -206,7 +206,6 @@ public class PayRefundServiceImpl implements PayRefundService {
206 206 }
207 207  
208 208 @Override
209   - @Transactional(rollbackFor = Exception.class)
210 209 public void notifyRefund(Long channelId, PayRefundRespDTO notify) {
211 210 // 校验支付渠道是否有效
212 211 channelService.validPayChannel(channelId);
... ... @@ -218,15 +217,20 @@ public class PayRefundServiceImpl implements PayRefundService {
218 217 TenantUtils.execute(channel.getTenantId(), () -> notifyRefund(channel, notify));
219 218 }
220 219  
  220 + // TODO 芋艿:事务问题
221 221 private void notifyRefund(PayChannelDO channel, PayRefundRespDTO notify) {
  222 + // 情况一:退款成功
222 223 if (PayRefundStatusRespEnum.isSuccess(notify.getStatus())) {
223 224 notifyRefundSuccess(channel, notify);
224   - } else {
  225 + return;
  226 + }
  227 + // 情况二:退款失败
  228 + if (PayRefundStatusRespEnum.isFailure(notify.getStatus())) {
225 229 notifyRefundFailure(channel, notify);
226 230 }
227 231 }
228 232  
229   - private void notifyRefundSuccess(PayChannelDO channel, PayRefundRespDTO notify) {
  233 + public void notifyRefundSuccess(PayChannelDO channel, PayRefundRespDTO notify) {
230 234 // 1.1 查询 PayRefundDO
231 235 PayRefundDO refund = refundMapper.selectByAppIdAndNo(
232 236 channel.getAppId(), notify.getOutRefundNo());
... ... @@ -234,12 +238,12 @@ public class PayRefundServiceImpl implements PayRefundService {
234 238 throw exception(ErrorCodeConstants.REFUND_NOT_FOUND);
235 239 }
236 240 if (PayRefundStatusEnum.isSuccess(refund.getStatus())) { // 如果已经是成功,直接返回,不用重复更新
  241 + log.info("[notifyRefundSuccess][退款订单({}) 已经是退款成功,无需更新]", refund.getId());
237 242 return;
238 243 }
239 244 if (!PayRefundStatusEnum.WAITING.getStatus().equals(refund.getStatus())) {
240 245 throw exception(ErrorCodeConstants.REFUND_STATUS_IS_NOT_WAITING);
241 246 }
242   -
243 247 // 1.2 更新 PayRefundDO
244 248 PayRefundDO updateRefundObj = new PayRefundDO()
245 249 .setSuccessTime(notify.getSuccessTime())
... ... @@ -250,17 +254,46 @@ public class PayRefundServiceImpl implements PayRefundService {
250 254 if (updateCounts == 0) { // 校验状态,必须是等待状态
251 255 throw exception(ErrorCodeConstants.REFUND_STATUS_IS_NOT_WAITING);
252 256 }
  257 + log.info("[notifyRefundSuccess][退款订单({}) 更新为退款成功]", refund.getId());
253 258  
254 259 // 2. 更新订单
255 260 orderService.updateOrderRefundPrice(refund.getOrderId(), refund.getRefundPrice());
256 261  
257   - // 3. 插入退款通知记录
  262 + // 3. 插入退款通知记录 TODO 芋艿:退款成功
258 263 notifyService.createPayNotifyTask(PayNotifyTaskCreateReqDTO.builder()
259 264 .type(PayNotifyTypeEnum.REFUND.getType()).dataId(refund.getId()).build());
260 265 }
261 266  
262   - private void notifyRefundFailure(PayChannelDO channel, PayRefundRespDTO notify) {
263   - // TODO 芋艿:未实现
  267 + @Transactional(rollbackFor = Exception.class)
  268 + public void notifyRefundFailure(PayChannelDO channel, PayRefundRespDTO notify) {
  269 + // 1.1 查询 PayRefundDO
  270 + PayRefundDO refund = refundMapper.selectByAppIdAndNo(
  271 + channel.getAppId(), notify.getOutRefundNo());
  272 + if (refund == null) {
  273 + throw exception(ErrorCodeConstants.REFUND_NOT_FOUND);
  274 + }
  275 + if (PayRefundStatusEnum.isFailure(refund.getStatus())) { // 如果已经是成功,直接返回,不用重复更新
  276 + log.info("[notifyRefundSuccess][退款订单({}) 已经是退款关闭,无需更新]", refund.getId());
  277 + return;
  278 + }
  279 + if (!PayRefundStatusEnum.WAITING.getStatus().equals(refund.getStatus())) {
  280 + throw exception(ErrorCodeConstants.REFUND_STATUS_IS_NOT_WAITING);
  281 + }
  282 + // 1.2 更新 PayRefundDO
  283 + PayRefundDO updateRefundObj = new PayRefundDO()
  284 + .setChannelRefundNo(notify.getChannelRefundNo())
  285 + .setStatus(PayRefundStatusEnum.FAILURE.getStatus())
  286 + .setChannelNotifyData(toJsonString(notify))
  287 + .setChannelErrorCode(notify.getChannelErrorCode()).setChannelErrorMsg(notify.getChannelErrorMsg());
  288 + int updateCounts = refundMapper.updateByIdAndStatus(refund.getId(), refund.getStatus(), updateRefundObj);
  289 + if (updateCounts == 0) { // 校验状态,必须是等待状态
  290 + throw exception(ErrorCodeConstants.REFUND_STATUS_IS_NOT_WAITING);
  291 + }
  292 + log.info("[notifyRefundFailure][退款订单({}) 更新为退款失败]", refund.getId());
  293 +
  294 + // 2. 插入退款通知记录 TODO 芋艿:退款失败
  295 + notifyService.createPayNotifyTask(PayNotifyTaskCreateReqDTO.builder()
  296 + .type(PayNotifyTypeEnum.REFUND.getType()).dataId(refund.getId()).build());
264 297 }
265 298  
266 299 }
... ...