From 656d6f8029f8bf9b2daa9dcc89101a879a70b860 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期三, 03 十二月 2025 23:10:05 +0800
Subject: [PATCH] feat:优先添加执行人
---
dryad-payment/src/main/java/com/ruoyi/payment/application/service/PaymentService.java | 307 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 304 insertions(+), 3 deletions(-)
diff --git a/dryad-payment/src/main/java/com/ruoyi/payment/application/service/PaymentService.java b/dryad-payment/src/main/java/com/ruoyi/payment/application/service/PaymentService.java
index 3b44a9b..98f9c28 100644
--- a/dryad-payment/src/main/java/com/ruoyi/payment/application/service/PaymentService.java
+++ b/dryad-payment/src/main/java/com/ruoyi/payment/application/service/PaymentService.java
@@ -12,6 +12,7 @@
import com.ruoyi.payment.infrastructure.channel.wechat.WxPayV2Client;
import com.ruoyi.payment.infrastructure.config.AlipayConfig;
import com.ruoyi.payment.infrastructure.config.QrCodeConfig;
+import com.ruoyi.payment.infrastructure.config.WechatPayConfig;
import com.ruoyi.payment.infrastructure.persistence.mapper.PaymentOrderMapper;
import com.ruoyi.payment.infrastructure.persistence.mapper.PaymentTransactionMapper;
import com.ruoyi.payment.infrastructure.util.QrCodeUtil;
@@ -60,6 +61,9 @@
@Autowired
private AlipayConfig alipayConfig;
+ @Autowired
+ private WechatPayConfig wechatPayConfig;
+
/**
* 鍙戣捣寰俊Native鏀粯
*/
@@ -99,6 +103,7 @@
requestParams.put("bizOrderId", request.getBizOrderId());
requestParams.put("amount", request.getAmount());
requestParams.put("subject", request.getSubject());
+ requestParams.put("notifyUrl",wechatPayConfig.getNotifyUrl());
transaction.setRequestParams(JSON.toJSONString(requestParams));
paymentTransactionMapper.insert(transaction);
@@ -150,6 +155,7 @@
requestParams.put("bizOrderId", request.getBizOrderId());
requestParams.put("amount", request.getAmount());
requestParams.put("subject", request.getSubject());
+ requestParams.put("notifyUrl",alipayConfig.getNotifyUrl());
transaction.setRequestParams(JSON.toJSONString(requestParams));
paymentTransactionMapper.insert(transaction);
@@ -202,6 +208,7 @@
requestParams.put("amount", request.getAmount());
requestParams.put("subject", request.getSubject());
requestParams.put("thirdParty", true);
+ requestParams.put("notifyUrl",alipayConfig.getThirdParty().getDefaultNotifyUrl());
transaction.setRequestParams(JSON.toJSONString(requestParams));
paymentTransactionMapper.insert(transaction);
@@ -283,11 +290,11 @@
private String callAlipayThirdPartyPrecreate(PaymentOrder order, PaymentRequest request) {
try {
// 浣跨敤AlipayConfig涓厤缃殑鍥炶皟鍦板潃
- String notifyUrl = alipayConfig.getNotifyUrl();
+ String notifyUrl = alipayConfig.getThirdParty().getDefaultNotifyUrl();
String outTradeNo = String.valueOf(order.getId());
Integer totalFee = order.getAmount(); // 鍗曚綅锛氬垎
String serviceOrdId = request.getBizOrderId(); // 涓氬姟璁㈠崟ID
-
+
return alipayThirdPartyClient.createQrCodeUrl(notifyUrl, outTradeNo, totalFee, serviceOrdId);
} catch (Exception e) {
log.error("璋冪敤绗笁鏂规敮浠樺疂鎺ュ彛澶辫触", e);
@@ -335,4 +342,298 @@
throw new RuntimeException("鏌ヨ浜ゆ槗鐘舵�佸け璐�: " + e.getMessage(), e);
}
}
-}
+
+ /**
+ * 杞鏌ヨ鏀粯鐘舵�侊紙鐢ㄤ簬鍥炶皟澶辫触鐨勮ˉ鍋挎満鍒讹級
+ * 鏀寔寰俊鍜屾敮浠樺疂
+ *
+ * @param orderId 璁㈠崟ID
+ * @return 杞缁撴灉锛堝寘鍚鍗曠姸鎬佸拰浜ゆ槗鐘舵�侊級
+ */
+ @Transactional(rollbackFor = Exception.class)
+ public Map<String, Object> pollPaymentStatus(Long orderId) {
+ log.info("寮�濮嬭疆璇㈡煡璇㈡敮浠樼姸鎬侊紝璁㈠崟ID: {}", orderId);
+
+ Map<String, Object> result = new HashMap<>();
+
+ // 1. 鏌ヨ璁㈠崟淇℃伅
+ PaymentOrder order = paymentOrderMapper.selectById(orderId);
+ if (order == null) {
+ log.error("璁㈠崟涓嶅瓨鍦紝璁㈠崟ID: {}", orderId);
+ throw new RuntimeException("璁㈠崟涓嶅瓨鍦�");
+ }
+
+ // 濡傛灉璁㈠崟宸茬粡鏄垚鍔熺姸鎬侊紝鐩存帴杩斿洖
+ if (OrderStatus.SUCCEEDED.getCode().equals(order.getStatus())) {
+ log.info("璁㈠崟宸叉垚鍔燂紝鏃犻渶杞锛岃鍗旾D: {}", orderId);
+ result.put("orderStatus", order.getStatus());
+ result.put("needPoll", false);
+ result.put("message", "璁㈠崟宸叉垚鍔�");
+ return result;
+ }
+
+ // 2. 鏌ヨ鏈�鏂颁氦鏄撹褰�
+ PaymentTransaction transaction = paymentTransactionMapper.selectLatestByOrderId(orderId);
+ if (transaction == null) {
+ log.error("鏈壘鍒颁氦鏄撹褰曪紝璁㈠崟ID: {}", orderId);
+ throw new RuntimeException("鏈壘鍒颁氦鏄撹褰�");
+ }
+
+ // 濡傛灉浜ゆ槗宸叉垚鍔燂紝浣嗚鍗曠姸鎬佹湭鏇存柊锛屾洿鏂拌鍗曠姸鎬�
+ if (TransactionStatus.SUCCEEDED.getCode().equals(transaction.getStatus())) {
+ log.info("浜ゆ槗宸叉垚鍔燂紝鍚屾璁㈠崟鐘舵�侊紝璁㈠崟ID: {}", orderId);
+ order.setStatus(OrderStatus.SUCCEEDED.getCode());
+ order.setUpdatedAt(LocalDateTime.now());
+ paymentOrderMapper.update(order);
+
+ result.put("orderStatus", OrderStatus.SUCCEEDED.getCode());
+ result.put("transactionStatus", transaction.getStatus());
+ result.put("needPoll", false);
+ result.put("message", "鏀粯鎴愬姛");
+ return result;
+ }
+
+ // 3. 鏍规嵁鏀粯娓犻亾璋冪敤鐩稿簲鐨勬煡璇㈡帴鍙�
+ String channel = order.getChannel();
+ boolean paymentSuccess = false;
+ String tradeStatus = null;
+
+ try {
+ if (PayChannel.WECHAT.getCode().equals(channel)) {
+ // 鏌ヨ寰俊鏀粯鐘舵��
+ paymentSuccess = queryWechatPaymentStatus(order, transaction);
+ tradeStatus = paymentSuccess ? "SUCCESS" : "NOTPAY";
+ result.put("paymethod","WECHAT");
+ } else if (PayChannel.ALIPAY.getCode().equals(channel)) {
+ // 鍒ゆ柇鏄惁涓虹涓夋柟鏀粯瀹�
+ boolean isThirdParty = isThirdPartyAlipay(transaction);
+ result.put("paymethod","ALIPAY");
+ if (isThirdParty) {
+ // 鏌ヨ绗笁鏂规敮浠樺疂鐘舵��
+ tradeStatus = queryAlipayThirdPartyTradeStatus(orderId);
+ paymentSuccess = "SUCCESS".equals(tradeStatus);
+ } else {
+ // 鏌ヨ瀹樻柟鏀粯瀹濈姸鎬�
+ paymentSuccess = queryAlipayPaymentStatus(order, transaction);
+ tradeStatus = paymentSuccess ? "TRADE_SUCCESS" : "WAIT_BUYER_PAY";
+ }
+ } else {
+ log.error("涓嶆敮鎸佺殑鏀粯娓犻亾: {}", channel);
+ throw new RuntimeException("涓嶆敮鎸佺殑鏀粯娓犻亾");
+ }
+ } catch (Exception e) {
+ log.error("鏌ヨ鏀粯鐘舵�佸紓甯革紝璁㈠崟ID: {}", orderId, e);
+ result.put("orderStatus", order.getStatus());
+ result.put("transactionStatus", transaction.getStatus());
+ result.put("needPoll", true);
+ result.put("error", e.getMessage());
+ result.put("message", "鏌ヨ寮傚父锛岃绋嶅悗閲嶈瘯");
+ return result;
+ }
+
+ // 4. 濡傛灉鏀粯鎴愬姛锛屾洿鏂拌鍗曞拰浜ゆ槗鐘舵��
+ if (paymentSuccess) {
+ log.info("杞鏌ヨ鍙戠幇鏀粯鎴愬姛锛岃鍗旾D: {}, 浜ゆ槗鐘舵��: {}", orderId, tradeStatus);
+
+ // 鏇存柊浜ゆ槗鐘舵��
+ transaction.setStatus(TransactionStatus.SUCCEEDED.getCode());
+ transaction.setPaidAt(LocalDateTime.now());
+ paymentTransactionMapper.update(transaction);
+
+ // 鏇存柊璁㈠崟鐘舵��
+ order.setStatus(OrderStatus.SUCCEEDED.getCode());
+ order.setUpdatedAt(LocalDateTime.now());
+ paymentOrderMapper.update(order);
+
+ result.put("orderStatus", OrderStatus.SUCCEEDED.getCode());
+ result.put("transactionStatus", TransactionStatus.SUCCEEDED.getCode());
+ result.put("tradeStatus", tradeStatus);
+ result.put("needPoll", false);
+ result.put("message", "鏀粯鎴愬姛");
+
+ log.info("杞鏌ヨ澶勭悊瀹屾垚锛岃鍗曞拰浜ゆ槗鐘舵�佸凡鏇存柊锛岃鍗旾D: {}", orderId);
+ } else {
+ log.info("杞鏌ヨ锛屾敮浠樺皻鏈畬鎴愶紝璁㈠崟ID: {}, 浜ゆ槗鐘舵��: {}", orderId, tradeStatus);
+ result.put("orderStatus", order.getStatus());
+ result.put("transactionStatus", transaction.getStatus());
+ result.put("tradeStatus", tradeStatus);
+ result.put("needPoll", true);
+ result.put("message", "鏀粯灏氭湭瀹屾垚锛岃缁х画杞");
+ }
+
+ return result;
+ }
+
+ /**
+ * 鏌ヨ寰俊鏀粯鐘舵��
+ */
+ private boolean queryWechatPaymentStatus(PaymentOrder order, PaymentTransaction transaction) throws Exception {
+ log.info("鏌ヨ寰俊鏀粯鐘舵�侊紝璁㈠崟ID: {}", order.getId());
+
+ String outTradeNo = String.valueOf(order.getId());
+ Map<String, String> queryResult = wxPayV2Client.queryOrder(outTradeNo);
+
+ // 妫�鏌ヤ笟鍔$粨鏋�
+ if (!"SUCCESS".equals(queryResult.get("result_code"))) {
+ log.warn("寰俊璁㈠崟鏌ヨ涓氬姟澶辫触: {}", queryResult.get("err_code_des"));
+ return false;
+ }
+
+ // 妫�鏌ヤ氦鏄撶姸鎬�
+ String tradeState = queryResult.get("trade_state");
+ log.info("寰俊璁㈠崟鐘舵��: {}", tradeState);
+
+ return "SUCCESS".equals(tradeState);
+ }
+
+ /**
+ * 鏌ヨ鏀粯瀹濇敮浠樼姸鎬侊紙瀹樻柟鎺ュ彛锛�
+ */
+ private boolean queryAlipayPaymentStatus(PaymentOrder order, PaymentTransaction transaction) throws Exception {
+ log.info("鏌ヨ鏀粯瀹濇敮浠樼姸鎬侊紝璁㈠崟ID: {}", order.getId());
+
+ String outTradeNo = String.valueOf(order.getId());
+ com.alipay.api.response.AlipayTradeQueryResponse queryResult = alipayF2FClient.queryOrder(outTradeNo);
+
+ // 妫�鏌ヤ氦鏄撶姸鎬�
+ String tradeStatus = queryResult.getTradeStatus();
+ log.info("鏀粯瀹濊鍗曠姸鎬�: {}", tradeStatus);
+ log.info("鏀粯瀹濊鍗曟煡璇㈢粨鏋�: {}", queryResult.getBody());
+ // TRADE_SUCCESS 鎴� TRADE_FINISHED 琛ㄧず鏀粯鎴愬姛
+ return "TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus);
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁涓虹涓夋柟鏀粯瀹�
+ */
+ private boolean isThirdPartyAlipay(PaymentTransaction transaction) {
+ if (transaction.getRequestParams() == null) {
+ return false;
+ }
+ try {
+ Map<String, Object> params = JSON.parseObject(transaction.getRequestParams(), Map.class);
+ return params.containsKey("thirdParty") && Boolean.TRUE.equals(params.get("thirdParty"));
+ } catch (Exception e) {
+ log.warn("瑙f瀽浜ゆ槗璇锋眰鍙傛暟澶辫触", e);
+ return false;
+ }
+ }
+
+ /**
+ * 鏍规嵁浜ゆ槗鍗曞彿鏌ヨ寰俊鏀粯鐘舵��
+ *
+ * @param outTradeNo 鍟嗘埛璁㈠崟鍙凤紙浜ゆ槗鍗曞彿锛�
+ * @return 浜ゆ槗鐘舵�佷俊鎭�
+ */
+ public Map<String, Object> queryWechatTradeByOutTradeNo(String outTradeNo) {
+ log.info("鏍规嵁浜ゆ槗鍗曞彿鏌ヨ寰俊鏀粯鐘舵�侊紝鍟嗘埛璁㈠崟鍙�: {}", outTradeNo);
+
+ Map<String, Object> result = new HashMap<>();
+
+ try {
+ Map<String, String> queryResult = wxPayV2Client.queryOrder(outTradeNo);
+
+ // 妫�鏌ヨ皟鐢ㄦ槸鍚︽垚鍔�
+ if (!"SUCCESS".equals(queryResult.get("return_code"))) {
+ result.put("success", false);
+ result.put("message", "寰俊鏌ヨ鎺ュ彛璋冪敤澶辫触: " + queryResult.get("return_msg"));
+ return result;
+ }
+
+ // 妫�鏌ヤ笟鍔$粨鏋�
+ if (!"SUCCESS".equals(queryResult.get("result_code"))) {
+ result.put("success", false);
+ result.put("message", "寰俊璁㈠崟鏌ヨ涓氬姟澶辫触: " + queryResult.get("err_code_des"));
+ result.put("errorCode", queryResult.get("err_code"));
+ return result;
+ }
+
+ // 杩斿洖浜ゆ槗淇℃伅
+ result.put("success", true);
+ result.put("tradeState", queryResult.get("trade_state")); // 浜ゆ槗鐘舵��
+ result.put("tradeStateDesc", queryResult.get("trade_state_desc")); // 浜ゆ槗鐘舵�佹弿杩�
+ result.put("outTradeNo", queryResult.get("out_trade_no")); // 鍟嗘埛璁㈠崟鍙�
+ result.put("transactionId", queryResult.get("transaction_id")); // 寰俊鏀粯璁㈠崟鍙�
+ result.put("totalFee", queryResult.get("total_fee")); // 璁㈠崟閲戦锛堝垎锛�
+ result.put("timeEnd", queryResult.get("time_end")); // 鏀粯瀹屾垚鏃堕棿
+ result.put("openid", queryResult.get("openid")); // 鐢ㄦ埛鏍囪瘑
+
+ // 鍒ゆ柇鏄惁鏀粯鎴愬姛
+ boolean isPaid = "SUCCESS".equals(queryResult.get("trade_state"));
+ result.put("isPaid", isPaid);
+ result.put("message", isPaid ? "鏀粯鎴愬姛" : "鏀粯鏈畬鎴�");
+
+ log.info("寰俊浜ゆ槗鏌ヨ鎴愬姛锛屼氦鏄撶姸鎬�: {}", queryResult.get("trade_state"));
+
+ } catch (Exception e) {
+ log.error("鏌ヨ寰俊浜ゆ槗鐘舵�佸紓甯革紝鍟嗘埛璁㈠崟鍙�: {}", outTradeNo, e);
+ result.put("success", false);
+ result.put("message", "鏌ヨ寮傚父: " + e.getMessage());
+ }
+
+ return result;
+ }
+
+ /**
+ * 鏍规嵁浜ゆ槗鍗曞彿鏌ヨ鏀粯瀹濇敮浠樼姸鎬�
+ *
+ * @param outTradeNo 鍟嗘埛璁㈠崟鍙凤紙浜ゆ槗鍗曞彿锛�
+ * @return 浜ゆ槗鐘舵�佷俊鎭�
+ */
+ public Map<String, Object> queryAlipayTradeByOutTradeNo(String outTradeNo) {
+ log.info("鏍规嵁浜ゆ槗鍗曞彿鏌ヨ鏀粯瀹濇敮浠樼姸鎬侊紝鍟嗘埛璁㈠崟鍙�: {}", outTradeNo);
+
+ Map<String, Object> result = new HashMap<>();
+
+ try {
+ com.alipay.api.response.AlipayTradeQueryResponse queryResult = alipayF2FClient.queryOrder(outTradeNo);
+
+ // 妫�鏌ヨ皟鐢ㄦ槸鍚︽垚鍔�
+ if (!queryResult.isSuccess()) {
+ result.put("success", false);
+ result.put("message", "鏀粯瀹濇煡璇㈠け璐�: " + queryResult.getSubMsg());
+ result.put("errorCode", queryResult.getSubCode());
+ return result;
+ }
+
+ // 杩斿洖浜ゆ槗淇℃伅
+ result.put("success", true);
+ result.put("tradeStatus", queryResult.getTradeStatus()); // 浜ゆ槗鐘舵��
+ result.put("outTradeNo", queryResult.getOutTradeNo()); // 鍟嗘埛璁㈠崟鍙�
+ result.put("tradeNo", queryResult.getTradeNo()); // 鏀粯瀹濅氦鏄撳彿
+ result.put("totalAmount", queryResult.getTotalAmount()); // 璁㈠崟閲戦锛堝厓锛�
+ result.put("buyerPayAmount", queryResult.getBuyerPayAmount()); // 涔板瀹為檯鏀粯閲戦
+ result.put("sendPayDate", queryResult.getSendPayDate()); // 浜ゆ槗鏀粯鏃堕棿
+ result.put("buyerLogonId", queryResult.getBuyerLogonId()); // 涔板鏀粯瀹濊处鍙�
+
+ // 鍒ゆ柇鏄惁鏀粯鎴愬姛
+ String tradeStatus = queryResult.getTradeStatus();
+ boolean isPaid = "TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus);
+ result.put("isPaid", isPaid);
+
+ // 鐘舵�佽鏄�
+ String message;
+ if ("TRADE_SUCCESS".equals(tradeStatus)) {
+ message = "浜ゆ槗鏀粯鎴愬姛";
+ } else if ("TRADE_FINISHED".equals(tradeStatus)) {
+ message = "浜ゆ槗缁撴潫锛屼笉鍙��娆�";
+ } else if ("WAIT_BUYER_PAY".equals(tradeStatus)) {
+ message = "浜ゆ槗鍒涘缓锛岀瓑寰呬拱瀹朵粯娆�";
+ } else if ("TRADE_CLOSED".equals(tradeStatus)) {
+ message = "鏈粯娆句氦鏄撹秴鏃跺叧闂紝鎴栨敮浠樺畬鎴愬悗鍏ㄩ閫�娆�";
+ } else {
+ message = "鏈煡鐘舵��: " + tradeStatus;
+ }
+ result.put("message", message);
+
+ log.info("鏀粯瀹濅氦鏄撴煡璇㈡垚鍔燂紝浜ゆ槗鐘舵��: {}", tradeStatus);
+
+ } catch (Exception e) {
+ log.error("鏌ヨ鏀粯瀹濅氦鏄撶姸鎬佸紓甯革紝鍟嗘埛璁㈠崟鍙�: {}", outTradeNo, e);
+ result.put("success", false);
+ result.put("message", "鏌ヨ寮傚父: " + e.getMessage());
+ }
+
+ return result;
+ }
+}
\ No newline at end of file
--
Gitblit v1.9.1