From 61b6272110914666ebd6e17e95e8980b572bfdca Mon Sep 17 00:00:00 2001 From: wucm667 Date: Thu, 14 May 2026 11:36:02 +0800 Subject: [PATCH] fix(payment): apply product affix to subscriptions --- backend/internal/service/payment_order.go | 29 +++++++++++---- .../service/payment_order_result_test.go | 35 +++++++++++++++++++ 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/backend/internal/service/payment_order.go b/backend/internal/service/payment_order.go index 056967f0388..e6cc4b3ca6b 100644 --- a/backend/internal/service/payment_order.go +++ b/backend/internal/service/payment_order.go @@ -499,22 +499,39 @@ func selectedInstanceSupportedTypes(sel *payment.InstanceSelection) string { func (s *PaymentService) buildPaymentSubject(plan *dbent.SubscriptionPlan, limitAmount float64, cfg *PaymentConfig, sel *payment.InstanceSelection) string { if plan != nil { - if plan.ProductName != "" { - return plan.ProductName + productName := plan.ProductName + if productName == "" { + productName = "Sub2API Subscription " + plan.Name } - return "Sub2API Subscription " + plan.Name + return applyPaymentProductNameAffix(productName, cfg) } currency := payment.DefaultPaymentCurrency if sel != nil { currency = paymentProviderConfigCurrency(sel.ProviderKey, sel.Config) } amountStr := payment.FormatAmountForCurrency(limitAmount, currency) + if hasPaymentProductNameAffix(cfg) { + return applyPaymentProductNameAffix(amountStr, cfg) + } + return "Sub2API " + amountStr + " " + currency +} + +func hasPaymentProductNameAffix(cfg *PaymentConfig) bool { + if cfg == nil { + return false + } pf := strings.TrimSpace(cfg.ProductNamePrefix) sf := strings.TrimSpace(cfg.ProductNameSuffix) - if pf != "" || sf != "" { - return strings.TrimSpace(pf + " " + amountStr + " " + sf) + return pf != "" || sf != "" +} + +func applyPaymentProductNameAffix(productName string, cfg *PaymentConfig) string { + if !hasPaymentProductNameAffix(cfg) { + return productName } - return "Sub2API " + amountStr + " " + currency + pf := strings.TrimSpace(cfg.ProductNamePrefix) + sf := strings.TrimSpace(cfg.ProductNameSuffix) + return strings.TrimSpace(pf + " " + productName + " " + sf) } func (s *PaymentService) maybeBuildWeChatOAuthRequiredResponse(ctx context.Context, req CreateOrderRequest, amount, payAmount, feeRate float64) (*CreateOrderResponse, error) { diff --git a/backend/internal/service/payment_order_result_test.go b/backend/internal/service/payment_order_result_test.go index f78d6b37fec..bfe275481cf 100644 --- a/backend/internal/service/payment_order_result_test.go +++ b/backend/internal/service/payment_order_result_test.go @@ -138,6 +138,41 @@ func TestCalculateCreateOrderPayAmountRejectsFractionalZeroDecimal(t *testing.T) } } +func TestBuildPaymentSubjectAppliesAffixToSubscriptionPlanProductName(t *testing.T) { + t.Parallel() + + svc := &PaymentService{} + cfg := &PaymentConfig{ + ProductNamePrefix: "PRE", + ProductNameSuffix: "SUF", + } + plan := &dbent.SubscriptionPlan{ + Name: "Pro Monthly", + ProductName: "Claude Pro", + } + + got := svc.buildPaymentSubject(plan, 0, cfg, nil) + if got != "PRE Claude Pro SUF" { + t.Fatalf("buildPaymentSubject() = %q, want %q", got, "PRE Claude Pro SUF") + } +} + +func TestBuildPaymentSubjectAppliesAffixToSubscriptionPlanDefaultName(t *testing.T) { + t.Parallel() + + svc := &PaymentService{} + cfg := &PaymentConfig{ + ProductNamePrefix: "PRE", + ProductNameSuffix: "SUF", + } + plan := &dbent.SubscriptionPlan{Name: "Team Monthly"} + + got := svc.buildPaymentSubject(plan, 0, cfg, nil) + if got != "PRE Sub2API Subscription Team Monthly SUF" { + t.Fatalf("buildPaymentSubject() = %q, want %q", got, "PRE Sub2API Subscription Team Monthly SUF") + } +} + func TestMaybeBuildWeChatOAuthRequiredResponse(t *testing.T) { t.Setenv("PAYMENT_RESUME_SIGNING_KEY", "0123456789abcdef0123456789abcdef")