Commit eb7b1af06ed4b483f64670c48835e117bb130b85

Authored by huanggang
1 parent e2a07d8f

upgrade after testing

cashier-pipeline/src/main/java/com/diligrp/cashier/pipeline/client/CardPaymentHttpClient.java
@@ -68,7 +68,7 @@ public class CardPaymentHttpClient extends ServiceEndpointSupport { @@ -68,7 +68,7 @@ public class CardPaymentHttpClient extends ServiceEndpointSupport {
68 LocalDateTime now = LocalDateTime.now(); 68 LocalDateTime now = LocalDateTime.now();
69 HttpResult result = send(uri, payload); 69 HttpResult result = send(uri, payload);
70 if (result.statusCode == 200) { 70 if (result.statusCode == 200) {
71 - LOG.debug("Received from card payment pipeline: {}\n{}", request.getPaymentId(), result.responseText); 71 + LOG.debug("Card payment response received: {}\n{}", request.getPaymentId(), result.responseText);
72 Map<String, Object> response = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {}); 72 Map<String, Object> response = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {});
73 if ("200".equals(response.get("code"))) { 73 if ("200".equals(response.get("code"))) {
74 Map<String, Object> data = (Map<String, Object>) response.get("data"); 74 Map<String, Object> data = (Map<String, Object>) response.get("data");
@@ -99,7 +99,7 @@ public class CardPaymentHttpClient extends ServiceEndpointSupport { @@ -99,7 +99,7 @@ public class CardPaymentHttpClient extends ServiceEndpointSupport {
99 LocalDateTime now = LocalDateTime.now(); 99 LocalDateTime now = LocalDateTime.now();
100 HttpResult result = send(uri, payload); 100 HttpResult result = send(uri, payload);
101 if (result.statusCode == 200) { 101 if (result.statusCode == 200) {
102 - LOG.debug("Received from card payment pipeline: {}\n", request.getRefundId(), result.responseText); 102 + LOG.debug("Card refund response received: {}\n{}", request.getRefundId(), result.responseText);
103 Map<String, Object> response = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {}); 103 Map<String, Object> response = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {});
104 if ("200".equals(response.get("code"))) { 104 if ("200".equals(response.get("code"))) {
105 return new OnlineRefundResponse(request.getRefundId(), null, now, 105 return new OnlineRefundResponse(request.getRefundId(), null, now,
@@ -121,7 +121,7 @@ public class CardPaymentHttpClient extends ServiceEndpointSupport { @@ -121,7 +121,7 @@ public class CardPaymentHttpClient extends ServiceEndpointSupport {
121 LOG.debug("Sending list user card request: {}\n{}", userId, payload); 121 LOG.debug("Sending list user card request: {}\n{}", userId, payload);
122 HttpResult result = send(uri, payload); 122 HttpResult result = send(uri, payload);
123 if (result.statusCode == 200) { 123 if (result.statusCode == 200) {
124 - LOG.debug("Received from card payment pipeline: {}\n{}", userId, result.responseText); 124 + LOG.debug("List user card response received: {}\n{}", userId, result.responseText);
125 Map<String, Object> response = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {}); 125 Map<String, Object> response = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {});
126 if ("200".equals(response.get("code"))) { 126 if ("200".equals(response.get("code"))) {
127 List<UserCardDTO> userCards = new ArrayList<>(); 127 List<UserCardDTO> userCards = new ArrayList<>();
cashier-pipeline/src/main/java/com/diligrp/cashier/pipeline/client/RcbOnlineHttpClient.java
@@ -11,7 +11,6 @@ @@ -11,7 +11,6 @@
11 import com.diligrp.cashier.shared.service.ServiceEndpointSupport; 11 import com.diligrp.cashier.shared.service.ServiceEndpointSupport;
12 import com.diligrp.cashier.shared.util.*; 12 import com.diligrp.cashier.shared.util.*;
13 import com.fasterxml.jackson.core.type.TypeReference; 13 import com.fasterxml.jackson.core.type.TypeReference;
14 - import jakarta.annotation.Resource;  
15 import org.slf4j.Logger; 14 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory; 15 import org.slf4j.LoggerFactory;
17 import org.springframework.dao.DataAccessException; 16 import org.springframework.dao.DataAccessException;
@@ -38,11 +37,6 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport { @@ -38,11 +37,6 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport {
38 37
39 private static final Logger LOG = LoggerFactory.getLogger(RcbOnlineHttpClient.class); 38 private static final Logger LOG = LoggerFactory.getLogger(RcbOnlineHttpClient.class);
40 39
41 - // 微信API BASE URL  
42 - private static final String WECHAT_BASE_URL = "https://api.weixin.qq.com";  
43 - // code2session接口: 根据登录凭证code获取登录信息  
44 - private static final String CODE_TO_SESSION = "/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";  
45 -  
46 private static final int STATUS_OK = 200; 40 private static final int STATUS_OK = 200;
47 41
48 private final String uri; 42 private final String uri;
@@ -89,7 +83,7 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport { @@ -89,7 +83,7 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport {
89 LOG.error("Failed to send rcb MiniPro prepay request: {}", result.statusCode); 83 LOG.error("Failed to send rcb MiniPro prepay request: {}", result.statusCode);
90 throw new PaymentPipelineException(ErrorCode.SYSTEM_UNKNOWN_ERROR, "调用小程序预支付接口失败: " + result.statusCode); 84 throw new PaymentPipelineException(ErrorCode.SYSTEM_UNKNOWN_ERROR, "调用小程序预支付接口失败: " + result.statusCode);
91 } 85 }
92 - LOG.debug("Received from rcb MiniPro pipeline: {}\n{}", request.getPaymentId(), result.responseText); 86 + LOG.debug("Rcb MiniPro prepay received: {}\n{}", request.getPaymentId(), result.responseText);
93 87
94 Map<String, String> data = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {}); 88 Map<String, String> data = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {});
95 String resultCode = data.get("resultCode"); 89 String resultCode = data.get("resultCode");
@@ -117,13 +111,13 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport { @@ -117,13 +111,13 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport {
117 111
118 params.put("sign", RcbSignatureUtils.sign(params, key)); 112 params.put("sign", RcbSignatureUtils.sign(params, key));
119 String payload = JsonUtils.toJsonString(params); 113 String payload = JsonUtils.toJsonString(params);
120 - LOG.info("Sending rcb query prepay order state request: {}", request.getPaymentId()); 114 + LOG.info("Sending query rcb prepay order request: {}", request.getPaymentId());
121 HttpResult result = send(uri + "/cposp/pay/orderQuery", payload); 115 HttpResult result = send(uri + "/cposp/pay/orderQuery", payload);
122 if (result.statusCode != STATUS_OK) { 116 if (result.statusCode != STATUS_OK) {
123 - LOG.error("Failed to query rcb prepay order state: {}", result.statusCode); 117 + LOG.error("Failed to query rcb prepay order: {}", result.statusCode);
124 throw new PaymentPipelineException(ErrorCode.SYSTEM_UNKNOWN_ERROR, "查询支付状态失败: " + result.statusCode); 118 throw new PaymentPipelineException(ErrorCode.SYSTEM_UNKNOWN_ERROR, "查询支付状态失败: " + result.statusCode);
125 } 119 }
126 - LOG.debug("Received from rcb online pipeline: {}\n{}", request.getPaymentId(), result.responseText); 120 + LOG.debug("Query rcb prepay order response received: {}\n{}", request.getPaymentId(), result.responseText);
127 121
128 Map<String, String> data = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {}); 122 Map<String, String> data = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {});
129 String signature = data.remove("sign"); 123 String signature = data.remove("sign");
@@ -175,7 +169,7 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport { @@ -175,7 +169,7 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport {
175 LOG.error("Failed to close rcb prepay order: {}", request.getPaymentId()); 169 LOG.error("Failed to close rcb prepay order: {}", request.getPaymentId());
176 throw new PaymentPipelineException(ErrorCode.SYSTEM_UNKNOWN_ERROR, "关闭支付订单失败: " + result.statusCode); 170 throw new PaymentPipelineException(ErrorCode.SYSTEM_UNKNOWN_ERROR, "关闭支付订单失败: " + result.statusCode);
177 } 171 }
178 - LOG.debug("Received from rcb online pipeline: {}\n{}", request.getPaymentId(), result.responseText); 172 + LOG.debug("Close rcb prepay order response received: {}\n{}", request.getPaymentId(), result.responseText);
179 173
180 Map<String, String> data = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {}); 174 Map<String, String> data = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {});
181 String resultCode = data.get("resultCode"); 175 String resultCode = data.get("resultCode");
@@ -212,7 +206,7 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport { @@ -212,7 +206,7 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport {
212 LOG.error("Failed to send rcb refund request: {}", request.getRefundId()); 206 LOG.error("Failed to send rcb refund request: {}", request.getRefundId());
213 throw new PaymentPipelineException(ErrorCode.SYSTEM_UNKNOWN_ERROR, "发送退款请求失败: " + result.statusCode); 207 throw new PaymentPipelineException(ErrorCode.SYSTEM_UNKNOWN_ERROR, "发送退款请求失败: " + result.statusCode);
214 } 208 }
215 - LOG.debug("Received from rcb online pipeline: {}\n{}", request.getRefundId(), result.responseText); 209 + LOG.debug("Rcb payment refund response received: {}\n{}", request.getRefundId(), result.responseText);
216 210
217 Map<String, String> data = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {}); 211 Map<String, String> data = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {});
218 String resultCode = data.get("resultCode"); 212 String resultCode = data.get("resultCode");
@@ -252,7 +246,7 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport { @@ -252,7 +246,7 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport {
252 LOG.error("Failed to get rcb batch no, statusCode: {}", result.statusCode); 246 LOG.error("Failed to get rcb batch no, statusCode: {}", result.statusCode);
253 throw new PaymentPipelineException(ErrorCode.SYSTEM_UNKNOWN_ERROR, "获取签到批次号: " + result.statusCode); 247 throw new PaymentPipelineException(ErrorCode.SYSTEM_UNKNOWN_ERROR, "获取签到批次号: " + result.statusCode);
254 } 248 }
255 - LOG.debug("Received from rcb online pipeline: {}", result.responseText); 249 + LOG.debug("Rcb signIn response received: {}", result.responseText);
256 250
257 Map<String, String> data = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {}); 251 Map<String, String> data = JsonUtils.fromJsonString(result.responseText, new TypeReference<>() {});
258 String resultCode = data.get("resultCode"); 252 String resultCode = data.get("resultCode");
@@ -262,13 +256,13 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport { @@ -262,13 +256,13 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport {
262 stringRedisTemplate.opsForValue().set(key, batchNo, 36 * 60 * 60, TimeUnit.SECONDS); 256 stringRedisTemplate.opsForValue().set(key, batchNo, 36 * 60 * 60, TimeUnit.SECONDS);
263 return batchNo; 257 return batchNo;
264 } else { 258 } else {
265 - LOG.error("Failed to rcb sign in, errorCode: {}, resultMessage: {}", resultCode, resultMessage);  
266 - throw new PaymentPipelineException(ErrorCode.SERVICE_ACCESS_ERROR, "签到接口调用失败"); 259 + LOG.error("Failed to rcb signIn: {}", result.responseText);
  260 + throw new PaymentPipelineException(ErrorCode.SERVICE_ACCESS_ERROR, "签到接口调用失败: " + resultMessage);
267 } 261 }
268 } catch (ServiceAccessException | PaymentPipelineException rex) { 262 } catch (ServiceAccessException | PaymentPipelineException rex) {
269 throw rex; 263 throw rex;
270 } catch (Exception ex) { 264 } catch (Exception ex) {
271 - LOG.error("Failed to get rcb sign in batchNo", ex); 265 + LOG.error("Failed to rcb signIn", ex);
272 throw new PaymentPipelineException(ErrorCode.SERVICE_ACCESS_ERROR, "获取签到批次号失败"); 266 throw new PaymentPipelineException(ErrorCode.SERVICE_ACCESS_ERROR, "获取签到批次号失败");
273 } 267 }
274 } 268 }
@@ -326,57 +320,4 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport { @@ -326,57 +320,4 @@ public class RcbOnlineHttpClient extends ServiceEndpointSupport {
326 } 320 }
327 return Optional.ofNullable(sslContext); 321 return Optional.ofNullable(sslContext);
328 } 322 }
329 -  
330 - private static class AuthorizationSession {  
331 - // 用户唯一标识  
332 - private String openid;  
333 - // 会话密钥  
334 - private String session_key;  
335 - // 用户在开放平台的唯一标识  
336 - private String unionid;  
337 - // 错误码  
338 - private Integer errcode;  
339 - // 错误信息  
340 - private String errmsg;  
341 -  
342 - public String getOpenid() {  
343 - return openid;  
344 - }  
345 -  
346 - public void setOpenid(String openid) {  
347 - this.openid = openid;  
348 - }  
349 -  
350 - public String getSession_key() {  
351 - return session_key;  
352 - }  
353 -  
354 - public void setSession_key(String session_key) {  
355 - this.session_key = session_key;  
356 - }  
357 -  
358 - public String getUnionid() {  
359 - return unionid;  
360 - }  
361 -  
362 - public void setUnionid(String unionid) {  
363 - this.unionid = unionid;  
364 - }  
365 -  
366 - public Integer getErrcode() {  
367 - return errcode;  
368 - }  
369 -  
370 - public void setErrcode(Integer errcode) {  
371 - this.errcode = errcode;  
372 - }  
373 -  
374 - public String getErrmsg() {  
375 - return errmsg;  
376 - }  
377 -  
378 - public void setErrmsg(String errmsg) {  
379 - this.errmsg = errmsg;  
380 - }  
381 - }  
382 } 323 }
cashier-pipeline/src/main/java/com/diligrp/cashier/pipeline/core/DefaultTimeStrategy.java
@@ -7,10 +7,10 @@ public class DefaultTimeStrategy implements ScanTimeStrategy { @@ -7,10 +7,10 @@ public class DefaultTimeStrategy implements ScanTimeStrategy {
7 private final long[] prepayTimeArray = { 10 * ONE_MINUTE }; 7 private final long[] prepayTimeArray = { 10 * ONE_MINUTE };
8 8
9 // 直接支付订单扫描时间策略 9 // 直接支付订单扫描时间策略
10 - private final long[] paymentTimeArray = {5 * ONE_SECOND, 5 * ONE_SECOND, 5 * ONE_SECOND, 5 * ONE_SECOND, 5 * ONE_SECOND, 5 * ONE_SECOND, 5 * ONE_SECOND, 5 * ONE_SECOND, 10 * ONE_SECOND, 15 * ONE_SECOND}; 10 + private final long[] paymentTimeArray = { 5 * ONE_SECOND, 5 * ONE_SECOND, 5 * ONE_SECOND, 5 * ONE_SECOND, 5 * ONE_SECOND, 5 * ONE_SECOND, 5 * ONE_SECOND, 5 * ONE_SECOND, 10 * ONE_SECOND, 15 * ONE_SECOND };
11 11
12 // 退款订单扫描时间策略 12 // 退款订单扫描时间策略
13 - private final long[] refundTimeArray = { 10 * ONE_MINUTE }; 13 + private final long[] refundTimeArray = { ONE_MINUTE, 2 * ONE_MINUTE, 2 * ONE_MINUTE, 5 * ONE_MINUTE };
14 14
15 @Override 15 @Override
16 public long nextPrepayScanTime(int times) { 16 public long nextPrepayScanTime(int times) {
cashier-shared/src/main/java/com/diligrp/cashier/shared/service/ThreadPoolService.java
1 package com.diligrp.cashier.shared.service; 1 package com.diligrp.cashier.shared.service;
2 2
3 -import java.util.concurrent.ExecutorService;  
4 -import java.util.concurrent.LinkedBlockingQueue;  
5 -import java.util.concurrent.ThreadPoolExecutor;  
6 -import java.util.concurrent.TimeUnit; 3 +import java.util.concurrent.*;
7 4
8 /** 5 /**
9 * 请谨慎使用此线程池工具类,通常建议根据特定的使用场景设置线程池参数,不建议使用统一的线程池配置 6 * 请谨慎使用此线程池工具类,通常建议根据特定的使用场景设置线程池参数,不建议使用统一的线程池配置
10 - * JDK的线程池类并不能很好区分"计算密集型"和"IO密集型"任务类型,根据不同的任务类型去配置不同的参数 7 + * JDK的线程池类并不能很好区分"计算密集型"和"IO密集型"任务类型,应该根据不同的任务类型去配置不同的参数
11 */ 8 */
12 public final class ThreadPoolService { 9 public final class ThreadPoolService {
13 10
@@ -15,7 +12,7 @@ public final class ThreadPoolService { @@ -15,7 +12,7 @@ public final class ThreadPoolService {
15 12
16 private static final int CPU_MAX_POOL_SIZE = 100; 13 private static final int CPU_MAX_POOL_SIZE = 100;
17 14
18 - private static final int IO_MAX_POOL_SIZE = 1000; 15 +// private static final int IO_MAX_POOL_SIZE = 1000;
19 16
20 // CPU运算密集型任务的线程池实例 17 // CPU运算密集型任务的线程池实例
21 private static volatile ExecutorService cpuThreadPoll; 18 private static volatile ExecutorService cpuThreadPoll;
@@ -32,11 +29,11 @@ public final class ThreadPoolService { @@ -32,11 +29,11 @@ public final class ThreadPoolService {
32 */ 29 */
33 public static ExecutorService getCpuThreadPoll() { 30 public static ExecutorService getCpuThreadPoll() {
34 if (cpuThreadPoll == null) { 31 if (cpuThreadPoll == null) {
  32 +
35 synchronized (ThreadPoolService.class) { 33 synchronized (ThreadPoolService.class) {
36 if (cpuThreadPoll == null) { 34 if (cpuThreadPoll == null) {
37 - cpuThreadPoll = new ThreadPoolExecutor(CPU_CORE_NUM + 1, CPU_MAX_POOL_SIZE,  
38 - 20, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100),  
39 - new ThreadPoolExecutor.AbortPolicy()); 35 + cpuThreadPoll = new ThreadPoolExecutor(CPU_CORE_NUM + 1, CPU_MAX_POOL_SIZE, 20,
  36 + TimeUnit.SECONDS, new LinkedBlockingQueue<>(100), new LazyRejectedExecutionHandler());
40 } 37 }
41 } 38 }
42 } 39 }
@@ -51,12 +48,29 @@ public final class ThreadPoolService { @@ -51,12 +48,29 @@ public final class ThreadPoolService {
51 if (ioThreadPoll == null) { 48 if (ioThreadPoll == null) {
52 synchronized (ThreadPoolService.class) { 49 synchronized (ThreadPoolService.class) {
53 if (ioThreadPoll == null) { 50 if (ioThreadPoll == null) {
54 - ioThreadPoll = new ThreadPoolExecutor(CPU_CORE_NUM + 1, IO_MAX_POOL_SIZE,  
55 - 20, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000),  
56 - new ThreadPoolExecutor.AbortPolicy()); 51 + ioThreadPoll = Executors.newVirtualThreadPerTaskExecutor();
  52 +
  53 +// ioThreadPoll = new ThreadPoolExecutor(CPU_CORE_NUM + 1, IO_MAX_POOL_SIZE, 20,
  54 +// TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000), new LazyRejectedExecutionHandler());
57 } 55 }
58 } 56 }
59 } 57 }
60 return ioThreadPoll; 58 return ioThreadPoll;
61 } 59 }
  60 +
  61 + private static class LazyRejectedExecutionHandler implements RejectedExecutionHandler {
  62 + @Override
  63 + public void rejectedExecution(Runnable task, ThreadPoolExecutor executor) {
  64 + boolean success = false;
  65 + try {
  66 + success = executor.getQueue().offer(task, 15, TimeUnit.SECONDS);
  67 + } catch (InterruptedException ex) {
  68 + Thread.currentThread().interrupt();
  69 + }
  70 +
  71 + if (!success) {
  72 + throw new RejectedExecutionException("task queue is full");
  73 + }
  74 + }
  75 + }
62 } 76 }
cashier-trade/src/main/java/com/diligrp/cashier/trade/manager/PaymentResultManager.java
@@ -86,7 +86,7 @@ public class PaymentResultManager { @@ -86,7 +86,7 @@ public class PaymentResultManager {
86 try { 86 try {
87 listener.onEvent(refundEvent); 87 listener.onEvent(refundEvent);
88 } catch (Exception ex) { 88 } catch (Exception ex) {
89 - LOG.error("Failed to notify trade refund result", ex); 89 + LOG.error("Failed to notify payment refund result", ex);
90 } 90 }
91 } 91 }
92 } 92 }
@@ -95,13 +95,13 @@ public class PaymentResultManager { @@ -95,13 +95,13 @@ public class PaymentResultManager {
95 ThreadPoolService.getIoThreadPoll().submit(() -> { 95 ThreadPoolService.getIoThreadPoll().submit(() -> {
96 try { 96 try {
97 String payload = JsonUtils.toJsonString(refundResult); 97 String payload = JsonUtils.toJsonString(refundResult);
98 - LOG.info("Notifying online trade refund result: {}", payload); 98 + LOG.info("Notifying online payment refund result: {}", payload);
99 ServiceEndpointSupport.HttpResult httpResult = new NotifyHttpClient(uri).send(payload); 99 ServiceEndpointSupport.HttpResult httpResult = new NotifyHttpClient(uri).send(payload);
100 if (httpResult.statusCode != 200) { 100 if (httpResult.statusCode != 200) {
101 - LOG.error("Failed to notify trade refund result"); 101 + LOG.error("Failed to notify payment refund result");
102 } 102 }
103 } catch (Exception ex) { 103 } catch (Exception ex) {
104 - LOG.error("Failed to notify trade refund result", ex); 104 + LOG.error("Failed to notify payment refund result", ex);
105 } 105 }
106 }); 106 });
107 } 107 }
cashier-trade/src/main/java/com/diligrp/cashier/trade/manager/TaskMessageConsumer.java
@@ -35,7 +35,7 @@ public class TaskMessageConsumer { @@ -35,7 +35,7 @@ public class TaskMessageConsumer {
35 ? properties.getContentEncoding() : StandardCharsets.UTF_8.name(); 35 ? properties.getContentEncoding() : StandardCharsets.UTF_8.name();
36 try { 36 try {
37 String body = new String(packet, charSet); 37 String body = new String(packet, charSet);
38 - LOG.info("Receiving async delay task message: {}", body); 38 + LOG.debug("Receiving async delay task message: {}", body);
39 TaskMessage task = TaskMessage.fromJson(body); 39 TaskMessage task = TaskMessage.fromJson(body);
40 int times = NumberUtils.str2Int(task.getParams(), Integer.MAX_VALUE); 40 int times = NumberUtils.str2Int(task.getParams(), Integer.MAX_VALUE);
41 if (task.getType() == TaskMessage.TYPE_CASHIER_ORDER_SCAN) { 41 if (task.getType() == TaskMessage.TYPE_CASHIER_ORDER_SCAN) {
cashier-trade/src/main/java/com/diligrp/cashier/trade/manager/TaskMessageSender.java
@@ -19,11 +19,6 @@ public class TaskMessageSender { @@ -19,11 +19,6 @@ public class TaskMessageSender {
19 19
20 private static final Logger LOG = LoggerFactory.getLogger(TaskMessageSender.class); 20 private static final Logger LOG = LoggerFactory.getLogger(TaskMessageSender.class);
21 21
22 - private static final long ONE_MINUTE = 60 * 1000;  
23 -  
24 - private static final long TEN_MINUTES = 10 * ONE_MINUTE;  
25 -  
26 - private static final long ONE_SECOND = 1000;  
27 22
28 @Resource 23 @Resource
29 private RabbitTemplate rabbitTemplate; 24 private RabbitTemplate rabbitTemplate;
@@ -33,7 +28,7 @@ public class TaskMessageSender { @@ -33,7 +28,7 @@ public class TaskMessageSender {
33 */ 28 */
34 public void sendDelayTaskMessage(TaskMessage task, long delayInMillis) { 29 public void sendDelayTaskMessage(TaskMessage task, long delayInMillis) {
35 if (delayInMillis < 0) { 30 if (delayInMillis < 0) {
36 - LOG.info("No need send scan order message: {}", task); 31 + LOG.debug("No need send scan order message: {}", task);
37 return; 32 return;
38 } 33 }
39 34
@@ -47,7 +42,7 @@ public class TaskMessageSender { @@ -47,7 +42,7 @@ public class TaskMessageSender {
47 properties.setHeader("x-delay", String.valueOf(delayInMillis)); 42 properties.setHeader("x-delay", String.valueOf(delayInMillis));
48 String payload = JsonUtils.toJsonString(task); 43 String payload = JsonUtils.toJsonString(task);
49 Message message = new Message(payload.getBytes(StandardCharsets.UTF_8), properties); 44 Message message = new Message(payload.getBytes(StandardCharsets.UTF_8), properties);
50 - LOG.info("Sending async delay task message: {}", task.getPayload()); 45 + LOG.debug("Sending async delay task message: {}", task.getPayload());
51 rabbitTemplate.send(Constants.PAYMENT_DELAY_EXCHANGE, Constants.PAYMENT_DELAY_KEY, message); 46 rabbitTemplate.send(Constants.PAYMENT_DELAY_EXCHANGE, Constants.PAYMENT_DELAY_KEY, message);
52 } catch (Exception ex) { 47 } catch (Exception ex) {
53 LOG.error("Failed to send async delay task message: {}", task.getPayload(), ex); 48 LOG.error("Failed to send async delay task message: {}", task.getPayload(), ex);
cashier-trade/src/main/java/com/diligrp/cashier/trade/service/impl/CashierAssistantServiceImpl.java
@@ -10,7 +10,9 @@ import com.diligrp.cashier.pipeline.service.IPaymentPipelineManager; @@ -10,7 +10,9 @@ import com.diligrp.cashier.pipeline.service.IPaymentPipelineManager;
10 import com.diligrp.cashier.pipeline.type.PaymentState; 10 import com.diligrp.cashier.pipeline.type.PaymentState;
11 import com.diligrp.cashier.trade.Constants; 11 import com.diligrp.cashier.trade.Constants;
12 import com.diligrp.cashier.trade.dao.IOnlinePaymentDao; 12 import com.diligrp.cashier.trade.dao.IOnlinePaymentDao;
  13 +import com.diligrp.cashier.trade.domain.TaskMessage;
13 import com.diligrp.cashier.trade.domain.TradeStateDTO; 14 import com.diligrp.cashier.trade.domain.TradeStateDTO;
  15 +import com.diligrp.cashier.trade.manager.TaskMessageSender;
14 import com.diligrp.cashier.trade.model.OnlinePayment; 16 import com.diligrp.cashier.trade.model.OnlinePayment;
15 import com.diligrp.cashier.trade.model.TradeOrder; 17 import com.diligrp.cashier.trade.model.TradeOrder;
16 import com.diligrp.cashier.trade.service.ICashierAssistantService; 18 import com.diligrp.cashier.trade.service.ICashierAssistantService;
@@ -45,11 +47,14 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService { @@ -45,11 +47,14 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService {
45 private TradeAssistantServiceImpl tradeAssistantService; 47 private TradeAssistantServiceImpl tradeAssistantService;
46 48
47 @Resource 49 @Resource
  50 + private TaskMessageSender taskMessageSender;
  51 +
  52 + @Resource
48 private RedissonClient redissonClient; 53 private RedissonClient redissonClient;
49 54
50 @Override 55 @Override
51 public void scanCashierTradeOrder(String tradeId, int times) { 56 public void scanCashierTradeOrder(String tradeId, int times) {
52 - LOG.debug("scanCashierTradeOrder{}: processing cashier trade order {}", times, tradeId); 57 + LOG.info("scanCashierTradeOrder{}: processing cashier order {}", times, tradeId);
53 String lockKey = String.format(Constants.TRADE_LOCK_REDIS_KEY, tradeId); 58 String lockKey = String.format(Constants.TRADE_LOCK_REDIS_KEY, tradeId);
54 RLock lock = redissonClient.getLock(lockKey); 59 RLock lock = redissonClient.getLock(lockKey);
55 try { 60 try {
@@ -64,12 +69,11 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService { @@ -64,12 +69,11 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService {
64 // 在线支付通道才能关闭订单, 园区卡支付不支持 69 // 在线支付通道才能关闭订单, 园区卡支付不支持
65 if (pipeline instanceof OnlinePipeline<?> onlinePipeline) { 70 if (pipeline instanceof OnlinePipeline<?> onlinePipeline) {
66 OnlinePrepayOrder order = new OnlinePrepayOrder(payment.getPaymentId(), payment.getOutTradeNo()); 71 OnlinePrepayOrder order = new OnlinePrepayOrder(payment.getPaymentId(), payment.getOutTradeNo());
67 - // 微信服务商模式,还需子商户  
68 OnlinePaymentResponse response = onlinePipeline.queryPrepayResponse(order); 72 OnlinePaymentResponse response = onlinePipeline.queryPrepayResponse(order);
69 if (!PaymentState.isFinished(response.getState().getCode())) { 73 if (!PaymentState.isFinished(response.getState().getCode())) {
70 try { 74 try {
71 onlinePipeline.closePrepayOrder(order); 75 onlinePipeline.closePrepayOrder(order);
72 - LOG.info("scanCashierTradeOrder: close online prepay order {}", payment.getPaymentId()); 76 + LOG.debug("scanCashierTradeOrder: close online prepay order {}", payment.getPaymentId());
73 response = new OnlinePaymentResponse(response.getPaymentId(), response.getOutTradeNo(), 77 response = new OnlinePaymentResponse(response.getPaymentId(), response.getOutTradeNo(),
74 response.getOutPayType(), response.getPayerId(), response.getWhen(), 78 response.getOutPayType(), response.getPayerId(), response.getWhen(),
75 PaymentState.FAILED, "自动关闭超时的支付订单"); 79 PaymentState.FAILED, "自动关闭超时的支付订单");
@@ -85,7 +89,9 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService { @@ -85,7 +89,9 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService {
85 if (!TradeState.isFinished(trade.getState())) { 89 if (!TradeState.isFinished(trade.getState())) {
86 TradeStateDTO tradeStateDTO = TradeStateDTO.of(trade.getTradeId(), TradeState.CLOSED, trade.getVersion(), now); 90 TradeStateDTO tradeStateDTO = TradeStateDTO.of(trade.getTradeId(), TradeState.CLOSED, trade.getVersion(), now);
87 tradeAssistantService.proceedTradeOrder(tradeStateDTO); 91 tradeAssistantService.proceedTradeOrder(tradeStateDTO);
88 - LOG.info("scanCashierTradeOrder: close cashier trade order {}", tradeId); 92 + LOG.debug("scanCashierTradeOrder: close cashier order {}", tradeId);
  93 + } else {
  94 + LOG.debug("scanCashierTradeOrder: cashier order {} already accomplished", trade.getTradeId());
89 } 95 }
90 } finally { 96 } finally {
91 if (lock.isHeldByCurrentThread()) { 97 if (lock.isHeldByCurrentThread()) {
@@ -96,10 +102,10 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService { @@ -96,10 +102,10 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService {
96 102
97 @Override 103 @Override
98 public void scanCashierRefundOrder(String refundId, int times) { 104 public void scanCashierRefundOrder(String refundId, int times) {
99 - LOG.debug("scanCashierRefundOrder{}: processing online refund order {}", times, refundId); 105 + LOG.info("scanCashierRefundOrder{}: processing cashier refund order {}", times, refundId);
100 OnlinePayment refund = tradeAssistantService.findByRefundId(refundId); 106 OnlinePayment refund = tradeAssistantService.findByRefundId(refundId);
101 if (PaymentState.isFinished(refund.getState())) { 107 if (PaymentState.isFinished(refund.getState())) {
102 - LOG.debug("scanCashierRefundOrder{}: online refund order {} already accomplished", times, refundId); 108 + LOG.debug("scanCashierRefundOrder{}: cashier refund order {} already accomplished", times, refundId);
103 return; 109 return;
104 } 110 }
105 111
@@ -107,5 +113,10 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService { @@ -107,5 +113,10 @@ public class CashierAssistantServiceImpl implements ICashierAssistantService {
107 OnlineRefundOrder order = new OnlineRefundOrder(refundId, refund.getOutTradeNo()); 113 OnlineRefundOrder order = new OnlineRefundOrder(refundId, refund.getOutTradeNo());
108 OnlineRefundResponse response = pipeline.queryRefundResponse(order); 114 OnlineRefundResponse response = pipeline.queryRefundResponse(order);
109 cashierPaymentService.notifyRefundResult(response); 115 cashierPaymentService.notifyRefundResult(response);
  116 + if (!PaymentState.isFinished(response.getState().getCode())) {
  117 + long delay = pipeline.getTimeStrategy().nextRefundScanTime(times + 1);
  118 + TaskMessage message = new TaskMessage(TaskMessage.TYPE_CASHIER_REFUND_SCAN, refundId, String.valueOf(times + 1));
  119 + taskMessageSender.sendDelayTaskMessage(message, delay);
  120 + }
110 } 121 }
111 } 122 }
cashier-trade/src/main/java/com/diligrp/cashier/trade/service/impl/CashierPaymentServiceImpl.java
@@ -5,6 +5,7 @@ import com.diligrp.cashier.assistant.service.impl.SnowflakeKeyManager; @@ -5,6 +5,7 @@ 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.ScanTimeStrategy;
8 import com.diligrp.cashier.pipeline.domain.*; 9 import com.diligrp.cashier.pipeline.domain.*;
9 import com.diligrp.cashier.pipeline.domain.card.CardPaymentRequest; 10 import com.diligrp.cashier.pipeline.domain.card.CardPaymentRequest;
10 import com.diligrp.cashier.pipeline.domain.card.CardPaymentResponse; 11 import com.diligrp.cashier.pipeline.domain.card.CardPaymentResponse;
@@ -104,19 +105,19 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { @@ -104,19 +105,19 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService {
104 /** 105 /**
105 * 收银台支付 106 * 收银台支付
106 * 107 *
107 - * @param cashierPayment - 支付信息 108 + * @param payment - 支付信息
108 * @return 支付状态 109 * @return 支付状态
109 */ 110 */
110 @Override 111 @Override
111 @Transactional(rollbackFor = Exception.class) 112 @Transactional(rollbackFor = Exception.class)
112 - public OnlinePaymentStatus doPayment(CashierPayment cashierPayment) { 113 + public OnlinePaymentStatus doPayment(CashierPayment payment) {
113 // TODO: 接口防重复提交 114 // TODO: 接口防重复提交
114 - String lockKey = String.format(Constants.TRADE_LOCK_REDIS_KEY, cashierPayment.getTradeId()); 115 + String lockKey = String.format(Constants.TRADE_LOCK_REDIS_KEY, payment.getTradeId());
115 RLock lock = redissonClient.getLock(lockKey); 116 RLock lock = redissonClient.getLock(lockKey);
116 try { 117 try {
117 boolean locked = lock.tryLock(Constants.TRADE_LOCK_TIMEOUT, TimeUnit.SECONDS); 118 boolean locked = lock.tryLock(Constants.TRADE_LOCK_TIMEOUT, TimeUnit.SECONDS);
118 if (locked) { 119 if (locked) {
119 - TradeOrder trade = tradeAssistantService.findByTradeId(cashierPayment.getTradeId()); 120 + TradeOrder trade = tradeAssistantService.findByTradeId(payment.getTradeId());
120 CashierType cashierType = CashierType.getByCode(trade.getType()); 121 CashierType cashierType = CashierType.getByCode(trade.getType());
121 if (TradeState.isFinished(trade.getState())) { 122 if (TradeState.isFinished(trade.getState())) {
122 throw new TradePaymentException(ErrorCode.OPERATION_NOT_ALLOWED, "不能进行支付, 交易订单已经完成"); 123 throw new TradePaymentException(ErrorCode.OPERATION_NOT_ALLOWED, "不能进行支付, 交易订单已经完成");
@@ -125,6 +126,7 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { @@ -125,6 +126,7 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService {
125 if (cashierType != CashierType.MINIPRO) { 126 if (cashierType != CashierType.MINIPRO) {
126 throw new TradePaymentException(ErrorCode.OPERATION_NOT_ALLOWED, "系统当前不支持的此收银台类型"); 127 throw new TradePaymentException(ErrorCode.OPERATION_NOT_ALLOWED, "系统当前不支持的此收银台类型");
127 } 128 }
  129 + LOG.info("Requesting cashier order payment: {}", payment.getTradeId());
128 // 关闭支付中的支付订单, 避免一个交易订单存在多笔支付订单, 造成重复支付 130 // 关闭支付中的支付订单, 避免一个交易订单存在多笔支付订单, 造成重复支付
129 if (!tradeAssistantService.resetTradeOrder(trade)) { 131 if (!tradeAssistantService.resetTradeOrder(trade)) {
130 throw new TradePaymentException(ErrorCode.OPERATION_NOT_ALLOWED, "不能进行支付, 交易订单正在支付中"); 132 throw new TradePaymentException(ErrorCode.OPERATION_NOT_ALLOWED, "不能进行支付, 交易订单正在支付中");
@@ -132,26 +134,26 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { @@ -132,26 +134,26 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService {
132 134
133 LocalDateTime now = LocalDateTime.now(); 135 LocalDateTime now = LocalDateTime.now();
134 // 获取支付通道 136 // 获取支付通道
135 - PaymentPipeline<?> pipeline = paymentPipelineManager.findPipelineById(  
136 - cashierPayment.getPipelineId(), PaymentPipeline.class); 137 + PaymentPipeline<?> pipeline = paymentPipelineManager.findPipelineById(payment.getPipelineId(), PaymentPipeline.class);
137 String paymentId = snowflakeKeyManager.getKeyGenerator(SnowflakeKey.PAYMENT_ID).nextId(); 138 String paymentId = snowflakeKeyManager.getKeyGenerator(SnowflakeKey.PAYMENT_ID).nextId();
138 if (pipeline instanceof OnlinePipeline<?> onlinePipeline) { // 在线支付通道 139 if (pipeline instanceof OnlinePipeline<?> onlinePipeline) { // 在线支付通道
139 // 在线支付通道: 不同的收银台类型使用不同的支付方式(目前只支持小程序收银台) 140 // 在线支付通道: 不同的收银台类型使用不同的支付方式(目前只支持小程序收银台)
140 // 小程序收银台将使用在线支付通道的小程序支付 141 // 小程序收银台将使用在线支付通道的小程序支付
141 - MiniProPrepayRequest request = new MiniProPaymentConverter(trade, paymentId, now).convert(cashierPayment); 142 + MiniProPrepayRequest request = new MiniProPaymentConverter(trade, paymentId, now).convert(payment);
142 MiniProPrepayResponse response = onlinePipeline.sendMiniProPrepayRequest(request); 143 MiniProPrepayResponse response = onlinePipeline.sendMiniProPrepayRequest(request);
143 String outMchId = request.getString(com.diligrp.cashier.pipeline.Constants.PARAM_MCH_ID); 144 String outMchId = request.getString(com.diligrp.cashier.pipeline.Constants.PARAM_MCH_ID);
144 - OnlinePayment payment = OnlinePayment.builder().outMchId(outMchId).tradeId(trade.getTradeId()) 145 + OnlinePayment onlinePayment = OnlinePayment.builder().outMchId(outMchId).tradeId(trade.getTradeId())
145 .type(TradeType.TRADE).paymentId(paymentId).channelId(onlinePipeline.supportedChannel()) 146 .type(TradeType.TRADE).paymentId(paymentId).channelId(onlinePipeline.supportedChannel())
146 .payType(PaymentType.MINI_PRO).pipelineId(onlinePipeline.pipelineId()).goods(trade.getGoods()) 147 .payType(PaymentType.MINI_PRO).pipelineId(onlinePipeline.pipelineId()).goods(trade.getGoods())
147 .amount(trade.getAmount()).payerId(request.getOpenId()).outTradeNo(response.getOutTradeNo()) 148 .amount(trade.getAmount()).payerId(request.getOpenId()).outTradeNo(response.getOutTradeNo())
148 .outPayType(OutPaymentType.NOP).finishTime(null).state(response.getState()) 149 .outPayType(OutPaymentType.NOP).finishTime(null).state(response.getState())
149 .notifyUrl(trade.getNotifyUrl()).description(null).version(0).createdTime(now).modifiedTime(now).build(); 150 .notifyUrl(trade.getNotifyUrl()).description(null).version(0).createdTime(now).modifiedTime(now).build();
150 - onlinePaymentDao.insertOnlinePayment(payment); 151 + onlinePaymentDao.insertOnlinePayment(onlinePayment);
  152 + LOG.debug("Cashier order payment result: {}:{}", response.getPaymentId(), response.getState().name());
151 return response; 153 return response;
152 } else if (pipeline instanceof DiliCardPipeline cardPipeline) { // 园区卡支付通道 154 } else if (pipeline instanceof DiliCardPipeline cardPipeline) { // 园区卡支付通道
153 // 园区卡支付通道: 所有的收银台类型使用的是同一种园区卡支付流程 155 // 园区卡支付通道: 所有的收银台类型使用的是同一种园区卡支付流程
154 - CardPaymentRequest request = new CardPaymentConverter(trade, paymentId, now).convert(cashierPayment); 156 + CardPaymentRequest request = new CardPaymentConverter(trade, paymentId, now).convert(payment);
155 // 园区卡支付需要订单来源 157 // 园区卡支付需要订单来源
156 request.attach("source", SourceType.getIfNonNull(trade.getSource())); 158 request.attach("source", SourceType.getIfNonNull(trade.getSource()));
157 // 修改支付状态为支付中,防止重复支付 159 // 修改支付状态为支付中,防止重复支付
@@ -160,14 +162,14 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { @@ -160,14 +162,14 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService {
160 if (response.getState() == PaymentState.SUCCESS) { 162 if (response.getState() == PaymentState.SUCCESS) {
161 // 园区卡支付通道outMchId为市场ID 163 // 园区卡支付通道outMchId为市场ID
162 String outMchId = request.getString(com.diligrp.cashier.pipeline.Constants.PARAM_MCH_ID); 164 String outMchId = request.getString(com.diligrp.cashier.pipeline.Constants.PARAM_MCH_ID);
163 - OnlinePayment payment = OnlinePayment.builder().outMchId(outMchId).tradeId(trade.getTradeId()) 165 + OnlinePayment onlinePayment = OnlinePayment.builder().outMchId(outMchId).tradeId(trade.getTradeId())
164 .type(TradeType.TRADE).paymentId(paymentId).channelId(cardPipeline.supportedChannel()) 166 .type(TradeType.TRADE).paymentId(paymentId).channelId(cardPipeline.supportedChannel())
165 .payType(PaymentType.DIRECT).pipelineId(cardPipeline.pipelineId()).goods(trade.getGoods()) 167 .payType(PaymentType.DIRECT).pipelineId(cardPipeline.pipelineId()).goods(trade.getGoods())
166 .amount(trade.getAmount()).payerId(response.getPayerId()).outTradeNo(response.getOutTradeNo()) 168 .amount(trade.getAmount()).payerId(response.getPayerId()).outTradeNo(response.getOutTradeNo())
167 .outPayType(response.getOutPayType()).finishTime(response.getWhen()).state(response.getState()) 169 .outPayType(response.getOutPayType()).finishTime(response.getWhen()).state(response.getState())
168 .notifyUrl(trade.getNotifyUrl()).description(response.getMessage()).version(0) 170 .notifyUrl(trade.getNotifyUrl()).description(response.getMessage()).version(0)
169 .createdTime(now).modifiedTime(now).build(); 171 .createdTime(now).modifiedTime(now).build();
170 - onlinePaymentDao.insertOnlinePayment(payment); 172 + onlinePaymentDao.insertOnlinePayment(onlinePayment);
171 173
172 TradeStateDTO tradeStateDTO = TradeStateDTO.of(trade.getTradeId(), TradeState.SUCCESS, 174 TradeStateDTO tradeStateDTO = TradeStateDTO.of(trade.getTradeId(), TradeState.SUCCESS,
173 trade.getVersion(), now); 175 trade.getVersion(), now);
@@ -178,6 +180,7 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { @@ -178,6 +180,7 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService {
178 response.getPayerId(), response.getWhen(), response.getMessage()); 180 response.getPayerId(), response.getWhen(), response.getMessage());
179 paymentResultManager.notifyPaymentResult(trade.getNotifyUrl(), paymentResult, 500); 181 paymentResultManager.notifyPaymentResult(trade.getNotifyUrl(), paymentResult, 500);
180 } 182 }
  183 + LOG.debug("Cashier order payment result: {}:{}", response.getPaymentId(), response.getState().name());
181 return response; 184 return response;
182 } else { 185 } else {
183 // 目前只有两类支付通道: CardPipeline和OnlinePipeline, 程序逻辑不应该到达此代码块 186 // 目前只有两类支付通道: CardPipeline和OnlinePipeline, 程序逻辑不应该到达此代码块
@@ -205,10 +208,10 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { @@ -205,10 +208,10 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService {
205 public void notifyPaymentResponse(OnlinePaymentResponse response) { 208 public void notifyPaymentResponse(OnlinePaymentResponse response) {
206 OnlinePayment payment = tradeAssistantService.findByPaymentId(response.getPaymentId()); 209 OnlinePayment payment = tradeAssistantService.findByPaymentId(response.getPaymentId());
207 if (PaymentState.isFinished(payment.getState())) { 210 if (PaymentState.isFinished(payment.getState())) {
208 - LOG.warn("Duplicate process payment response: [{}:{}]", payment.getPaymentId(), response.getState()); 211 + LOG.warn("Duplicate process cashier payment response: [{}:{}]", payment.getPaymentId(), response.getState().name());
209 return; 212 return;
210 } 213 }
211 - LOG.info("Processing payment response: [{},{}]", payment.getPaymentId(), response.getState()); 214 + LOG.info("Processing cashier payment response: [{},{}]", payment.getPaymentId(), response.getState().name());
212 215
213 if (PaymentState.isFinished(response.getState().getCode())) { 216 if (PaymentState.isFinished(response.getState().getCode())) {
214 LocalDateTime now = LocalDateTime.now(); 217 LocalDateTime now = LocalDateTime.now();
@@ -261,6 +264,7 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { @@ -261,6 +264,7 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService {
261 throw new TradePaymentException(ErrorCode.OPERATION_NOT_ALLOWED, "关闭交易订单失败: 无效的订单状态"); 264 throw new TradePaymentException(ErrorCode.OPERATION_NOT_ALLOWED, "关闭交易订单失败: 无效的订单状态");
262 } 265 }
263 266
  267 + LOG.info("Requesting close cashier trade order: {}", tradeId);
264 LocalDateTime now = LocalDateTime.now(); 268 LocalDateTime now = LocalDateTime.now();
265 // 获取所有支付记录 269 // 获取所有支付记录
266 List<OnlinePayment> onlinePayments = onlinePaymentDao.listOnlinePayments(trade.getTradeId(), 270 List<OnlinePayment> onlinePayments = onlinePaymentDao.listOnlinePayments(trade.getTradeId(),
@@ -326,6 +330,7 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { @@ -326,6 +330,7 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService {
326 TradeType.TRADE.getCode(), PaymentState.SUCCESS.getCode()).stream().findFirst() 330 TradeType.TRADE.getCode(), PaymentState.SUCCESS.getCode()).stream().findFirst()
327 .orElseThrow(() -> new TradePaymentException(ErrorCode.OPERATION_NOT_ALLOWED, "不能进行交易退款: 无支付信息")); 331 .orElseThrow(() -> new TradePaymentException(ErrorCode.OPERATION_NOT_ALLOWED, "不能进行交易退款: 无支付信息"));
328 332
  333 + LOG.info("Requesting cashier payment refund: {}", request.getTradeId());
329 LocalDateTime now = LocalDateTime.now().withNano(0); 334 LocalDateTime now = LocalDateTime.now().withNano(0);
330 KeyGenerator refundIdKey = snowflakeKeyManager.getKeyGenerator(SnowflakeKey.PAYMENT_ID); 335 KeyGenerator refundIdKey = snowflakeKeyManager.getKeyGenerator(SnowflakeKey.PAYMENT_ID);
331 String refundId = refundIdKey.nextId(); 336 String refundId = refundIdKey.nextId();
@@ -341,6 +346,7 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { @@ -341,6 +346,7 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService {
341 throw new TradePaymentException(ErrorCode.OPERATION_NOT_ALLOWED, "不支持的支付通道"); 346 throw new TradePaymentException(ErrorCode.OPERATION_NOT_ALLOWED, "不支持的支付通道");
342 } 347 }
343 348
  349 + LOG.debug("Cashier payment refund result: [{}:{}]", trade.getTradeId(), response.getState().name());
344 OnlinePayment refund = OnlinePayment.builder().outMchId(payment.getOutMchId()).tradeId(payment.getTradeId()) 350 OnlinePayment refund = OnlinePayment.builder().outMchId(payment.getOutMchId()).tradeId(payment.getTradeId())
345 .type(TradeType.REFUND).paymentId(refundId).channelId(payment.getChannelId()) 351 .type(TradeType.REFUND).paymentId(refundId).channelId(payment.getChannelId())
346 .payType(payment.getPayType()).pipelineId(payment.getPipelineId()).goods(payment.getGoods() + "-退款") 352 .payType(payment.getPayType()).pipelineId(payment.getPipelineId()).goods(payment.getGoods() + "-退款")
@@ -356,8 +362,11 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { @@ -356,8 +362,11 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService {
356 tradeAssistantService.proceedTradeOrder(tradeState); 362 tradeAssistantService.proceedTradeOrder(tradeState);
357 } else if (!PaymentState.isFinished(response.getState().getCode())) { 363 } else if (!PaymentState.isFinished(response.getState().getCode())) {
358 // 固定周期后,查询退款状态,根据状态完成退款订单 364 // 固定周期后,查询退款状态,根据状态完成退款订单
359 - TaskMessage message = new TaskMessage(TaskMessage.TYPE_CASHIER_REFUND_SCAN, refundId, "1");  
360 - taskMessageSender.sendDelayTaskMessage(message, trade.getTimeout() * 1000); 365 + if (pipeline instanceof OnlinePipeline<?> onlinePipeline) { // 只有在线支付通道允许查询退款状态
  366 + long delay = onlinePipeline.getTimeStrategy().nextRefundScanTime(1);
  367 + TaskMessage message = new TaskMessage(TaskMessage.TYPE_CASHIER_REFUND_SCAN, refundId, "1");
  368 + taskMessageSender.sendDelayTaskMessage(message, delay);
  369 + }
361 } 370 }
362 371
363 return new OnlineRefundResult(refundId, payment.getPaymentId(), response.getState().getCode(), 372 return new OnlineRefundResult(refundId, payment.getPaymentId(), response.getState().getCode(),
@@ -369,14 +378,14 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService { @@ -369,14 +378,14 @@ public class CashierPaymentServiceImpl implements ICashierPaymentService {
369 public void notifyRefundResult(OnlineRefundResponse response) { 378 public void notifyRefundResult(OnlineRefundResponse response) {
370 OnlinePayment refund = tradeAssistantService.findByRefundId(response.getRefundId()); 379 OnlinePayment refund = tradeAssistantService.findByRefundId(response.getRefundId());
371 if (PaymentState.isFinished(refund.getState())) { 380 if (PaymentState.isFinished(refund.getState())) {
372 - LOG.warn("Duplicate process online refund order[{}:{}]", response.getRefundId(), response.getState()); 381 + LOG.warn("Duplicate process cashier refund response: [{}:{}]", response.getRefundId(), response.getState().name());
373 return; 382 return;
374 } 383 }
375 if (!PaymentState.isFinished(response.getState().getCode())) { 384 if (!PaymentState.isFinished(response.getState().getCode())) {
376 - LOG.warn("Ignore online refund order[{}:{}]", response.getRefundId(), response.getState()); 385 + LOG.warn("Ignore cashier refund response: [{}:{}]", response.getRefundId(), response.getState().name());
377 return; 386 return;
378 } 387 }
379 - LOG.info("Processing online refund order[{}:{}]", response.getRefundId(), response.getState()); 388 + LOG.info("Processing cashier refund response: [{}:{}]", response.getRefundId(), response.getState().name());
380 389
381 LocalDateTime now = LocalDateTime.now(); 390 LocalDateTime now = LocalDateTime.now();
382 TradeOrder trade = tradeAssistantService.findByTradeId(refund.getTradeId()); 391 TradeOrder trade = tradeAssistantService.findByTradeId(refund.getTradeId());
cashier-trade/src/main/java/com/diligrp/cashier/trade/service/impl/TradeAssistantServiceImpl.java
@@ -65,7 +65,7 @@ public class TradeAssistantServiceImpl implements ITradeAssistantService { @@ -65,7 +65,7 @@ public class TradeAssistantServiceImpl implements ITradeAssistantService {
65 List<OnlinePayment> onlinePayments = onlinePaymentDao.listOnlinePayments(trade.getTradeId(), TradeType.TRADE.getCode(), null); 65 List<OnlinePayment> onlinePayments = onlinePaymentDao.listOnlinePayments(trade.getTradeId(), TradeType.TRADE.getCode(), null);
66 for (OnlinePayment payment : onlinePayments) { 66 for (OnlinePayment payment : onlinePayments) {
67 if (!PaymentState.isFinished(payment.getState())) { 67 if (!PaymentState.isFinished(payment.getState())) {
68 - LOG.info("Trying to close payment order in process: {}", payment.getPaymentId()); 68 + LOG.debug("Trying to close payment order in process: {}", payment.getPaymentId());
69 PaymentPipeline<?> pipeline = paymentPipelineManager.findPipelineById(payment.getPipelineId(), PaymentPipeline.class); 69 PaymentPipeline<?> pipeline = paymentPipelineManager.findPipelineById(payment.getPipelineId(), PaymentPipeline.class);
70 if (pipeline instanceof OnlinePipeline<?> onlinePipeline) { 70 if (pipeline instanceof OnlinePipeline<?> onlinePipeline) {
71 // 理论上只存在一条支付中的支付记录,否则后面的支付通道关闭失败时,会回滚前面支付记录的状态修改 71 // 理论上只存在一条支付中的支付记录,否则后面的支付通道关闭失败时,会回滚前面支付记录的状态修改