From 36b14b058411634ee20764140880ec7982acc11d Mon Sep 17 00:00:00 2001 From: erio Date: Wed, 8 Apr 2026 02:35:22 +0800 Subject: [PATCH] fix(payment): Stripe instance polluting alipay/wxpay limits groups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: Stripe instance had supported_types="card,alipay,link,wxpay" but only card/link were mapped to "stripe" group. Stripe's alipay/wxpay leaked into independent groups, and since Stripe had no limits configured, it triggered the "any unlimited → all zeros" early return, making ALL method limits show as zero. Fix: pcGroupByPaymentType now routes ALL types from Stripe provider instances to the "stripe" group (by checking ProviderKey, not sub-type). Frontend: Stripe provider dialog shows single "Stripe" limits entry instead of per-sub-type entries. --- .../internal/service/payment_config_limits.go | 19 ++++++++----------- .../payment/PaymentProviderDialog.vue | 7 ++++++- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/backend/internal/service/payment_config_limits.go b/backend/internal/service/payment_config_limits.go index c71223608c..5690527885 100644 --- a/backend/internal/service/payment_config_limits.go +++ b/backend/internal/service/payment_config_limits.go @@ -10,9 +10,6 @@ import ( "github.com/Wei-Shaw/sub2api/internal/payment" ) -// stripeSubTypes are types that should be aggregated under TypeStripe for user-facing display. -var stripeSubTypes = map[string]bool{string(payment.TypeCard): true, string(payment.TypeLink): true} - // GetAvailableMethodLimits collects all payment types from enabled provider // instances and returns limits for each, plus the global widest range. // Stripe sub-types (card, link) are aggregated under "stripe". @@ -55,7 +52,8 @@ func (s *PaymentConfigService) GetMethodLimits(ctx context.Context, types []stri } // pcGroupByPaymentType groups instances by user-facing payment type. -// Stripe sub-types (card, link) are merged under "stripe". +// For Stripe providers, ALL sub-types (card, link, alipay, wxpay) map to "stripe" +// because the user sees a single "Stripe" button, not individual sub-methods. // Uses a seen set to avoid counting one instance twice. func pcGroupByPaymentType(instances []*dbent.PaymentProviderInstance) map[string][]*dbent.PaymentProviderInstance { typeInstances := make(map[string][]*dbent.PaymentProviderInstance) @@ -70,15 +68,13 @@ func pcGroupByPaymentType(instances []*dbent.PaymentProviderInstance) map[string } } for _, inst := range instances { - for _, t := range splitTypes(inst.SupportedTypes) { - if stripeSubTypes[t] || t == payment.TypeStripe { - add(payment.TypeStripe, inst) - } else { - add(t, inst) - } - } + // Stripe provider: all sub-types → single "stripe" group if inst.ProviderKey == payment.TypeStripe { add(payment.TypeStripe, inst) + continue + } + for _, t := range splitTypes(inst.SupportedTypes) { + add(t, inst) } } return typeInstances @@ -86,6 +82,7 @@ func pcGroupByPaymentType(instances []*dbent.PaymentProviderInstance) map[string // pcInstanceTypeLimits extracts per-type limits from a provider instance. // Returns (limits, true) if configured; (zero, false) if unlimited. +// For Stripe instances, limits are stored under "stripe" key regardless of sub-types. func pcInstanceTypeLimits(inst *dbent.PaymentProviderInstance, pt string) (payment.ChannelLimits, bool) { if inst.Limits == "" { return payment.ChannelLimits{}, false diff --git a/frontend/src/components/payment/PaymentProviderDialog.vue b/frontend/src/components/payment/PaymentProviderDialog.vue index 6bf0829b53..cb2871dda7 100644 --- a/frontend/src/components/payment/PaymentProviderDialog.vue +++ b/frontend/src/components/payment/PaymentProviderDialog.vue @@ -22,7 +22,7 @@