OptionalbillingAVS data — order.customer.billingAddress on the payment.
Epoch milliseconds. Tokens without it are rejected.
The Hosted Tokenization id created at session time (POST /hostedtokenizations).
OptionalidHost-app internal id (PaymentSession.id), round-tripped via order.references.merchantReference.
OptionalmetadataThe session's metadata as the JSON sent for it reads back, when that has entries: order.references.merchantParameters on the payment. Contexts signed before it was carried have none. Signed, not encrypted: whoever holds the token can read it.
OptionalreceiptCustomer email (order.customer.contactDetails.emailAddress on the payment).
Optionalreturn3-D Secure return URL (sent as both cardPaymentMethodSpecificInput.returnUrl and its threeDSecure.redirectionData form): the session's own, or the adapter's defaultReturnUrl. Contexts signed before it became mandatory may lack it or carry an empty one; completePayment then falls back to defaultReturnUrl.
OptionalscaSCA preference. challenge: "force" becomes threeDSecure.challengeIndicator
"challenge-required". exemption: "moto" becomes
cardPaymentMethodSpecificInput.transactionChannel "MOTO", Worldline's mail order /
telephone order channel, and leaves the 3-D Secure data unchanged.
OptionalshippingOptionalstatementStatement text (order.references.softDescriptor on the payment).
Worldline Direct's Hosted Tokenization is tokenize-first: the browser tokenizes the card into a
hostedTokenizationId, and the payment object only exists once the server'scompletePaymentcall creates it — yet that call needs amount/currency/capture-method, none of which are sent at tokenization time. PayFanout is stateless, socreatePaymentSessionencodes that context into thepspSessionIditself:base64url(json) + "." + base64url(hmac).The HMAC (sessionSigningKey) makes the context tamper-proof: the token may pass through the browser, and without the signature a client could inflate/deflate the amount before server completion. The client adapter never needs this token — the tokenization iframe is addressed by the session's
clientSecret(the hostedTokenizationUrl), andconfirm()returns a clientToken carrying thehostedTokenizationIdand the browser's device data, which completePayment decodes separately (see client-token.ts). It is signed, not encrypted: whoever holds the token can read the JSON half.Every context carries an expiry (
expiresAt, epoch ms): a signed token must not stay completable forever. Enforced at decode time —completePaymentrejects 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.