From 8fe2249e07ebe15b33e0231cd9dafa7c303486f6 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期三, 16 九月 2026 16:35:39 +0800
Subject: [PATCH] fix(payment): 取消与到期不再赌钱,先与通道确认并在通道侧关单

---
 talent-card-server/src/test/java/com/talentcard/server/business/merchant/MerchantVerificationServiceTests.java |   28 ++++++++++++++++++++++------
 1 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/talent-card-server/src/test/java/com/talentcard/server/business/merchant/MerchantVerificationServiceTests.java b/talent-card-server/src/test/java/com/talentcard/server/business/merchant/MerchantVerificationServiceTests.java
index d234392..446a9c3 100644
--- a/talent-card-server/src/test/java/com/talentcard/server/business/merchant/MerchantVerificationServiceTests.java
+++ b/talent-card-server/src/test/java/com/talentcard/server/business/merchant/MerchantVerificationServiceTests.java
@@ -2,6 +2,8 @@
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
 
 import java.math.BigDecimal;
 import java.sql.Timestamp;
@@ -9,6 +11,7 @@
 import java.time.LocalDateTime;
 import java.util.Map;
 import com.talentcard.server.business.merchant.auth.MerchantPrincipal;
+import com.talentcard.server.business.payment.huifu.HuifuMiniProgramPaymentGateway;
 import com.talentcard.server.business.portal.FreeBenefitPortalService;
 import com.talentcard.server.business.portal.PendingOrderPaymentRequest;
 import com.talentcard.server.business.portal.PendingOrderPortalService;
@@ -20,6 +23,7 @@
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
 
 @SpringBootTest
 @ActiveProfiles("test")
@@ -48,6 +52,9 @@
 
     @Autowired
     private FreeBenefitPortalService freeBenefitPortalService;
+
+    @MockitoBean
+    private HuifuMiniProgramPaymentGateway paymentGateway;
 
     private Long merchantId;
     private Long storeId;
@@ -175,17 +182,26 @@
 	void pendingOrderCanBeCancelledAfterPrepayIsCreated() {
 		String suffix = String.valueOf(System.nanoTime());
 		String orderNo = "PREPAY-CANCEL-" + suffix;
+		// 取消前必须先问通道,所以订单要带上收款子商户,通道也要能答复这笔交易的状态。
+		String huifuId = "H" + suffix.substring(Math.max(0, suffix.length() - 8));
 		jdbc.update("""
 				insert into benefit_order(order_no, talent_id, card_id, merchant_id, store_id, order_type,
-				                          order_amount, subsidy_amount, pay_amount, order_status, verify_status, deleted)
-				values (?, ?, ?, ?, ?, 'GROUP_BUY', 10000, 0, 10000, 0, 0, 0)
-				""", orderNo, talentId, cardId, merchantId, storeId);
+				                          order_amount, subsidy_amount, pay_amount, order_status, verify_status, deleted,
+				                          collect_huifu_id)
+				values (?, ?, ?, ?, ?, 'GROUP_BUY', 10000, 0, 10000, 0, 0, 0, ?)
+				""", orderNo, talentId, cardId, merchantId, storeId, huifuId);
 		Long orderId = jdbc.queryForObject("select max(id) from benefit_order", Long.class);
 		jdbc.update("""
 				insert into payment_transaction(payment_no, provider, order_id, order_no, talent_id, merchant_id,
-				                                amount, status, idempotency_key)
-				values (?, 'HUIFU', ?, ?, ?, ?, 10000, 'PREPAY_CREATED', ?)
-				""", "PREPAY-CANCEL-PAY-" + suffix, orderId, orderNo, talentId, merchantId, "prepay-cancel-" + suffix);
+				                                provider_huifu_id, amount, status, idempotency_key)
+				values (?, 'HUIFU', ?, ?, ?, ?, ?, 10000, 'PREPAY_CREATED', ?)
+				""", "PREPAY-CANCEL-PAY-" + suffix, orderId, orderNo, talentId, merchantId, huifuId, "prepay-cancel-" + suffix);
+		// 通道回答「交易只登记过、从未开始支付」:这笔请求不可能收过钱,取消成立;关单确认成功之后,
+		// 本地流水才记为已关闭。
+		when(paymentGateway.queryMiniProgramPayment(any())).thenReturn(Map.of("data", Map.of(
+				"trans_stat", "I", "resp_code", "00000000", "trans_amt", "100.00", "huifu_id", huifuId)));
+		when(paymentGateway.closeMiniProgramPayment(any())).thenReturn(Map.of("data", Map.of(
+				"trans_stat", "S", "resp_code", "00000000", "resp_desc", "交易成功", "huifu_id", huifuId)));
 
 		pendingOrderPortalService.cancel(orderNo, talentId);
 

--
Gitblit v1.7.1