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

  1. Allow js.airwallex.com (and its CDN) in the page CSP script-src/connect-src.
  2. Pin the Airwallex web SDK version explicitly and verify the loaded bundle exposes window.Airwallex().payments.
  3. Check the network tab for blocked/failed airwallex requests and disable ad blockers on the checkout page.
  4. 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

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


AI-assisted analysis of Wei-Shaw/sub2api@073e92d171 (2026-08-15). Data as JSON: /api/errors/f69f68d6d7a98585. Report an issue: GitHub.