From a8a98cc5a1aa52292e3835e9d4da95fd4b20485f Mon Sep 17 00:00:00 2001 From: erio Date: Thu, 9 Apr 2026 02:29:18 +0800 Subject: [PATCH] fix: order expiry cancels upstream, subscription layout, popup & label fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ExpireTimedOutOrders now cancels upstream payment (Stripe PaymentIntent) before marking order as expired - Active subscriptions moved below plan list with compact inline style - StripePaymentView uses minimal layout (no AppLayout) in popup mode - Fix misleading "服务商" label → "支持的支付方式" for payment type toggles --- backend/internal/service/payment_order.go | 19 ++++++ frontend/src/i18n/locales/zh.ts | 4 +- frontend/src/views/user/PaymentView.vue | 59 ++++++++----------- frontend/src/views/user/StripePaymentView.vue | 11 ++-- 4 files changed, 51 insertions(+), 42 deletions(-) diff --git a/backend/internal/service/payment_order.go b/backend/internal/service/payment_order.go index b1493e9408..e9841461e1 100644 --- a/backend/internal/service/payment_order.go +++ b/backend/internal/service/payment_order.go @@ -436,6 +436,8 @@ func (s *PaymentService) ExpireTimedOutOrders(ctx context.Context) (int, error) } n := 0 for _, o := range orders { + // Cancel upstream payment (e.g. Stripe PaymentIntent) before marking expired + s.cancelUpstreamPayment(ctx, o) c, e := s.entClient.PaymentOrder.Update().Where(paymentorder.IDEQ(o.ID), paymentorder.StatusEQ(OrderStatusPending)).SetStatus(OrderStatusExpired).Save(ctx) if e != nil { slog.Warn("expire failed", "orderID", o.ID, "error", e) @@ -448,3 +450,20 @@ func (s *PaymentService) ExpireTimedOutOrders(ctx context.Context) (int, error) } return n, nil } + +// cancelUpstreamPayment attempts to cancel the upstream provider payment (e.g. Stripe PaymentIntent). +func (s *PaymentService) cancelUpstreamPayment(ctx context.Context, o *dbent.PaymentOrder) { + if o.PaymentTradeNo == "" || o.PaymentType == "" { + return + } + s.EnsureProviders(ctx) + prov, err := s.registry.GetProvider(o.PaymentType) + if err != nil { + return + } + if cp, ok := prov.(payment.CancelableProvider); ok { + if err := cp.CancelPayment(ctx, o.PaymentTradeNo); err != nil { + slog.Warn("cancel upstream payment failed", "orderID", o.ID, "tradeNo", o.PaymentTradeNo, "error", err) + } + } +} diff --git a/frontend/src/i18n/locales/zh.ts b/frontend/src/i18n/locales/zh.ts index 8f9f06897b..bf6c0dd088 100644 --- a/frontend/src/i18n/locales/zh.ts +++ b/frontend/src/i18n/locales/zh.ts @@ -4510,8 +4510,8 @@ export default { description: '配置支付系统选项', enabled: '启用支付', enabledHint: '启用或禁用支付系统', - enabledPaymentTypes: '服务商', - enabledPaymentTypesHint: '选择要启用的服务商', + enabledPaymentTypes: '支持的支付方式', + enabledPaymentTypesHint: '选择要启用的支付方式', minAmount: '最低金额', maxAmount: '最高金额', dailyLimit: '每日限额', diff --git a/frontend/src/views/user/PaymentView.vue b/frontend/src/views/user/PaymentView.vue index 0dfdbaabc5..f0f86ff3be 100644 --- a/frontend/src/views/user/PaymentView.vue +++ b/frontend/src/views/user/PaymentView.vue @@ -96,42 +96,6 @@ diff --git a/frontend/src/views/user/StripePaymentView.vue b/frontend/src/views/user/StripePaymentView.vue index 22e35115df..bc65255d64 100644 --- a/frontend/src/views/user/StripePaymentView.vue +++ b/frontend/src/views/user/StripePaymentView.vue @@ -1,6 +1,6 @@ - +