Confirm-on-client shape (§4a): Stripe finalizes here, including inline 3DS (redirect: "if_required" keeps card flows in an iframe/modal — no navigation). Never returns a clientToken.
Return-trip completion for redirect methods (iDEAL, bank redirects): Stripe lands the customer on returnUrl with payment_intent_client_secret (or setup_intent_client_secret) + redirect_status in the query string. Resolves the actual outcome from the intent itself — redirect_status alone is a hint, not the source of truth. Returns null when the URL carries no Stripe return params, so callers can probe every adapter safely.
Loads Stripe.js once, in the build config.apiVersion names, with
cspNonce on the tag; mount() and handleRedirectReturn() call it
first. A page runs one Stripe.js build, as a second copy leaves
window.Stripe to the first, so the adapter uses the Stripe.js it finds,
as Stripe's own loader does, whether the page had it before the call or
another script defined it while the adapter's own was loading. Its
version decides how: v3 is given config.apiVersion, a release's
version included, and then speaks exactly it; another versioned build
speaks the API version Stripe pins it to, and in a sandbox the adapter
warns once on the console; a global whose version names no build is
used as if it were the build config.apiVersion names. Beside a Stripe.js
v2 global, the build loads and attaches itself as window.Stripe.StripeV3,
which the adapter uses.
A <script> the page added for the build's URL is waited for, for up to
30 seconds, since it may still be loading: the call resolves when it loads,
or as soon as another script defines a usable Stripe.js, and otherwise
rejects with a retryable psp_unavailable when the tag fails, which removes
it, or when the wait ends. A page tag that failed before the call leaves no
sign of it, so that first call waits the full 30 seconds. A load that fails
or leaves Stripe.js missing is not kept: the next call loads again, and
replaces with a fresh one a tag that an earlier call, of any adapter on the
page, watched settle without Stripe.js: one the adapter injected, after it
loaded, or a page's, after its wait.
Renders the PSP's hosted fields into container.
Layout slot convention (split-field PSPs like Paysafe): when the host has
placed elements carrying data-payfanout-field="<fieldName>" inside the
container, the adapter mounts each hosted field INTO its slot — the host
fully owns the layout (grid, rows, spacing). Without slots, the adapter
falls back to its own stacked containers. Single-element PSPs (Stripe's
Payment Element) control layout via MountOptions.fieldOptions instead.
Stripe's Payment Element in the browser, confirm-on-client:
confirm()finalizes the PaymentIntent the server adapter created. Stripe.js loads lazily fromhttps://js.stripe.com, in the build ofconfig.apiVersion, so the browser follows the host's pin, not the account's default version.