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,8 +59,8 @@ public class CashierDeskController {
59 } 59 }
60 60
61 @RequestMapping("/orderClose") 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 return Message.success(); 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,9 +29,9 @@ public interface ICashierDeskService {
29 OnlinePaymentStatus doPayment(CashierPayment payment); 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,8 +105,8 @@ public class CashierDeskServiceImpl implements ICashierDeskService {
105 } 105 }
106 106
107 @Override 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 @Override 112 @Override
cashier-trade/src/main/java/com/diligrp/cashier/trade/service/ICashierPaymentService.java
@@ -31,9 +31,9 @@ public interface ICashierPaymentService { @@ -31,9 +31,9 @@ public interface ICashierPaymentService {
31 void notifyPaymentResponse(OnlinePaymentResponse response); 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,7 +5,6 @@ import com.diligrp.cashier.assistant.service.impl.SnowflakeKeyManager;
5 import com.diligrp.cashier.pipeline.core.DiliCardPipeline; 5 import com.diligrp.cashier.pipeline.core.DiliCardPipeline;
6 import com.diligrp.cashier.pipeline.core.OnlinePipeline; 6 import com.diligrp.cashier.pipeline.core.OnlinePipeline;
7 import com.diligrp.cashier.pipeline.core.PaymentPipeline; 7 import com.diligrp.cashier.pipeline.core.PaymentPipeline;
8 -import com.diligrp.cashier.pipeline.core.WechatPipeline;  
9 import com.diligrp.cashier.pipeline.domain.*; 8 import com.diligrp.cashier.pipeline.domain.*;
10 import com.diligrp.cashier.pipeline.domain.card.CardPaymentRequest; 9 import com.diligrp.cashier.pipeline.domain.card.CardPaymentRequest;
11 import com.diligrp.cashier.pipeline.domain.card.CardPaymentResponse; 10 import com.diligrp.cashier.pipeline.domain.card.CardPaymentResponse;
@@ -40,6 +39,7 @@ import org.springframework.stereotype.Service; @@ -40,6 +39,7 @@ import org.springframework.stereotype.Service;
40 import org.springframework.transaction.annotation.Transactional; 39 import org.springframework.transaction.annotation.Transactional;
41 40
42 import java.time.LocalDateTime; 41 import java.time.LocalDateTime;
  42 +import java.util.List;
43 import java.util.Objects; 43 import java.util.Objects;
44 import java.util.concurrent.TimeUnit; 44 import java.util.concurrent.TimeUnit;
45 45
@@ -244,33 +244,43 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { @@ -244,33 +244,43 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService {
244 244
245 @Override 245 @Override
246 @Transactional(rollbackFor = Exception.class) 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 RLock lock = redissonClient.getLock(lockKey); 249 RLock lock = redissonClient.getLock(lockKey);
255 try { 250 try {
256 lock.lock(); 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 } finally { 284 } finally {
275 if (lock.isHeldByCurrentThread()) { 285 if (lock.isHeldByCurrentThread()) {
276 lock.unlock(); 286 lock.unlock();
cashier-trade/src/main/java/com/diligrp/cashier/trade/service/impl/TradeAssistantServiceImpl.java
1 package com.diligrp.cashier.trade.service.impl; 1 package com.diligrp.cashier.trade.service.impl;
2 2
3 -import com.diligrp.cashier.pipeline.Constants;  
4 import com.diligrp.cashier.pipeline.core.OnlinePipeline; 3 import com.diligrp.cashier.pipeline.core.OnlinePipeline;
5 import com.diligrp.cashier.pipeline.core.PaymentPipeline; 4 import com.diligrp.cashier.pipeline.core.PaymentPipeline;
6 import com.diligrp.cashier.pipeline.domain.OnlinePrepayOrder; 5 import com.diligrp.cashier.pipeline.domain.OnlinePrepayOrder;
@@ -65,24 +64,22 @@ public class TradeAssistantServiceImpl implements ITradeAssistantService { @@ -65,24 +64,22 @@ public class TradeAssistantServiceImpl implements ITradeAssistantService {
65 // 查询支付订单所有的支付记录, 关闭支付中的支付记录, 忽略支付失败的支付记录, 存在支付成功的支付记录时不允许继续支付 64 // 查询支付订单所有的支付记录, 关闭支付中的支付记录, 忽略支付失败的支付记录, 存在支付成功的支付记录时不允许继续支付
66 List<OnlinePayment> onlinePayments = onlinePaymentDao.listOnlinePayments(trade.getTradeId(), TradeType.TRADE.getCode(), null); 65 List<OnlinePayment> onlinePayments = onlinePaymentDao.listOnlinePayments(trade.getTradeId(), TradeType.TRADE.getCode(), null);
67 for (OnlinePayment payment : onlinePayments) { 66 for (OnlinePayment payment : onlinePayments) {
68 - if (PaymentState.PENDING.equalTo(payment.getState()) || PaymentState.PROCESSING.equalTo(payment.getState())) { 67 + if (!PaymentState.isFinished(payment.getState())) {
69 PaymentPipeline<?> pipeline = paymentPipelineManager.findPipelineById(payment.getPipelineId(), PaymentPipeline.class); 68 PaymentPipeline<?> pipeline = paymentPipelineManager.findPipelineById(payment.getPipelineId(), PaymentPipeline.class);
70 if (pipeline instanceof OnlinePipeline<?> onlinePipeline) { 69 if (pipeline instanceof OnlinePipeline<?> onlinePipeline) {
  70 + // 理论上只存在一条支付中的支付记录,否则后面的支付通道关闭失败时,会回滚前面支付记录的状态修改
71 LocalDateTime now = LocalDateTime.now(); 71 LocalDateTime now = LocalDateTime.now();
72 PaymentStateDTO paymentStateDTO = PaymentStateDTO.builder().paymentId(payment.getPaymentId()) 72 PaymentStateDTO paymentStateDTO = PaymentStateDTO.builder().paymentId(payment.getPaymentId())
73 .finishTime(now).state(PaymentState.FAILED).description("主动关闭支付中的订单") 73 .finishTime(now).state(PaymentState.FAILED).description("主动关闭支付中的订单")
74 .version(payment.getVersion()).modifiedTime(now).build(); 74 .version(payment.getVersion()).modifiedTime(now).build();
75 proceedOnlinePayment(paymentStateDTO); 75 proceedOnlinePayment(paymentStateDTO);
76 OnlinePrepayOrder prepayOrder = new OnlinePrepayOrder(payment.getPaymentId(), payment.getOutTradeNo()); 76 OnlinePrepayOrder prepayOrder = new OnlinePrepayOrder(payment.getPaymentId(), payment.getOutTradeNo());
77 - // 微信服务商模式下, outMchId为签约子商户; 园区卡支付时, outMchId为市场ID  
78 - prepayOrder.attach(Constants.PARAM_MCH_ID, payment.getOutMchId());  
79 onlinePipeline.closePrepayOrder(prepayOrder); 77 onlinePipeline.closePrepayOrder(prepayOrder);
80 } 78 }
81 // 园区卡支付通道不会存在支付中的记录 79 // 园区卡支付通道不会存在支付中的记录
82 } else if (PaymentState.SUCCESS.equalTo(payment.getState())) { 80 } else if (PaymentState.SUCCESS.equalTo(payment.getState())) {
83 return false; 81 return false;
84 } else if (PaymentState.FAILED.equalTo(payment.getState())) { 82 } else if (PaymentState.FAILED.equalTo(payment.getState())) {
85 - continue;  
86 } 83 }
87 } 84 }
88 return true; 85 return true;