Commit 3bde43b148faf4e95bdc655cf65c0ceed178d8bc

Authored by YunaiV
1 parent 57a934ae

【功能优化】支付:钱包充值的支付回调,增加“已支付”情况下的防重处理

yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java
... ... @@ -115,18 +115,19 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService {
115 115 // 1.1 校验订单是否存在
116 116 PayDemoOrderDO order = payDemoOrderMapper.selectById(id);
117 117 if (order == null) {
  118 + log.error("[updateDemoOrderPaid][order({}) payOrder({}) 不存在订单,请进行处理!]", id, payOrderId);
118 119 throw exception(DEMO_ORDER_NOT_FOUND);
119 120 }
120 121 // 1.2 校验订单已支付
121 122 if (order.getPayStatus()) {
122 123 // 特殊:如果订单已支付,且支付单号相同,直接返回,说明重复回调
123 124 if (ObjectUtil.equals(order.getPayOrderId(), payOrderId)) {
124   - log.warn("[updateDemoOrderPaid][order({}) 已支付,且支付单号相同({}),直接返回]", id, payOrderId);
  125 + log.warn("[updateDemoOrderPaid][order({}) 已支付,且支付单号相同({}),直接返回]", order, payOrderId);
125 126 return;
126 127 }
127 128 // 异常:支付单号不同,说明支付单号错误
128 129 log.error("[updateDemoOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]",
129   - id, payOrderId, toJsonString(order));
  130 + order, payOrderId, toJsonString(order));
130 131 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
131 132 }
132 133  
... ... @@ -153,24 +154,24 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService {
153 154 // 1. 校验支付单是否存在
154 155 PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId);
155 156 if (payOrder == null) {
156   - log.error("[validateDemoOrderCanPaid][order({}) payOrder({}) 不存在,请进行处理!]", order, payOrderId);
  157 + log.error("[validatePayOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", order, payOrderId);
157 158 throw exception(PAY_ORDER_NOT_FOUND);
158 159 }
159 160 // 2.1 校验支付单已支付
160 161 if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) {
161   - log.error("[validateDemoOrderCanPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]",
  162 + log.error("[validatePayOrderPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]",
162 163 order, payOrderId, toJsonString(payOrder));
163 164 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS);
164 165 }
165 166 // 2.1 校验支付金额一致
166 167 if (notEqual(payOrder.getPrice(), order.getPrice())) {
167   - log.error("[validateDemoOrderCanPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]",
  168 + log.error("[validatePayOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]",
168 169 order, payOrderId, toJsonString(order), toJsonString(payOrder));
169 170 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH);
170 171 }
171 172 // 2.2 校验支付订单匹配(二次)
172 173 if (notEqual(payOrder.getMerchantOrderId(), order.getId().toString())) {
173   - log.error("[validateDemoOrderCanPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]",
  174 + log.error("[validatePayOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]",
174 175 order, payOrderId, toJsonString(payOrder));
175 176 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
176 177 }
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java
... ... @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.pay.service.wallet;
2 2  
3 3 import cn.hutool.core.date.LocalDateTimeUtil;
4 4 import cn.hutool.core.lang.Assert;
  5 +import cn.hutool.core.util.ObjectUtil;
5 6 import cn.hutool.extra.spring.SpringUtil;
6 7 import cn.iocoder.yudao.framework.common.pojo.PageParam;
7 8 import cn.iocoder.yudao.framework.common.pojo.PageResult;
... ... @@ -113,16 +114,28 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
113 114 @Override
114 115 @Transactional(rollbackFor = Exception.class)
115 116 public void updateWalletRechargerPaid(Long id, Long payOrderId) {
116   - // 1.1 获取钱包充值记录
117   - PayWalletRechargeDO walletRecharge = walletRechargeMapper.selectById(id);
118   - if (walletRecharge == null) {
119   - log.error("[updateWalletRechargerPaid][钱包充值记录不存在,钱包充值记录 id({})]", id);
  117 + // 1.1 校验钱包充值是否存在
  118 + PayWalletRechargeDO recharge = walletRechargeMapper.selectById(id);
  119 + if (recharge == null) {
  120 + log.error("[updateWalletRechargerPaid][recharge({}) payOrder({}) 不存在充值订单,请进行处理!]", id, payOrderId);
120 121 throw exception(WALLET_RECHARGE_NOT_FOUND);
121 122 }
122 123 // 1.2 校验钱包充值是否可以支付
123   - PayOrderDO payOrderDO = validateWalletRechargerCanPaid(walletRecharge, payOrderId);
  124 + if (recharge.getPayStatus()) {
  125 + // 特殊:如果订单已支付,且支付单号相同,直接返回,说明重复回调
  126 + if (ObjectUtil.equals(recharge.getPayOrderId(), payOrderId)) {
  127 + log.warn("[updateWalletRechargerPaid][recharge({}) 已支付,且支付单号相同({}),直接返回]", recharge, payOrderId);
  128 + return;
  129 + }
  130 + // 异常:支付单号不同,说明支付单号错误
  131 + log.error("[updateWalletRechargerPaid][recharge({}) 已支付,但是支付单号不同({}),请进行处理!]", recharge, payOrderId);
  132 + throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_ID_ERROR);
  133 + }
124 134  
125   - // 2. 更新钱包充值的支付状态
  135 + // 2. 校验支付订单的合法性
  136 + PayOrderDO payOrderDO = validatePayOrderPaid(recharge, payOrderId);
  137 +
  138 + // 3. 更新钱包充值的支付状态
126 139 int updateCount = walletRechargeMapper.updateByIdAndPaid(id, false,
127 140 new PayWalletRechargeDO().setId(id).setPayStatus(true).setPayTime(LocalDateTime.now())
128 141 .setPayChannelCode(payOrderDO.getChannelCode()));
... ... @@ -130,14 +143,14 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
130 143 throw exception(WALLET_RECHARGE_UPDATE_PAID_STATUS_NOT_UNPAID);
131 144 }
132 145  
133   - // 3. 更新钱包余额
  146 + // 4. 更新钱包余额
134 147 // TODO @jason:这样的话,未来提现会不会把充值的,也提现走哈。类似先充 100,送 110;然后提现 110;
135 148 // TODO 需要钱包中加个可提现余额
136   - payWalletService.addWalletBalance(walletRecharge.getWalletId(), String.valueOf(id),
137   - PayWalletBizTypeEnum.RECHARGE, walletRecharge.getTotalPrice());
  149 + payWalletService.addWalletBalance(recharge.getWalletId(), String.valueOf(id),
  150 + PayWalletBizTypeEnum.RECHARGE, recharge.getTotalPrice());
138 151  
139   - // 4. 发送订阅消息
140   - getSelf().sendWalletRechargerPaidMessage(payOrderId, walletRecharge);
  152 + // 5. 发送订阅消息
  153 + getSelf().sendWalletRechargerPaidMessage(payOrderId, recharge);
141 154 }
142 155  
143 156 @Async
... ... @@ -267,43 +280,38 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
267 280 return wallet;
268 281 }
269 282  
270   - private PayOrderDO validateWalletRechargerCanPaid(PayWalletRechargeDO walletRecharge, Long payOrderId) {
271   - // 1.1 校验充值记录的支付状态
272   - if (walletRecharge.getPayStatus()) {
273   - log.error("[validateWalletRechargerCanPaid][钱包({}) 不处于未支付状态! 钱包数据是:{}]",
274   - walletRecharge.getId(), toJsonString(walletRecharge));
275   - throw exception(WALLET_RECHARGE_UPDATE_PAID_STATUS_NOT_UNPAID);
276   - }
277   - // 1.2 校验支付订单匹配
278   - if (notEqual(walletRecharge.getPayOrderId(), payOrderId)) { // 支付单号
279   - log.error("[validateWalletRechargerCanPaid][钱包({}) 支付单不匹配({}),请进行处理! 钱包数据是:{}]",
280   - walletRecharge.getId(), payOrderId, toJsonString(walletRecharge));
281   - throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_ID_ERROR);
282   - }
283   -
284   - // 2.1 校验支付单是否存在
  283 + /**
  284 + * 校验支付订单的合法性
  285 + *
  286 + * @param recharge 充值订单
  287 + * @param payOrderId 支付订单编号
  288 + * @return 支付订单
  289 + */
  290 + private PayOrderDO validatePayOrderPaid(PayWalletRechargeDO recharge, Long payOrderId) {
  291 + // 1. 校验支付单是否存在
285 292 PayOrderDO payOrder = payOrderService.getOrder(payOrderId);
286 293 if (payOrder == null) {
287   - log.error("[validateWalletRechargerCanPaid][钱包({}) payOrder({}) 不存在,请进行处理!]",
288   - walletRecharge.getId(), payOrderId);
  294 + log.error("[validatePayOrderPaid][充值订单({}) payOrder({}) 不存在,请进行处理!]",
  295 + recharge, payOrderId);
289 296 throw exception(PAY_ORDER_NOT_FOUND);
290 297 }
291   - // 2.2 校验支付单已支付
  298 +
  299 + // 2.1 校验支付单已支付
292 300 if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) {
293   - log.error("[validateWalletRechargerCanPaid][钱包({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]",
294   - walletRecharge.getId(), payOrderId, toJsonString(payOrder));
  301 + log.error("[validatePayOrderPaid][充值订单({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]",
  302 + recharge, payOrderId, toJsonString(payOrder));
295 303 throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_STATUS_NOT_SUCCESS);
296 304 }
297   - // 2.3 校验支付金额一致
298   - if (notEqual(payOrder.getPrice(), walletRecharge.getPayPrice())) {
299   - log.error("[validateDemoOrderCanPaid][钱包({}) payOrder({}) 支付金额不匹配,请进行处理!钱包 数据是:{},payOrder 数据是:{}]",
300   - walletRecharge.getId(), payOrderId, toJsonString(walletRecharge), toJsonString(payOrder));
  305 + // 2.2 校验支付金额一致
  306 + if (notEqual(payOrder.getPrice(), recharge.getPayPrice())) {
  307 + log.error("[validatePayOrderPaid][充值订单({}) payOrder({}) 支付金额不匹配,请进行处理!钱包 数据是:{},payOrder 数据是:{}]",
  308 + recharge, payOrderId, toJsonString(recharge), toJsonString(payOrder));
301 309 throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_PRICE_NOT_MATCH);
302 310 }
303   - // 2.4 校验支付订单的商户订单匹配
304   - if (notEqual(payOrder.getMerchantOrderId(), walletRecharge.getId().toString())) {
305   - log.error("[validateDemoOrderCanPaid][钱包({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]",
306   - walletRecharge.getId(), payOrderId, toJsonString(payOrder));
  311 + // 2.3 校验支付订单的商户订单匹配
  312 + if (notEqual(payOrder.getMerchantOrderId(), recharge.getId().toString())) {
  313 + log.error("[validatePayOrderPaid][充值订单({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]",
  314 + recharge, payOrderId, toJsonString(payOrder));
307 315 throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_ID_ERROR);
308 316 }
309 317 return payOrder;
... ...