Wei-Shaw/sub2api · error
payment.airwallexLoadFailed
Error message
payment.airwallexLoadFailed
What it means
In frontend/src/views/user/AirwallexPaymentView.vue:119, the code awaits loadAirwallex({ locale }) (the Airwallex Web SDK), then checks result.payments — the payments module needed for redirectToCheckout. If the SDK loaded but initialized without a payments module (wrong package entry, blocked script, init failure swallowed), it throws the localized 'payment.airwallexLoadFailed'. The same key is the generic fallback in the catch block.
Source
Thrown at frontend/src/views/user/AirwallexPaymentView.vue:119
try {
const airwallex = await import('@airwallex/components-sdk')
const result = await airwallex.init({
env: snapshot.paymentEnv === 'prod' ? 'prod' : 'demo',
enabledElements: ['payments'],
locale: checkoutLocale,
})
loading.value = false
const checkoutOptions = {
intent_id: snapshot.intentId,
client_secret: snapshot.clientSecret,
currency: snapshot.currency || 'CNY',
country_code: snapshot.countryCode || 'CN',
successUrl: buildSuccessUrl(snapshot),
}
if (!result.payments) {
throw new Error(t('payment.airwallexLoadFailed'))
}
const redirectResult = result.payments.redirectToCheckout(checkoutOptions)
if (typeof redirectResult === 'string' && redirectResult) {
window.location.assign(redirectResult)
}
} catch (err: unknown) {
loading.value = false
errorMessage.value = err instanceof Error && err.message
? err.message
: t('payment.airwallexLoadFailed')
}
})
</script>
View on GitHub (pinned to 073e92d171)
Solutions
- Allow js.airwallex.com (and its CDN) in the page CSP script-src/connect-src.
- Pin the Airwallex web SDK version explicitly and verify the loaded bundle exposes window.Airwallex().payments.
- Check the network tab for blocked/failed airwallex requests and disable ad blockers on the checkout page.
- Validate the intent is still active (not expired) before loading the SDK; refresh the payment session if not.
Example fix
// before
if (!result.payments) {
throw new Error(t('payment.airwallexLoadFailed'))
}
const redirectResult = result.payments.redirectToCheckout(checkoutOptions)
// after
if (!result.payments || typeof result.payments.redirectToCheckout !== 'function') {
throw new Error(t('payment.airwallexLoadFailed'))
}
try {
const redirectResult = await result.payments.redirectToCheckout(checkoutOptions)
if (typeof redirectResult === 'string' && redirectResult) window.location.assign(redirectResult)
} catch (e) {
errorMessage.value = e instanceof Error && e.message ? e.message : t('payment.airwallexLoadFailed')
} Defensive patterns
Strategy: type-guard
Validate before calling
// Verify the SDK exposes the payments module with the method you need before checkout:
const aw = await loadAirwallex({ locale: checkoutLocale });
if (!aw?.payments || typeof aw.payments.redirectToCheckout !== 'function') {
errorMessage.value = t('payment.airwallexLoadFailed');
return;
} Type guard
interface AirwallexPayments { redirectToCheckout(opts: Record<string, unknown>): unknown }
function hasPaymentsModule(aw: unknown): aw is { payments: AirwallexPayments } {
return !!aw && typeof (aw as any)?.payments?.redirectToCheckout === 'function';
} Try / catch
try {
const aw = await loadAirwallex({ locale });
if (!hasPaymentsModule(aw)) throw new Error(t('payment.airwallexLoadFailed'));
await aw.payments.redirectToCheckout(checkoutOptions);
} catch (err) {
loading.value = false;
errorMessage.value = err instanceof Error && err.message ? err.message : t('payment.airwallexLoadFailed');
} Prevention
- Allow js.airwallex.com in CSP script-src/connect-src
- Pin the Airwallex web SDK version and assert window.Airwallex().payments exists after load
- Check the intent is still active before loading the SDK; refresh expired payment sessions
- Warn users when a blocker/extension prevented the SDK from fully loading
When it happens
Trigger: Airwallex SDK script loads partially or an older/different bundle is served that lacks the payments namespace; loadAirwallex resolves with an incomplete object because the script was blocked by a CSP without script-src allowing js.airwallex.com; network interception (ad blocker) loading a stub; SDK version drift where payments moved to a submodule import.
Common situations: Strict Content-Security-Policy blocking the third-party SDK; regional network filtering of airwallex domains (common in mainland China); bundler resolving a mock/outdated airwallex package; the checkout intent (intentId/clientSecret) expired so init degrades.
Related errors
- Passkeys are not supported by this browser
- Passkey sign-in was cancelled
- Passkey creation was cancelled
- HTTP error! status: ${response.status}
- No response body
AI-assisted analysis of Wei-Shaw/sub2api@073e92d171 (2026-08-15).
Data as JSON: /api/errors/f69f68d6d7a98585.
Report an issue: GitHub.