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/PaymentNotifyService.java | 274 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 272 insertions(+), 2 deletions(-)
diff --git a/dryad-payment/src/main/java/com/ruoyi/payment/application/service/PaymentNotifyService.java b/dryad-payment/src/main/java/com/ruoyi/payment/application/service/PaymentNotifyService.java
index c4a8ff4..506f6f5 100644
--- a/dryad-payment/src/main/java/com/ruoyi/payment/application/service/PaymentNotifyService.java
+++ b/dryad-payment/src/main/java/com/ruoyi/payment/application/service/PaymentNotifyService.java
@@ -62,7 +62,7 @@
// 閫氫俊鎴愬姛涓斾笟鍔℃垚鍔�
if ("SUCCESS".equals(returnCode) && "SUCCESS".equals(resultCode)) {
// 鏌ヨ璁㈠崟鍜屼氦鏄擄紙浣跨敤涓氬姟璁㈠崟鍙锋煡璇級
- PaymentOrder order = paymentOrderMapper.selectByBizOrderIdAndChannel(outTradeNo, "WECHAT");
+ PaymentOrder order = paymentOrderMapper.selectById(Long.parseLong(outTradeNo));
if (order == null) {
log.error("璁㈠崟涓嶅瓨鍦�: {}", outTradeNo);
updateNotifyLog(notifyLog.getId(), false, "璁㈠崟涓嶅瓨鍦�");
@@ -134,7 +134,7 @@
// 浜ゆ槗鎴愬姛
if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
// 鏌ヨ璁㈠崟鍜屼氦鏄擄紙浣跨敤涓氬姟璁㈠崟鍙锋煡璇級
- PaymentOrder order = paymentOrderMapper.selectByBizOrderIdAndChannel(outTradeNo, "ALIPAY");
+ PaymentOrder order = paymentOrderMapper.selectById(Long.parseLong(outTradeNo));
if (order == null) {
log.error("璁㈠崟涓嶅瓨鍦�: {}", outTradeNo);
updateNotifyLog(notifyLog.getId(), false, "璁㈠崟涓嶅瓨鍦�");
@@ -183,6 +183,276 @@
}
/**
+ * 澶勭悊绗笁鏂规敮浠樺疂鍥炶皟
+ * 绗笁鏂规敮浠樺疂閫氳繃GET鏂瑰紡鍥炶皟锛屽弬鏁伴�氳繃URL浼犻��
+ *
+ * 鍙傛暟鏍煎紡锛�
+ * method: 鏂规硶鍚�
+ * APPID: 搴旂敤ID
+ * PaidMoneyType: 鏀粯绫诲瀷
+ * PaidMoney: 鏀粯閲戦锛堝垎锛�
+ * PaidRemarks: 鏀粯澶囨敞锛堝寘鍚玹ransaction_id锛�
+ * UnixTime: 鏃堕棿鎴�
+ * Sign: 绛惧悕
+ */
+ @Transactional(rollbackFor = Exception.class)
+ public void processAlipayThirdPartyNotify(Map<String, String> params) {
+ String method = params.get("method"); // 鏂规硶鍚�
+ String appId = params.get("APPID"); // 搴旂敤ID
+ String paidMoneyType = params.get("PaidMoneyType"); // 鏀粯绫诲瀷
+ String paidMoney = params.get("PaidMoney"); // 鏀粯閲戦锛堝垎锛�
+ String paidRemarks = params.get("PaidRemarks"); // 鏀粯澶囨敞锛堝彲鑳藉寘鍚鍗曞彿鍜屼氦鏄撳彿锛�
+ String unixTime = params.get("UnixTime"); // 鏃堕棿鎴�
+ String sign = params.get("Sign"); // 绛惧悕
+
+ log.info("澶勭悊绗笁鏂规敮浠樺疂鍥炶皟锛宮ethod: {}, APPID: {}, PaidMoneyType: {}, PaidMoney: {}, PaidRemarks: {}, UnixTime: {}, Sign: {}",
+ method, appId, paidMoneyType, paidMoney, paidRemarks, unixTime, sign);
+ log.info("绗笁鏂规敮浠樺疂鍥炶皟瀹屾暣鍙傛暟: {}", params);
+
+ // 浠嶱aidRemarks涓彁鍙栬鍗曞彿锛坥ut_trade_no锛�
+ // PaidRemarks鏍煎紡鍙兘鏄�: "璁㈠崟鍙�+浜ゆ槗鍙�" 鎴栧叾浠栨牸寮忥紝闇�瑕佽В鏋�
+ String outTradeNo = extractOutTradeNo(paidRemarks);
+ String transactionId = extractTransactionId(paidRemarks);
+
+ if (outTradeNo == null || outTradeNo.isEmpty()) {
+ log.error("鏃犳硶浠嶱aidRemarks涓彁鍙栬鍗曞彿: {}", paidRemarks);
+ return;
+ }
+
+ log.info("瑙f瀽鍑鸿鍗曞彿: {}, 浜ゆ槗鍙�: {}", outTradeNo, transactionId);
+
+ // 妫�鏌ュ箓绛夋�э紙浣跨敤璁㈠崟鍙锋垨绛惧悕锛�
+ String notifyId = transactionId != null ? transactionId : sign;
+ if (isNotifyProcessed("ALIPAY_THIRD_PARTY", notifyId)) {
+ log.info("绗笁鏂规敮浠樺疂鍥炶皟宸插鐞嗚繃锛屾爣璇�: {}", notifyId);
+ return;
+ }
+
+ // 璁板綍鍥炶皟鏃ュ織
+ NotifyLog notifyLog = saveNotifyLog("ALIPAY_THIRD_PARTY", notifyId, JSON.toJSONString(params), true);
+
+ try {
+ // 绗笁鏂规敮浠樺疂鎴愬姛鐨勫垽鏂潯浠讹紙鏍规嵁瀹為檯鎯呭喌璋冩暣锛�
+ // 閫氬父鍙鑳芥敹鍒板洖璋冨氨琛ㄧず鏀粯鎴愬姛
+ if (paidMoney != null && Integer.parseInt(paidMoney) > 0) {
+ // 鏌ヨ璁㈠崟锛堜娇鐢ㄥ晢鎴疯鍗曞彿锛岃繖閲岀殑outTradeNo瀹為檯鏄垜浠殑璁㈠崟ID锛�
+ PaymentOrder order = paymentOrderMapper.selectById(Long.valueOf(outTradeNo));
+ if (order == null) {
+ log.error("璁㈠崟涓嶅瓨鍦�: {}", outTradeNo);
+ updateNotifyLog(notifyLog.getId(), false, "璁㈠崟涓嶅瓨鍦�");
+ return;
+ }
+
+ // 楠岃瘉閲戦鏄惁鍖归厤
+ if (!order.getAmount().equals(Integer.parseInt(paidMoney))) {
+ log.error("璁㈠崟閲戦涓嶅尮閰嶏紝璁㈠崟閲戦: {}, 鍥炶皟閲戦: {}", order.getAmount(), paidMoney);
+ updateNotifyLog(notifyLog.getId(), false, "閲戦涓嶅尮閰�");
+ return;
+ }
+
+ // 鏌ヨ寰呮敮浠樹氦鏄�
+ PaymentTransaction transaction = paymentTransactionMapper.selectPendingByOrderId(order.getId());
+ if (transaction == null) {
+ // 濡傛灉娌℃湁寰呮敮浠樹氦鏄擄紝灏濊瘯鏌ヨ鏈�鏂颁氦鏄�
+ transaction = paymentTransactionMapper.selectLatestByOrderId(order.getId());
+ if (transaction == null || "SUCCEEDED".equals(transaction.getStatus())) {
+ log.warn("浜ゆ槗宸插畬鎴愭垨涓嶅瓨鍦紝璁㈠崟ID: {}", order.getId());
+ updateNotifyLog(notifyLog.getId(), true, "浜ゆ槗宸插畬鎴�");
+ return;
+ }
+ }
+
+ // 鏇存柊浜ゆ槗鐘舵��
+ transaction.setStatus("SUCCEEDED");
+ if (transactionId != null) {
+ transaction.setChannelTradeNo(transactionId);
+ }
+ transaction.setPaidAt(LocalDateTime.now());
+ transaction.setResponseSnapshot(JSON.toJSONString(params));
+ paymentTransactionMapper.update(transaction);
+
+ // 鏇存柊璁㈠崟鐘舵��
+ order.setStatus("SUCCEEDED");
+ if (transactionId != null) {
+ order.setChannelTradeNo(transactionId);
+ }
+ order.setPaidAt(LocalDateTime.now());
+ order.setLatestTransactionId(transaction.getId());
+ paymentOrderMapper.update(order);
+
+ // 鏇存柊閫氱煡鏃ュ織
+ notifyLog.setOrderId(order.getId());
+ notifyLog.setTransactionId(transaction.getId());
+ updateNotifyLog(notifyLog.getId(), true, "澶勭悊鎴愬姛");
+
+ // 瑙﹀彂涓氬姟鍥炶皟
+ bizCallbackService.triggerCallback(order, transaction);
+
+ log.info("绗笁鏂规敮浠樺疂鍥炶皟澶勭悊鎴愬姛锛岃鍗旾D: {}, 浜ゆ槗ID: {}", order.getId(), transaction.getId());
+ } else {
+ log.warn("绗笁鏂规敮浠樺疂鏀粯閲戦寮傚父: {}", paidMoney);
+ updateNotifyLog(notifyLog.getId(), true, "閲戦寮傚父: " + paidMoney);
+ }
+ } catch (Exception e) {
+ log.error("澶勭悊绗笁鏂规敮浠樺疂鍥炶皟寮傚父", e);
+ updateNotifyLog(notifyLog.getId(), false, "澶勭悊寮傚父: " + e.getMessage());
+ throw e;
+ }
+ }
+
+ /**
+ * 浠嶱aidRemarks涓彁鍙栬鍗曞彿
+ * PaidRemarks鍙兘鍖呭惈璁㈠崟鍙峰拰浜ゆ槗鍙凤紝闇�瑕佽В鏋�
+ */
+ private String extractOutTradeNo(String paidRemarks) {
+ if (paidRemarks == null || paidRemarks.isEmpty()) {
+ return null;
+ }
+
+ // 鍋囪PaidRemarks鏍煎紡: "璁㈠崟鍙�+浜ゆ槗鍙�" 鎴� "璁㈠崟鍙�"
+ // 鏍规嵁瀹為檯鏍煎紡璋冩暣瑙f瀽閫昏緫
+ // 杩欓噷鍋囪璁㈠崟鍙峰湪鏈�鍓嶉潰锛屽彲鑳界敤鏌愪釜鍒嗛殧绗﹀垎闅�
+
+ // 灏濊瘯鎻愬彇绾暟瀛椾綔涓鸿鍗旾D
+ String[] parts = paidRemarks.split("[^0-9]+");
+ for (String part : parts) {
+ if (part.length() > 10) { // 璁㈠崟ID閫氬父鏄暱鏁村瀷锛岄暱搴﹁緝闀�
+ return part;
+ }
+ }
+
+ // 濡傛灉娌℃湁鎵惧埌锛岃繑鍥炴暣涓瓧绗︿覆鐨勬暟瀛楅儴鍒�
+ return paidRemarks.replaceAll("[^0-9]", "");
+ }
+
+ /**
+ * 浠嶱aidRemarks涓彁鍙栦氦鏄撳彿
+ */
+ private String extractTransactionId(String paidRemarks) {
+ if (paidRemarks == null || paidRemarks.isEmpty()) {
+ return null;
+ }
+
+ // 濡傛灉PaidRemarks鍖呭惈鏀粯瀹濅氦鏄撳彿锛堥�氬父浠�2寮�澶寸殑28浣嶆暟瀛楋級
+ // 杩欓噷绠�鍗曡繑鍥瀗ull锛屽彲浠ユ牴鎹疄闄呮牸寮忚皟鏁�
+ return null;
+ }
+
+ /**
+ * 澶勭悊绗笁鏂瑰井淇″洖璋�
+ * 绗笁鏂瑰井淇¢�氳繃GET鏂瑰紡鍥炶皟锛屽弬鏁伴�氳繃URL浼犻��
+ *
+ * 鍙傛暟鏍煎紡锛�
+ * method: 鏂规硶鍚�
+ * APPID: 搴旂敤ID
+ * PaidMoneyType: 鏀粯绫诲瀷
+ * PaidMoney: 鏀粯閲戦锛堝垎锛�
+ * PaidRemarks: 鏀粯澶囨敞锛堝寘鍚玹ransaction_id锛�
+ * UnixTime: 鏃堕棿鎴�
+ */
+ @Transactional(rollbackFor = Exception.class)
+ public void processWechatThirdPartyNotify(Map<String, String> params) {
+ String method = params.get("method"); // 鏂规硶鍚�
+ String appId = params.get("APPID"); // 搴旂敤ID
+ String paidMoneyType = params.get("PaidMoneyType"); // 鏀粯绫诲瀷
+ String paidMoney = params.get("PaidMoney"); // 鏀粯閲戦锛堝垎锛�
+ String paidRemarks = params.get("PaidRemarks"); // 鏀粯澶囨敞锛堝彲鑳藉寘鍚鍗曞彿鍜屼氦鏄撳彿锛�
+ String unixTime = params.get("UnixTime"); // 鏃堕棿鎴�
+
+ log.info("澶勭悊绗笁鏂瑰井淇″洖璋冿紝method: {}, APPID: {}, PaidMoneyType: {}, PaidMoney: {}, PaidRemarks: {}, UnixTime: {}",
+ method, appId, paidMoneyType, paidMoney, paidRemarks, unixTime);
+ log.info("绗笁鏂瑰井淇″洖璋冨畬鏁村弬鏁�: {}", params);
+
+ // 浠嶱aidRemarks涓彁鍙栬鍗曞彿锛坥ut_trade_no锛�
+ String outTradeNo = extractOutTradeNo(paidRemarks);
+ String transactionId = extractTransactionId(paidRemarks);
+
+ if (outTradeNo == null || outTradeNo.isEmpty()) {
+ log.error("鏃犳硶浠嶱aidRemarks涓彁鍙栬鍗曞彿: {}", paidRemarks);
+ return;
+ }
+
+ log.info("瑙f瀽鍑鸿鍗曞彿: {}, 浜ゆ槗鍙�: {}", outTradeNo, transactionId);
+
+ // 妫�鏌ュ箓绛夋�э紙浣跨敤璁㈠崟鍙锋垨鏃堕棿鎴筹級
+ String notifyId = transactionId != null ? transactionId : (outTradeNo + "_" + unixTime);
+ if (isNotifyProcessed("WECHAT_THIRD_PARTY", notifyId)) {
+ log.info("绗笁鏂瑰井淇″洖璋冨凡澶勭悊杩囷紝鏍囪瘑: {}", notifyId);
+ return;
+ }
+
+ // 璁板綍鍥炶皟鏃ュ織
+ NotifyLog notifyLog = saveNotifyLog("WECHAT_THIRD_PARTY", notifyId, JSON.toJSONString(params), true);
+
+ try {
+ // 绗笁鏂瑰井淇℃垚鍔熺殑鍒ゆ柇鏉′欢锛堥�氬父鍙鑳芥敹鍒板洖璋冨氨琛ㄧず鏀粯鎴愬姛锛�
+ if (paidMoney != null && Integer.parseInt(paidMoney) > 0) {
+ // 鏌ヨ璁㈠崟锛堜娇鐢ㄥ晢鎴疯鍗曞彿锛岃繖閲岀殑outTradeNo瀹為檯鏄垜浠殑璁㈠崟ID锛�
+ PaymentOrder order = paymentOrderMapper.selectById(Long.valueOf(outTradeNo));
+ if (order == null) {
+ log.error("璁㈠崟涓嶅瓨鍦�: {}", outTradeNo);
+ updateNotifyLog(notifyLog.getId(), false, "璁㈠崟涓嶅瓨鍦�");
+ return;
+ }
+
+ // 楠岃瘉閲戦鏄惁鍖归厤
+ if (!order.getAmount().equals(Integer.parseInt(paidMoney))) {
+ log.error("璁㈠崟閲戦涓嶅尮閰嶏紝璁㈠崟閲戦: {}, 鍥炶皟閲戦: {}", order.getAmount(), paidMoney);
+ updateNotifyLog(notifyLog.getId(), false, "閲戦涓嶅尮閰�");
+ return;
+ }
+
+ // 鏌ヨ寰呮敮浠樹氦鏄�
+ PaymentTransaction transaction = paymentTransactionMapper.selectPendingByOrderId(order.getId());
+ if (transaction == null) {
+ // 濡傛灉娌℃湁寰呮敮浠樹氦鏄擄紝灏濊瘯鏌ヨ鏈�鏂颁氦鏄�
+ transaction = paymentTransactionMapper.selectLatestByOrderId(order.getId());
+ if (transaction == null || "SUCCEEDED".equals(transaction.getStatus())) {
+ log.warn("浜ゆ槗宸插畬鎴愭垨涓嶅瓨鍦紝璁㈠崟ID: {}", order.getId());
+ updateNotifyLog(notifyLog.getId(), true, "浜ゆ槗宸插畬鎴�");
+ return;
+ }
+ }
+
+ // 鏇存柊浜ゆ槗鐘舵��
+ transaction.setStatus("SUCCEEDED");
+ if (transactionId != null) {
+ transaction.setChannelTradeNo(transactionId);
+ }
+ transaction.setPaidAt(LocalDateTime.now());
+ transaction.setResponseSnapshot(JSON.toJSONString(params));
+ paymentTransactionMapper.update(transaction);
+
+ // 鏇存柊璁㈠崟鐘舵��
+ order.setStatus("SUCCEEDED");
+ if (transactionId != null) {
+ order.setChannelTradeNo(transactionId);
+ }
+ order.setPaidAt(LocalDateTime.now());
+ order.setLatestTransactionId(transaction.getId());
+ paymentOrderMapper.update(order);
+
+ // 鏇存柊閫氱煡鏃ュ織
+ notifyLog.setOrderId(order.getId());
+ notifyLog.setTransactionId(transaction.getId());
+ updateNotifyLog(notifyLog.getId(), true, "澶勭悊鎴愬姛");
+
+ // 瑙﹀彂涓氬姟鍥炶皟
+ bizCallbackService.triggerCallback(order, transaction);
+
+ log.info("绗笁鏂瑰井淇″洖璋冨鐞嗘垚鍔燂紝璁㈠崟ID: {}, 浜ゆ槗ID: {}", order.getId(), transaction.getId());
+ } else {
+ log.warn("绗笁鏂瑰井淇℃敮浠橀噾棰濆紓甯�: {}", paidMoney);
+ updateNotifyLog(notifyLog.getId(), true, "閲戦寮傚父: " + paidMoney);
+ }
+ } catch (Exception e) {
+ log.error("澶勭悊绗笁鏂瑰井淇″洖璋冨紓甯�", e);
+ updateNotifyLog(notifyLog.getId(), false, "澶勭悊寮傚父: " + e.getMessage());
+ throw e;
+ }
+ }
+
+ /**
* 妫�鏌ラ�氱煡鏄惁宸插鐞嗭紙骞傜瓑鎬э級
*/
private boolean isNotifyProcessed(String channel, String notifyId) {
--
Gitblit v1.9.1