mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-24 16:05:44 +08:00
fix(payment): fix order creation + show actual provider types on payment page
- Fix CreateOrderRequest field name mismatch (payment_type → paymentType) - Payment page now discovers available types from providers (not global config) - Backend GetLimits returns map keyed by payment type - EasyPay shows 3 buttons (跳转/支付宝/微信), Stripe shows card/alipay/wxpay/link - Auto-select first method after limits loaded
This commit is contained in:
@@ -1 +1 @@
|
||||
0.1.108.61
|
||||
0.1.108.62
|
||||
|
||||
@@ -61,20 +61,20 @@ func (h *PaymentHandler) GetChannels(c *gin.Context) {
|
||||
response.Success(c, channels)
|
||||
}
|
||||
|
||||
// GetLimits returns per-payment-type limits.
|
||||
// GetLimits returns per-payment-type limits derived from enabled provider instances.
|
||||
// GET /api/v1/payment/limits
|
||||
func (h *PaymentHandler) GetLimits(c *gin.Context) {
|
||||
cfg, err := h.configService.GetPaymentConfig(c.Request.Context())
|
||||
limits, err := h.configService.GetAvailableMethodLimits(c.Request.Context())
|
||||
if err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
limits, err := h.configService.GetMethodLimits(c.Request.Context(), cfg.EnabledTypes)
|
||||
if err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
// Return as map keyed by payment type (frontend expects Record<string, MethodLimit>)
|
||||
result := make(map[string]service.MethodLimits, len(limits))
|
||||
for _, ml := range limits {
|
||||
result[ml.PaymentType] = ml
|
||||
}
|
||||
response.Success(c, limits)
|
||||
response.Success(c, result)
|
||||
}
|
||||
|
||||
// CreateOrderRequest is the request body for creating a payment order.
|
||||
|
||||
@@ -606,6 +606,36 @@ func (s *PaymentConfigService) GetPlan(ctx context.Context, id int64) (*dbent.Su
|
||||
return plan, nil
|
||||
}
|
||||
|
||||
// GetAvailableMethodLimits collects all payment types from enabled provider
|
||||
// instances and returns limits for each. This is used by the user-facing payment
|
||||
// page to discover which payment methods are actually available.
|
||||
func (s *PaymentConfigService) GetAvailableMethodLimits(ctx context.Context) ([]MethodLimits, error) {
|
||||
instances, err := s.entClient.PaymentProviderInstance.Query().
|
||||
Where(paymentproviderinstance.EnabledEQ(true)).All(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("query provider instances: %w", err)
|
||||
}
|
||||
// Collect unique payment types from all enabled providers
|
||||
typeSet := make(map[string]bool)
|
||||
for _, inst := range instances {
|
||||
for _, t := range splitTypes(inst.SupportedTypes) {
|
||||
typeSet[t] = true
|
||||
}
|
||||
}
|
||||
result := make([]MethodLimits, 0, len(typeSet))
|
||||
for pt := range typeSet {
|
||||
ml := MethodLimits{PaymentType: pt}
|
||||
for _, inst := range instances {
|
||||
if !payment.InstanceSupportsType(inst.SupportedTypes, pt) {
|
||||
continue
|
||||
}
|
||||
pcApplyInstanceLimits(inst, pt, &ml)
|
||||
}
|
||||
result = append(result, ml)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetMethodLimits returns per-payment-type limits from enabled provider instances.
|
||||
func (s *PaymentConfigService) GetMethodLimits(ctx context.Context, types []string) ([]MethodLimits, error) {
|
||||
instances, err := s.entClient.PaymentProviderInstance.Query().
|
||||
|
||||
@@ -114,9 +114,9 @@ export interface ProviderInstance {
|
||||
|
||||
export interface CreateOrderRequest {
|
||||
amount: number
|
||||
payment_type: string
|
||||
order_type: string
|
||||
plan_id?: number
|
||||
paymentType: string
|
||||
orderType: string
|
||||
planId?: number
|
||||
}
|
||||
|
||||
export interface CreateOrderResult {
|
||||
|
||||
@@ -156,7 +156,8 @@ const tabs = computed(() => {
|
||||
return result
|
||||
})
|
||||
|
||||
const enabledMethods = computed(() => config.value?.enabled_payment_types ?? [])
|
||||
// Available methods derived from limits API (actual provider types)
|
||||
const enabledMethods = computed(() => Object.keys(methodLimits.value))
|
||||
// 0 = no limit; provider-level overrides global
|
||||
const minAmount = computed(() => {
|
||||
const limit = methodLimits.value[selectedMethod.value]
|
||||
@@ -225,9 +226,9 @@ async function createOrder(orderAmount: number, orderType: string, planId?: numb
|
||||
try {
|
||||
const result = await paymentStore.createOrder({
|
||||
amount: orderAmount,
|
||||
payment_type: selectedMethod.value,
|
||||
order_type: orderType,
|
||||
plan_id: planId,
|
||||
paymentType: selectedMethod.value,
|
||||
orderType: orderType,
|
||||
planId: planId,
|
||||
})
|
||||
if (result.client_secret) {
|
||||
router.push({ path: '/payment/stripe', query: { order_id: String(result.order_id), client_secret: result.client_secret } })
|
||||
@@ -260,11 +261,11 @@ watch(() => activeTab.value, (tab) => {
|
||||
onMounted(async () => {
|
||||
try {
|
||||
await paymentStore.fetchConfig(true)
|
||||
if (enabledMethods.value.length) selectedMethod.value = enabledMethods.value[0]
|
||||
try {
|
||||
const limitsRes = await paymentAPI.getLimits()
|
||||
methodLimits.value = limitsRes.data
|
||||
} catch (e) { /* limits endpoint may not exist */ }
|
||||
if (enabledMethods.value.length) selectedMethod.value = enabledMethods.value[0]
|
||||
if (config.value?.balance_disabled) {
|
||||
activeTab.value = 'subscription'
|
||||
await loadPlans()
|
||||
|
||||
Reference in New Issue
Block a user