Commit fcbe32ca14e4839a3fa1254b614a0eedf4a44637

Authored by huanggang
1 parent 890f6a67

close trade order

cashier-boss/src/main/java/com/diligrp/cashier/boss/controller/CashierDeskController.java
... ... @@ -59,8 +59,8 @@ public class CashierDeskController {
59 59 }
60 60  
61 61 @RequestMapping("/orderClose")
62   - public Message<?> orderPayment(@RequestParam("paymentId") String paymentId) {
63   - cashierDeskService.closePrepayOrder(paymentId);
  62 + public Message<?> orderClose(@RequestParam("tradeId") String tradeId) {
  63 + cashierDeskService.closeTradeOrder(tradeId);
64 64 return Message.success();
65 65 }
66 66  
... ...
cashier-boss/src/main/java/com/diligrp/cashier/boss/service/ICashierDeskService.java
... ... @@ -29,9 +29,9 @@ public interface ICashierDeskService {
29 29 OnlinePaymentStatus doPayment(CashierPayment payment);
30 30  
31 31 /**
32   - * 关闭预支付订单
  32 + * 关闭交易订单
33 33 */
34   - void closePrepayOrder(String paymentId);
  34 + void closeTradeOrder(String tradeId);
35 35  
36 36 /**
37 37 * 查询支付状态
... ...
cashier-boss/src/main/java/com/diligrp/cashier/boss/service/impl/CashierDeskServiceImpl.java
... ... @@ -105,8 +105,8 @@ public class CashierDeskServiceImpl implements ICashierDeskService {
105 105 }
106 106  
107 107 @Override
108   - public void closePrepayOrder(String paymentId) {
109   - cashierPaymentService.closePrepayOrder(paymentId);
  108 + public void closeTradeOrder(String tradeId) {
  109 + cashierPaymentService.closeTradeOrder(tradeId);
110 110 }
111 111  
112 112 @Override
... ...
cashier-trade/src/main/java/com/diligrp/cashier/trade/service/ICashierPaymentService.java
... ... @@ -31,9 +31,9 @@ public interface ICashierPaymentService {
31 31 void notifyPaymentResponse(OnlinePaymentResponse response);
32 32  
33 33 /**
34   - * 关闭预支付订单
  34 + * 关闭交易订单
35 35 */
36   - void closePrepayOrder(String paymentId);
  36 + void closeTradeOrder(String tradeId);
37 37  
38 38 /**
39 39 * 查询交易订单状态
... ...
cashier-trade/src/main/java/com/diligrp/cashier/trade/service/impl/CashierPaymentServiceImpl.java
... ... @@ -5,7 +5,6 @@ import com.diligrp.cashier.assistant.service.impl.SnowflakeKeyManager;
5 5 import com.diligrp.cashier.pipeline.core.DiliCardPipeline;
6 6 import com.diligrp.cashier.pipeline.core.OnlinePipeline;
7 7 import com.diligrp.cashier.pipeline.core.PaymentPipeline;
8   -import com.diligrp.cashier.pipeline.core.WechatPipeline;
9 8 import com.diligrp.cashier.pipeline.domain.*;
10 9 import com.diligrp.cashier.pipeline.domain.card.CardPaymentRequest;
11 10 import com.diligrp.cashier.pipeline.domain.card.CardPaymentResponse;
... ... @@ -40,6 +39,7 @@ import org.springframework.stereotype.Service;
40 39 import org.springframework.transaction.annotation.Transactional;
41 40  
42 41 import java.time.LocalDateTime;
  42 +import java.util.List;
43 43 import java.util.Objects;
44 44 import java.util.concurrent.TimeUnit;
45 45  
... ... @@ -244,33 +244,43 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService {
244 244  
245 245 @Override
246 246 @Transactional(rollbackFor = Exception.class)
247   - public void closePrepayOrder(String paymentId) {
248   - OnlinePayment payment = tradeAssistantService.findByPaymentId(paymentId);
249   - if (PaymentState.isFinished(payment.getState())) {
250   - throw new TradePaymentException(ErrorCode.OPERATION_NOT_ALLOWED, "不能关闭预支付订单: 无效的订单状态");
251   - }
252   -
253   - String lockKey = String.format(Constants.TRADE_LOCK_REDIS_KEY, payment.getTradeId());
  247 + public void closeTradeOrder(String tradeId) {
  248 + String lockKey = String.format(Constants.TRADE_LOCK_REDIS_KEY, tradeId);
254 249 RLock lock = redissonClient.getLock(lockKey);
255 250 try {
256 251 lock.lock();
257 252  
258   - LocalDateTime now = LocalDateTime.now();
259   -// TradeOrder trade = tradeAssistantService.findByTradeId(payment.getTradeId());
260   - PaymentPipeline<?> pipeline = paymentPipelineManager.findPipelineById(payment.getPipelineId(), PaymentPipeline.class);
261   - // 只有在线支付通道才可以关闭支付订单,园区卡支付不支持
262   - if (pipeline instanceof OnlinePipeline<?> onlinePipeline) {
263   - OnlinePrepayOrder order = new OnlinePrepayOrder(paymentId, payment.getOutTradeNo());
264   - onlinePipeline.closePrepayOrder(order);
265   - PaymentStateDTO paymentDTO = PaymentStateDTO.builder().paymentId(payment.getPaymentId())
266   - .outTradeNo(null).outPayType(null).payerId(null).finishTime(null).state(PaymentState.FAILED)
267   - .description("人工关闭支付订单").version(payment.getVersion()).modifiedTime(now).build();
268   - tradeAssistantService.proceedOnlinePayment(paymentDTO);
  253 + TradeOrder trade = tradeAssistantService.findByTradeId(tradeId);
  254 + if (TradeState.CLOSED.equalTo(trade.getState())) {
  255 + return;
  256 + }
  257 + if (TradeState.isFinished(trade.getState())) {
  258 + throw new TradePaymentException(ErrorCode.OPERATION_NOT_ALLOWED, "关闭交易订单失败: 无效的订单状态");
  259 + }
269 260  
270   - // 暂时不修改交易订单,交易订单状态由延时消息统一处理,此时交易订单仍然可以继续支付
271   -// TradeStateDTO tradeStateDTO = TradeStateDTO.of(trade.getTradeId(), TradeState.CLOSED, trade.getVersion(), now);
272   -// tradeAssistantService.proceedTradeOrder(tradeStateDTO);
  261 + LocalDateTime now = LocalDateTime.now();
  262 + // 获取所有支付记录
  263 + List<OnlinePayment> onlinePayments = onlinePaymentDao.listOnlinePayments(trade.getTradeId(),
  264 + TradeType.TRADE.getCode(), null);
  265 + for (OnlinePayment payment : onlinePayments) {
  266 + if (PaymentState.SUCCESS.equalTo(payment.getState())) {
  267 + throw new TradePaymentException(ErrorCode.OPERATION_NOT_ALLOWED, "关闭交易订单失败: 存在支付成功的记录");
  268 + } else if (PaymentState.PENDING.equalTo(payment.getState()) || PaymentState.PROCESSING.equalTo(payment.getState())) {
  269 + PaymentPipeline<?> pipeline = paymentPipelineManager.findPipelineById(payment.getPipelineId(), PaymentPipeline.class);
  270 + if (pipeline instanceof OnlinePipeline<?> onlinePipeline) {
  271 + // 理论上只存在一条支付中的支付记录,否则后面的支付通道关闭失败时,会回滚前面支付记录的状态修改
  272 + OnlinePrepayOrder order = new OnlinePrepayOrder(payment.getPaymentId(), payment.getOutTradeNo());
  273 + onlinePipeline.closePrepayOrder(order);
  274 + PaymentStateDTO paymentDTO = PaymentStateDTO.builder().paymentId(payment.getPaymentId())
  275 + .outTradeNo(null).outPayType(null).payerId(null).finishTime(null).state(PaymentState.FAILED)
  276 + .description("人工关闭支付订单").version(payment.getVersion()).modifiedTime(now).build();
  277 + tradeAssistantService.proceedOnlinePayment(paymentDTO);
  278 + }
  279 + }
273 280 }
  281 +
  282 + TradeStateDTO tradeStateDTO = TradeStateDTO.of(trade.getTradeId(), TradeState.CLOSED, trade.getVersion(), now);
  283 + tradeAssistantService.proceedTradeOrder(tradeStateDTO);
274 284 } finally {
275 285 if (lock.isHeldByCurrentThread()) {
276 286 lock.unlock();
... ...
cashier-trade/src/main/java/com/diligrp/cashier/trade/service/impl/TradeAssistantServiceImpl.java
1 1 package com.diligrp.cashier.trade.service.impl;
2 2  
3   -import com.diligrp.cashier.pipeline.Constants;
4 3 import com.diligrp.cashier.pipeline.core.OnlinePipeline;
5 4 import com.diligrp.cashier.pipeline.core.PaymentPipeline;
6 5 import com.diligrp.cashier.pipeline.domain.OnlinePrepayOrder;
... ... @@ -65,24 +64,22 @@ public class TradeAssistantServiceImpl implements ITradeAssistantService {
65 64 // 查询支付订单所有的支付记录, 关闭支付中的支付记录, 忽略支付失败的支付记录, 存在支付成功的支付记录时不允许继续支付
66 65 List<OnlinePayment> onlinePayments = onlinePaymentDao.listOnlinePayments(trade.getTradeId(), TradeType.TRADE.getCode(), null);
67 66 for (OnlinePayment payment : onlinePayments) {
68   - if (PaymentState.PENDING.equalTo(payment.getState()) || PaymentState.PROCESSING.equalTo(payment.getState())) {
  67 + if (!PaymentState.isFinished(payment.getState())) {
69 68 PaymentPipeline<?> pipeline = paymentPipelineManager.findPipelineById(payment.getPipelineId(), PaymentPipeline.class);
70 69 if (pipeline instanceof OnlinePipeline<?> onlinePipeline) {
  70 + // 理论上只存在一条支付中的支付记录,否则后面的支付通道关闭失败时,会回滚前面支付记录的状态修改
71 71 LocalDateTime now = LocalDateTime.now();
72 72 PaymentStateDTO paymentStateDTO = PaymentStateDTO.builder().paymentId(payment.getPaymentId())
73 73 .finishTime(now).state(PaymentState.FAILED).description("主动关闭支付中的订单")
74 74 .version(payment.getVersion()).modifiedTime(now).build();
75 75 proceedOnlinePayment(paymentStateDTO);
76 76 OnlinePrepayOrder prepayOrder = new OnlinePrepayOrder(payment.getPaymentId(), payment.getOutTradeNo());
77   - // 微信服务商模式下, outMchId为签约子商户; 园区卡支付时, outMchId为市场ID
78   - prepayOrder.attach(Constants.PARAM_MCH_ID, payment.getOutMchId());
79 77 onlinePipeline.closePrepayOrder(prepayOrder);
80 78 }
81 79 // 园区卡支付通道不会存在支付中的记录
82 80 } else if (PaymentState.SUCCESS.equalTo(payment.getState())) {
83 81 return false;
84 82 } else if (PaymentState.FAILED.equalTo(payment.getState())) {
85   - continue;
86 83 }
87 84 }
88 85 return true;
... ...