diff --git a/backend/internal/payment/load_balancer.go b/backend/internal/payment/load_balancer.go index b6374a74d9..ab55b78816 100644 --- a/backend/internal/payment/load_balancer.go +++ b/backend/internal/payment/load_balancer.go @@ -90,6 +90,7 @@ func (lb *DefaultLoadBalancer) SelectInstance(ctx context.Context, providerKey s InstanceID: fmt.Sprintf("%d", selected.ID), Config: config, SupportedTypes: selected.SupportedTypes, + PaymentMode: selected.PaymentMode, }, nil } diff --git a/backend/internal/payment/provider/easypay.go b/backend/internal/payment/provider/easypay.go index 46150856f3..5cf42c9eea 100644 --- a/backend/internal/payment/provider/easypay.go +++ b/backend/internal/payment/provider/easypay.go @@ -57,8 +57,9 @@ func (e *EasyPay) SupportedTypes() []payment.PaymentType { func (e *EasyPay) CreatePayment(ctx context.Context, req payment.CreatePaymentRequest) (*payment.CreatePaymentResponse, error) { // Payment mode determined by instance config, not payment type. - // "redirect" → hosted page (submit.php); default → API call (mapi.php). - if e.config["paymentMode"] == "redirect" { + // "redirect"/"popup" → hosted page (submit.php); "qrcode"/default → API call (mapi.php). + mode := e.config["paymentMode"] + if mode == "redirect" || mode == "popup" { return e.createRedirectPayment(req) } return e.createAPIPayment(ctx, req) diff --git a/backend/internal/payment/types.go b/backend/internal/payment/types.go index 26b5edde70..ab27dfeda0 100644 --- a/backend/internal/payment/types.go +++ b/backend/internal/payment/types.go @@ -126,6 +126,7 @@ type InstanceSelection struct { InstanceID string Config map[string]string SupportedTypes string // Comma-separated list of supported payment types from the instance + PaymentMode string // Payment display mode: "qrcode", "redirect", "popup" } // Provider defines the interface that all payment providers must implement. diff --git a/backend/internal/service/payment_order.go b/backend/internal/service/payment_order.go index b8416d7412..b1493e9408 100644 --- a/backend/internal/service/payment_order.go +++ b/backend/internal/service/payment_order.go @@ -275,7 +275,7 @@ func (s *PaymentService) invokeProvider(ctx context.Context, order *dbent.Paymen return nil, fmt.Errorf("update order with payment details: %w", err) } s.writeAuditLog(ctx, order.ID, "ORDER_CREATED", fmt.Sprintf("user:%d", req.UserID), map[string]any{"amount": req.Amount, "paymentType": req.PaymentType, "orderType": req.OrderType}) - return &CreateOrderResponse{OrderID: order.ID, Amount: order.Amount, PayAmount: payAmount, FeeRate: order.FeeRate, Status: OrderStatusPending, PaymentType: req.PaymentType, PayURL: pr.PayURL, QRCode: pr.QRCode, ClientSecret: pr.ClientSecret, ExpiresAt: order.ExpiresAt}, nil + return &CreateOrderResponse{OrderID: order.ID, Amount: order.Amount, PayAmount: payAmount, FeeRate: order.FeeRate, Status: OrderStatusPending, PaymentType: req.PaymentType, PayURL: pr.PayURL, QRCode: pr.QRCode, ClientSecret: pr.ClientSecret, ExpiresAt: order.ExpiresAt, PaymentMode: sel.PaymentMode}, nil } func (s *PaymentService) buildPaymentSubject(plan *dbent.SubscriptionPlan, payAmountStr string, cfg *PaymentConfig) string { diff --git a/backend/internal/service/payment_service.go b/backend/internal/service/payment_service.go index c5dd0ea1c1..d48e6e3c0b 100644 --- a/backend/internal/service/payment_service.go +++ b/backend/internal/service/payment_service.go @@ -81,6 +81,7 @@ type CreateOrderResponse struct { QRCode string `json:"qr_code,omitempty"` ClientSecret string `json:"client_secret,omitempty"` ExpiresAt time.Time `json:"expires_at"` + PaymentMode string `json:"payment_mode,omitempty"` } type OrderListParams struct { diff --git a/frontend/src/components/payment/PaymentProviderDialog.vue b/frontend/src/components/payment/PaymentProviderDialog.vue index cb2871dda7..c101b3c7af 100644 --- a/frontend/src/components/payment/PaymentProviderDialog.vue +++ b/frontend/src/components/payment/PaymentProviderDialog.vue @@ -37,7 +37,7 @@
-
+