OptionalbillingAVS data — Paysafe rejects card payments without a zip (error 3004).
OptionalcountryEpoch milliseconds. Tokens without it are rejected.
OptionalidHost-app internal id (PaymentSession.id), round-tripped for completePayment.
OptionalmerchantAbsent = single-account API key; Paysafe routes by key + currency.
OptionalmetadataOptionalpaymentRedirect rails only: the handle minted at session creation. Card sessions have no token until the browser tokenizes, so completePayment takes it from the caller instead.
OptionalpaymentPaysafe paymentType for rails that are not Paysafe.js-tokenizable: the handle's type for redirect rails minted at session creation (Interac e-Transfer), the rail to mint at completion for bank debits (SEPA/ACH/BACS/EFT). Absent on card sessions, which tokenize in the browser and learn their type only at completion.
OptionalreceiptCustomer email (profile.email on the payment).
OptionalredirectRedirect rails only: the Paysafe-hosted URL the client adapter navigates to.
OptionalreturnOptionalshippingOptionalstatementStatement text (merchantDescriptor.dynamicDescriptor on the payment).
Optionalwebhook
Paysafe is tokenize-first (§4a): no PSP object exists until the server's completePayment call, yet that call needs amount/currency/merchant-account. PayFanout is stateless, so createPaymentSession encodes that context into the pspSessionId itself:
base64url(json) + "." + base64url(hmac).The HMAC (sessionSigningKey) makes the context tamper-proof: the token round-trips through the browser, and without the signature a client could inflate/deflate the amount before server completion. The client adapter only READS the payload half (for tokenize params) — it never needs the key.
Every context carries an expiry (
expiresAt, epoch ms): a signed token must not stay completable forever. Enforced at decode time — completePayment, verifyPaymentMethod, and updatePaymentSession all reject expired tokens with code "session_expired" (hosts recover by creating a fresh session).Crypto is WebCrypto (async) so this module runs on edge runtimes too.