fix(payment): 同时启用易支付和 Stripe 时显示 Stripe 按钮
VISIBLE_METHOD_ALIASES 漏了 stripe,导致 getVisibleMethods 把后端返回 的 stripe 过滤掉。点 Stripe 按钮时省略 method 查询参数,让落地页渲染 完整的 Payment Element。
This commit is contained in:
@@ -33,7 +33,7 @@ function createOrderResult(overrides: Partial<CreateOrderResult> = {}): CreateOr
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('getVisibleMethods', () => {
|
describe('getVisibleMethods', () => {
|
||||||
it('filters hidden provider methods and normalizes aliases', () => {
|
it('normalizes provider aliases and keeps stripe as a top-level method', () => {
|
||||||
const visible = getVisibleMethods({
|
const visible = getVisibleMethods({
|
||||||
alipay_direct: methodLimit({ single_min: 5 }),
|
alipay_direct: methodLimit({ single_min: 5 }),
|
||||||
wxpay: methodLimit({ single_max: 100 }),
|
wxpay: methodLimit({ single_max: 100 }),
|
||||||
@@ -43,6 +43,7 @@ describe('getVisibleMethods', () => {
|
|||||||
expect(visible).toEqual({
|
expect(visible).toEqual({
|
||||||
alipay: methodLimit({ single_min: 5 }),
|
alipay: methodLimit({ single_min: 5 }),
|
||||||
wxpay: methodLimit({ single_max: 100 }),
|
wxpay: methodLimit({ single_max: 100 }),
|
||||||
|
stripe: methodLimit({ fee_rate: 3 }),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -76,6 +77,19 @@ describe('decidePaymentLaunch', () => {
|
|||||||
expect(decision.recovery.outTradeNo).toBe('')
|
expect(decision.recovery.outTradeNo).toBe('')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('routes Stripe button click to the full Payment Element without a preselected sub-method', () => {
|
||||||
|
const decision = decidePaymentLaunch(createOrderResult({
|
||||||
|
client_secret: 'cs_test',
|
||||||
|
}), {
|
||||||
|
visibleMethod: 'stripe',
|
||||||
|
orderType: 'balance',
|
||||||
|
isMobile: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(decision.kind).toBe('stripe_route')
|
||||||
|
expect(decision.stripeMethod).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
it('uses Stripe route flow for mobile WeChat client secret', () => {
|
it('uses Stripe route flow for mobile WeChat client secret', () => {
|
||||||
const decision = decidePaymentLaunch(createOrderResult({
|
const decision = decidePaymentLaunch(createOrderResult({
|
||||||
client_secret: 'cs_test',
|
client_secret: 'cs_test',
|
||||||
|
|||||||
@@ -14,9 +14,10 @@ const VISIBLE_METHOD_ALIASES = {
|
|||||||
alipay_direct: 'alipay',
|
alipay_direct: 'alipay',
|
||||||
wxpay: 'wxpay',
|
wxpay: 'wxpay',
|
||||||
wxpay_direct: 'wxpay',
|
wxpay_direct: 'wxpay',
|
||||||
|
stripe: 'stripe',
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export type VisiblePaymentMethod = 'alipay' | 'wxpay'
|
export type VisiblePaymentMethod = 'alipay' | 'wxpay' | 'stripe'
|
||||||
export type StripeVisibleMethod = 'alipay' | 'wechat_pay'
|
export type StripeVisibleMethod = 'alipay' | 'wechat_pay'
|
||||||
export type PaymentLaunchKind =
|
export type PaymentLaunchKind =
|
||||||
| 'qr_waiting'
|
| 'qr_waiting'
|
||||||
@@ -144,7 +145,12 @@ export function decidePaymentLaunch(
|
|||||||
}, context.now)
|
}, context.now)
|
||||||
|
|
||||||
if (baseState.clientSecret) {
|
if (baseState.clientSecret) {
|
||||||
const stripeMethod: StripeVisibleMethod = visibleMethod === 'wxpay' ? 'wechat_pay' : 'alipay'
|
// visibleMethod === 'stripe' means the user clicked the dedicated Stripe button
|
||||||
|
// and should land on the full Payment Element to choose a sub-method themselves.
|
||||||
|
const isStripeButton = visibleMethod === 'stripe'
|
||||||
|
const stripeMethod: StripeVisibleMethod | undefined = isStripeButton
|
||||||
|
? undefined
|
||||||
|
: visibleMethod === 'wxpay' ? 'wechat_pay' : 'alipay'
|
||||||
const kind: PaymentLaunchKind = stripeMethod === 'alipay' && !context.isMobile
|
const kind: PaymentLaunchKind = stripeMethod === 'alipay' && !context.isMobile
|
||||||
? 'stripe_popup'
|
? 'stripe_popup'
|
||||||
: 'stripe_route'
|
: 'stripe_route'
|
||||||
|
|||||||
@@ -693,14 +693,18 @@ async function createOrder(orderAmount: number, orderType: OrderType, planId?: n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const visibleMethod = normalizeVisibleMethod(requestType) || requestType
|
const visibleMethod = normalizeVisibleMethod(requestType) || requestType
|
||||||
const stripeMethod = visibleMethod === 'wxpay' ? 'wechat_pay' : 'alipay'
|
// When user clicks the dedicated Stripe button, leave method blank so the
|
||||||
|
// landing page renders Stripe's full Payment Element (card/link/alipay/wxpay).
|
||||||
|
const stripeMethod = visibleMethod === 'stripe'
|
||||||
|
? ''
|
||||||
|
: visibleMethod === 'wxpay' ? 'wechat_pay' : 'alipay'
|
||||||
const stripeRouteUrl = result.client_secret
|
const stripeRouteUrl = result.client_secret
|
||||||
? router.resolve({
|
? router.resolve({
|
||||||
path: '/payment/stripe',
|
path: '/payment/stripe',
|
||||||
query: {
|
query: {
|
||||||
order_id: String(result.order_id),
|
order_id: String(result.order_id),
|
||||||
client_secret: result.client_secret,
|
client_secret: result.client_secret,
|
||||||
method: stripeMethod,
|
method: stripeMethod || undefined,
|
||||||
resume_token: result.resume_token || undefined,
|
resume_token: result.resume_token || undefined,
|
||||||
},
|
},
|
||||||
}).href
|
}).href
|
||||||
|
|||||||
Reference in New Issue
Block a user