From 0c8ea845c81f25e29b1a1ec2727cc80328ce87c1 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期四, 17 九月 2026 17:56:36 +0800
Subject: [PATCH] feat(payment): 取消订单不再等关单结论,按用户意图立刻生效
---
talent-card-server/src/main/java/com/talentcard/server/business/payment/PaymentReconciliationService.java | 46 ++++++++++------------------------------------
1 files changed, 10 insertions(+), 36 deletions(-)
diff --git a/talent-card-server/src/main/java/com/talentcard/server/business/payment/PaymentReconciliationService.java b/talent-card-server/src/main/java/com/talentcard/server/business/payment/PaymentReconciliationService.java
index b79e4b9..4cc3e0e 100644
--- a/talent-card-server/src/main/java/com/talentcard/server/business/payment/PaymentReconciliationService.java
+++ b/talent-card-server/src/main/java/com/talentcard/server/business/payment/PaymentReconciliationService.java
@@ -66,37 +66,7 @@
public Map<String, Object> reconcile(int pendingAfterMinutes) {
int paymentChecked = reconcilePayments(pendingAfterMinutes);
int refundChecked = reconcileRefunds(pendingAfterMinutes);
- // 关单结论回来之后,替已经点过取消的用户把订单收掉。放在查单/关单之后:同一轮里先把这次尝试
- // 问出结论,再决定这笔订单能不能结束。
- int cancelledOnRequest = cancelOrdersAwaitingCloseConclusion();
- return Map.of("paymentChecked", paymentChecked, "refundChecked", refundChecked,
- "cancelledOnRequest", cancelledOnRequest);
- }
-
- /**
- * 落地「用户点过取消、但当时关单还没有结论」的订单。
- *
- * <p>取消在通道说「关单处理中」时只能先受理(见 {@code PendingOrderPortalService.cancel}),订单要等
- * 每笔尝试都有了结论才能结束。那之后必须有人替用户把这一步走完:关单关掉了就取消,通道说钱收下了就
- * 交给结算把它翻成已支付——否则用户点的取消会随着页面关掉而丢失,订单一直挂在「待支付」,他只能再点
- * 一次取消,或者等到 15 分钟超时被清理收掉。
- *
- * <p>条件与「取消」本身一致:不留未定局的尝试(它们还可能被支付),也不取消已经收到钱的订单。
- */
- private int cancelOrdersAwaitingCloseConclusion() {
- return jdbc.update("""
- update benefit_order o set o.order_status = 2
- where o.order_status = 0 and o.deleted = 0 and o.cancel_requested_at is not null
- and not exists (
- select 1 from payment_transaction p
- where p.order_id = o.id
- and p.status in ('CREATED', 'PREPAY_CREATED', 'CREATE_UNKNOWN', 'CLOSING', 'CANCEL_UNCONFIRMED')
- )
- and not exists (
- select 1 from payment_transaction p
- where p.order_id = o.id and p.status = 'SUCCEEDED'
- )
- """);
+ return Map.of("paymentChecked", paymentChecked, "refundChecked", refundChecked);
}
/** What the provider said about the payments of one order whose local state is still undecided. */
@@ -131,12 +101,16 @@
}
/**
- * 取消订单前的通道确认:除了确认这笔订单有没有收到钱,通道说没收款的预支付单还要在通道侧关掉。
+ * 取消订单前的通道确认:问清这笔订单有没有收到钱,并尽最大努力把还没付款的预支付单在通道侧关掉。
*
- * <p>只把本地流水标成已关闭是不够的:用户手上那张预支付单在通道侧还活着,照样能付进来,钱收了
- * 而订单已经取消。所以取消必须以通道侧的关单结论为准——关单回执说原交易已经成功就落成已支付并拒绝
- * 取消,说还在处理中就让这次尝试停在 {@code CLOSING} 并交给后台重试,只有确认关掉、或通道明确拒绝
- * 关单(见 {@link #keepWatchableAfterRefusedClose})时才继续取消。
+ * <p><b>只有「钱收没收下」决定取消能不能落地</b>:收下了就落成已支付并拒绝取消;没有就立刻取消。
+ * 关单只是顺带做的(它便宜,而且拿到了「已关闭」这条结论,本地就不用再盯着这张凭证),
+ * 它的结论**不再**挡住取消——等它返回「处理中」再落地,用户看到的就是「点了取消一直卡着」,
+ * 而「关单中期间直接取消」的代价(取消后才收到的钱)已经由悬账自动退款兜住(判定见
+ * {@code docs/adr/0003} 的 2026-09-17 修订)。
+ *
+ * <p>关单结论决定的是这次尝试的本地终态:通道说关掉了就落成 {@code CLOSED}(不必再盯),
+ * 说「处理中」或拒绝就留成 {@code CLOSING}/{@code CANCEL_UNCONFIRMED},由对账继续盯着并把凭证关掉。
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
public PendingPaymentConfirmation closePendingPayments(String orderNo) {
--
Gitblit v1.7.1