yeg
2026-09-17 e3f412c5474311a471345ea508db4875c9ec648e
talent-card-server/src/main/java/com/talentcard/server/business/payment/PaymentSettlementService.java
@@ -35,10 +35,13 @@
    private final JdbcTemplate jdbc;
    private final PaymentIssueRecorder issues;
    private final com.talentcard.server.business.order.OrderVerificationService orderVerification;
    public PaymentSettlementService(JdbcTemplate jdbc, PaymentIssueRecorder issues) {
    public PaymentSettlementService(JdbcTemplate jdbc, PaymentIssueRecorder issues,
                                    @org.springframework.context.annotation.Lazy com.talentcard.server.business.order.OrderVerificationService orderVerification) {
        this.jdbc = jdbc;
        this.issues = issues;
        this.orderVerification = orderVerification;
    }
    @Transactional
@@ -93,11 +96,14 @@
        }
        if (!alreadySucceeded) {
            // CANCEL_UNCONFIRMED 也在这里:订单取消后用户又把预支付单付了,钱必须落成已支付的事实,
            // 再让下面的订单状态判断把它记成「取消后才收到钱」的问题记录。CLOSING(关单中)同理:
            // 它只说明我们发出过关单请求,通道完全可能已经把钱收下了。
            int paymentUpdated = jdbc.update("""
                    update payment_transaction
                    set status = 'SUCCEEDED', provider_transaction_no = coalesce(nullif(?, ''), provider_transaction_no),
                        provider_response_code = ?, provider_response_message = ?, paid_at = coalesce(paid_at, now())
                    where id = ? and status in ('CREATED', 'CREATE_FAILED', 'PREPAY_CREATED', 'CREATE_UNKNOWN')
                    where id = ? and status in ('CREATED', 'CREATE_FAILED', 'PREPAY_CREATED', 'CREATE_UNKNOWN', 'CANCEL_UNCONFIRMED', 'CLOSING')
                    """, fact.providerTransactionNo(), fact.responseCode(), fact.responseMessage(), paymentId);
            if (paymentUpdated == 0) return SettlementOutcome.NOT_SETTLEABLE;
        }
@@ -111,12 +117,17 @@
        }
        // STORE_CONSUME orders are fulfilled at payment time, so the query path must verify them
        // exactly like the callback path does.
        jdbc.update("""
        int orderUpdated = jdbc.update("""
                update benefit_order
                set order_status = 1,
                    verify_status = case when order_type = 'STORE_CONSUME' then 1 else verify_status end
                where id = ? and order_status = 0
                """, payment.get("orderId"));
        if (orderUpdated == 1) {
            // 到店消费的核销是支付的副产品。补一条核销记录,否则这笔核销在数据里没有任何凭证,
            // 冲正、纠纷举证与按核销统计都会缺一块。方法内部幂等,重复回调不会产生第二条记录。
            orderVerification.recordAutomaticVerification(number(payment.get("orderId")), java.time.LocalDateTime.now());
        }
        return alreadySucceeded ? SettlementOutcome.ALREADY_SETTLED : SettlementOutcome.SETTLED;
    }