Paysafe documents no query parameters on the return trip — it signals the outcome by WHICH returnLinks rel it sends the customer to, and the server adapter deliberately points them all at the host's one returnUrl. So the marker the server plants there is the only reliable evidence a Paysafe redirect landed, and the landing spot never decides the outcome: the rail is server-completed, so the host finalizes with completePayment. The clientToken is a placeholder — the real handle token rides the signed session context and the server ignores the wire value once a handle is minted — but it must be present and non-empty, because the standard completion transport only fires when a clientToken exists and the completion route rejects an empty one. Returns null on any other URL, so a router can probe every adapter safely.
Dynamic script/SDK load — only pulled in if this PSP is active.
Renders Paysafe's hosted iframe fields (SAQ-A eligible: card data never touches the host DOM). Layout is host-controllable: elements inside the container carrying data-payfanout-field="cardNumber|expiryDate|cvv" become the mount points (the host owns rows/grid/spacing); missing slots fall back to adapter-created stacked containers. Placeholders and any other per-field or SDK option come from MountOptions.fieldOptions / locale.
Tokenize-first shape (§4a): resolves with requires_confirmation plus the Payment Handle token. The host passes that clientToken to the server's completePayment — wires this automatically. 3DS runs inline
inside Paysafe.js during tokenize (challenge iframe), never a navigation.
Redirect rails have no token to produce: confirm() hands the page to the provider and the outcome resolves server-side after the return trip.
Bank-debit rails tokenize nothing: confirm() reads the typed details and packs them into the envelope the server's completePayment mints the handle from.