feat: add Airwallex payments and multi-currency support
This commit is contained in:
@@ -15,15 +15,17 @@ const VISIBLE_METHOD_ALIASES = {
|
||||
wxpay: 'wxpay',
|
||||
wxpay_direct: 'wxpay',
|
||||
stripe: 'stripe',
|
||||
airwallex: 'airwallex',
|
||||
} as const
|
||||
|
||||
export type VisiblePaymentMethod = 'alipay' | 'wxpay' | 'stripe'
|
||||
export type VisiblePaymentMethod = 'alipay' | 'wxpay' | 'stripe' | 'airwallex'
|
||||
export type StripeVisibleMethod = 'alipay' | 'wechat_pay'
|
||||
export type PaymentLaunchKind =
|
||||
| 'qr_waiting'
|
||||
| 'redirect_waiting'
|
||||
| 'stripe_popup'
|
||||
| 'stripe_route'
|
||||
| 'airwallex_route'
|
||||
| 'wechat_oauth'
|
||||
| 'wechat_jsapi'
|
||||
| 'unhandled'
|
||||
@@ -37,6 +39,10 @@ export interface PaymentRecoverySnapshot {
|
||||
payUrl: string
|
||||
outTradeNo: string
|
||||
clientSecret: string
|
||||
intentId: string
|
||||
currency: string
|
||||
countryCode: string
|
||||
paymentEnv: string
|
||||
payAmount: number
|
||||
orderType: OrderType | ''
|
||||
paymentMode: string
|
||||
@@ -52,6 +58,7 @@ export interface PaymentLaunchContext {
|
||||
now?: number
|
||||
stripePopupUrl?: string
|
||||
stripeRouteUrl?: string
|
||||
airwallexRouteUrl?: string
|
||||
}
|
||||
|
||||
export interface PaymentLaunchDecision {
|
||||
@@ -138,12 +145,24 @@ export function decidePaymentLaunch(
|
||||
payUrl: result.pay_url || '',
|
||||
outTradeNo: result.out_trade_no || '',
|
||||
clientSecret: result.client_secret || '',
|
||||
intentId: result.intent_id || '',
|
||||
currency: result.currency || '',
|
||||
countryCode: result.country_code || '',
|
||||
paymentEnv: result.payment_env || '',
|
||||
payAmount: result.pay_amount,
|
||||
orderType: context.orderType,
|
||||
paymentMode: (result.payment_mode || '').trim(),
|
||||
resumeToken: result.resume_token || '',
|
||||
}, context.now)
|
||||
|
||||
if (visibleMethod === 'airwallex' && baseState.clientSecret && baseState.intentId) {
|
||||
if (!context.airwallexRouteUrl) {
|
||||
return { kind: 'unhandled', paymentState: baseState, recovery: baseState }
|
||||
}
|
||||
const paymentState = { ...baseState, payUrl: context.airwallexRouteUrl || '' }
|
||||
return { kind: 'airwallex_route', paymentState, recovery: paymentState }
|
||||
}
|
||||
|
||||
if (baseState.clientSecret) {
|
||||
// visibleMethod === 'stripe' means the user clicked the dedicated Stripe button
|
||||
// and should land on the full Payment Element to choose a sub-method themselves.
|
||||
@@ -239,6 +258,10 @@ export function readPaymentRecoverySnapshot(
|
||||
|| typeof parsed.payUrl !== 'string'
|
||||
|| (parsed.outTradeNo != null && typeof parsed.outTradeNo !== 'string')
|
||||
|| typeof parsed.clientSecret !== 'string'
|
||||
|| (parsed.intentId != null && typeof parsed.intentId !== 'string')
|
||||
|| (parsed.currency != null && typeof parsed.currency !== 'string')
|
||||
|| (parsed.countryCode != null && typeof parsed.countryCode !== 'string')
|
||||
|| (parsed.paymentEnv != null && typeof parsed.paymentEnv !== 'string')
|
||||
|| typeof parsed.payAmount !== 'number'
|
||||
|| typeof parsed.paymentMode !== 'string'
|
||||
|| typeof parsed.resumeToken !== 'string'
|
||||
@@ -265,6 +288,10 @@ export function readPaymentRecoverySnapshot(
|
||||
payUrl: parsed.payUrl,
|
||||
outTradeNo: parsed.outTradeNo || '',
|
||||
clientSecret: parsed.clientSecret,
|
||||
intentId: parsed.intentId || '',
|
||||
currency: parsed.currency || '',
|
||||
countryCode: parsed.countryCode || '',
|
||||
paymentEnv: parsed.paymentEnv || '',
|
||||
payAmount: parsed.payAmount,
|
||||
orderType: parsed.orderType === 'subscription' ? 'subscription' : 'balance',
|
||||
paymentMode: parsed.paymentMode,
|
||||
|
||||
Reference in New Issue
Block a user