Skip to main content
ThreeDS coordinates 3D Secure from the browser after a card is tokenized. Get one from radiumone.threeDS(). One flow runs at a time per instance — a concurrent call throws three-ds:in_progress; use a separate instance for parallel flows.
Never use a secret key (r1sk_…) in browser code, mobile apps, or anywhere a shopper can inspect it. Secret keys belong on your server only.
For the full integration walkthrough (session amount pinning, challenge presentation, results), see 3D Secure with Elements.

authenticate(context, options?)

Run 3D Secure for a bound card, from start to a terminal outcome, in one call. Collects browser data, calls POST /gateway/v1/3ds/authenticate, then performs whatever the gateway asks (device data collection, challenge, decoupled approval), polling GET /gateway/v1/3ds/status until a terminal status. Waits are capped at 5 minutes. No amount or currency is sent — the gateway takes them from the session. Only one flow may run per instance. Error codes: the three-ds:* codes below mean the call was constructed wrong. The urn:radiumone:three-ds:* codes are flow failures to handle at runtime; gateway error URNs are passed through verbatim. Full catalogue: docs/reference/error-codes.json.
ThreeDSAuthenticateContext
required
Session and card token. See ThreeDSAuthenticateContext.
ThreeDSHandleOptions
Presentation, cancellation and decoupled-UI options.
Returns Promise<ThreeDSResult> — The terminal status and the 3DS ref for authorization. Throws:

handle(action, options?)

Drive a gateway 3DS action (obtained by your server) to a terminal outcome. Same flow and errors as ThreeDS.authenticate, minus the initial authenticate call and its argument checks. Pass the gateway action object unchanged.
ThreeDSAction
required
The gateway action. See ThreeDSAction.
ThreeDSHandleOptions
Presentation, cancellation and decoupled-UI options.
Returns Promise<ThreeDSResult> — The terminal status and the 3DS ref for authorization. Throws:
  • three-ds:invalid_action (validation_error) — action is not an object with a string type.
  • three-ds:in_progress (rate_limited) — a flow is already running on this instance.
  • ElementsError urn:radiumone:three-ds:* and gateway URNs — as for ThreeDS.authenticate.

getPendingRedirect()

Detect whether this page load is the return from a redirect challenge. Reads the pending reference from sessionStorage, then from the action_ref URL query or fragment parameter. Call at the top of your return page. Returns PendingRedirect | null — The pending redirect, or null if this is not a 3DS return. PendingRedirect (the returned value):
string
required
The in-flight 3DS action reference being resumed.

resume()

Finish a redirect challenge on the return page. Needs only the publishable key: reads the pending reference (see ThreeDS.getPendingRedirect) and fetches the final status once. Safe to call again. No card Elements or session secret are required. Returns Promise<ThreeDSResult> — The terminal status and the 3DS ref. Throws:
  • urn:radiumone:three-ds:action-malformed (validation_error) — no pending redirect, or the status is not terminal yet.
  • ElementsError urn:radiumone:three-ds:provider-unavailable, urn:radiumone:three-ds:action-not-found, gateway URNs — as for ThreeDS.authenticate.

ThreeDSResult

string
required
3DS reference to pass to your server’s authorization call.
ThreeDSStatus
required
Terminal status — never DECOUPLED or PENDING. See ThreeDSStatus.
ThreeDSStatus values: AUTHENTICATED, ATTEMPTED, NOT_AUTHENTICATED, FAILED, REJECTED, DECOUPLED, EXPIRED, PENDING

ThreeDSAction

For integrations that obtain the first 3DS action server-side and pass it to handle() unchanged — most integrations never touch this shape directly.
string
required
Gateway reference for this action; used for continue and status calls.
{ acs_url: string; fields: Record<string, string>; window_size?: string; notification_ref: string; redirectable?: boolean; }
Issuer challenge step. Present on challenge actions.
{ expires_at: string; poll_interval_ms?: number; }
Out-of-band approval step. Present on decoupled actions.
{ url: string; }
Hosted challenge URL for gateway_hosted render mode. Not supported yet.
{ url: string; fields: Record<string, string>; timeout_ms?: number; }
Device data collection step. Present on method actions.
number
default:"5000 for challenge, 3000 for decoupled"
Status poll interval in milliseconds for challenge and decoupled actions. Values below 1000 are raised to 1000.
boolean
Gateway hint that the browser handles a full-page redirect better than an iframe (for example an in-app webview). Honoured when challengePresentation is 'auto'.
ThreeDSRenderMode
Challenge rendering mode. Present on challenge actions.
ThreeDSStatus
Outcome. Required on terminal action types; a terminal action without a valid status rejects with urn:radiumone:three-ds:action-malformed.
ThreeDSActionType
required
What the SDK must do next. See ThreeDSActionType.

ThreeDSBrowserData

Collected automatically by authenticate() — exported for reference, not something you construct.
number
required
screen.colorDepth.
boolean
required
navigator.javaEnabled(); false when unavailable.
boolean
required
Always true.
string
required
navigator.language (BCP 47 tag).
number
required
screen.height in CSS pixels.
number
required
screen.width in CSS pixels.
number
required
UTC offset in minutes, from Date#getTimezoneOffset() — positive when behind UTC, so UTC+8 is -480.

Example

Gateway calls

The SDK makes these gateway HTTP calls on your behalf — bind runs from elements.submit(), the rest from authenticate()/handle()/resume(). You don’t call these directly; this is for troubleshooting with network traces or support. Base URL is the API origin for the key’s environment (production api.radiumone.io, sandbox api-sandbox.radiumone.io) — see Content Security Policy.

Errors

3DS-specific error codes (three-ds:*) and gateway URNs are documented on 3D Secure errors. Status-outcome tables (what each status means and whether to authorize) live on Authentication results. For recovery steps, see Handle 3D Secure failures in Elements.
Last modified on September 15, 2026