PayFanout API reference
    Preparing search index...

    Interface PaysafeSessionContextV1

    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.

    interface PaysafeSessionContextV1 {
        amount: number;
        billingDetails?: {
            address?: {
                city?: string;
                country?: string;
                line1?: string;
                postalCode?: string;
            };
            email?: string;
            name?: string;
        };
        captureMethod: "automatic"
        | "manual";
        country?: string;
        currency: string;
        expiresAt: number;
        id?: string;
        merchantAccountId?: string;
        metadata?: Record<string, string>;
        paymentHandleToken?: string;
        paymentType?: string;
        receiptEmail?: string;
        redirectUrl?: string;
        returnUrl?: string;
        shippingDetails?: ShippingDetails;
        statementDescriptor?: string;
        v: 1;
        webhookUrl?: string;
    }
    Index
    amount: number
    billingDetails?: {
        address?: {
            city?: string;
            country?: string;
            line1?: string;
            postalCode?: string;
        };
        email?: string;
        name?: string;
    }

    AVS data — Paysafe rejects card payments without a zip (error 3004).

    captureMethod: "automatic" | "manual"
    country?: string
    currency: string
    expiresAt: number

    Epoch milliseconds. Tokens without it are rejected.

    id?: string

    Host-app internal id (PaymentSession.id), round-tripped for completePayment.

    merchantAccountId?: string

    Absent = single-account API key; Paysafe routes by key + currency.

    metadata?: Record<string, string>
    paymentHandleToken?: string

    Redirect 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.

    paymentType?: string

    Paysafe 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.

    receiptEmail?: string

    Customer email (profile.email on the payment).

    redirectUrl?: string

    Redirect rails only: the Paysafe-hosted URL the client adapter navigates to.

    returnUrl?: string
    shippingDetails?: ShippingDetails
    statementDescriptor?: string

    Statement text (merchantDescriptor.dynamicDescriptor on the payment).

    v: 1
    webhookUrl?: string