3DS Challenge Element

Mount the issuer 3DS challenge returned by a card operation and resolve the flow on its outcome.

Before You Start

Read the following guides before proceeding:

GuideWhy
PCI Compliant SDKIsolation model and package map
SDK SetupCSP entry for the 3DS orchestrator origin
Top-Up TransferThe operation that returns three_ds_state

Overview

@wirexapp/card-3ds-web mounts the 3DS step-up challenge an issuer demands during a card operation. The
challenge is a Wirex-hosted orchestrator page rendered in an iframe; the package owns the message handling
around it — origin verification, protocol parsing and once-only resolution.

No cardholder data passes through your page at any point of the 3DS step. The package depends on nothing
else in the SDK and does not use the frame origin.

This element runs the issuer challenge for an operation your application initiated, such as a card
top-up debit. It is not the in-app approval flow for transactions made on an issued Wirex card — that
flow is webhook-driven and documented in 3DS Authentication.


When You Need It

API operations that can require a step-up return a challenge URL when the issuer demands one. Card top-up
execute returns it as three_ds_state.url:

{
  "id": "d4e5f6a7-b8c9-0123-def4-567890123456",
  "status": "Pending",
  "three_ds_state": {
    "flow": "challenge",
    "provider": "checkout",
    "status": "pending",
    "status_reason": "authentication_required",
    "url": "https://3ds.example/challenge?session_token=abc123"
  }
}

Run the challenge when three_ds_state.url is present. When three_ds_state is absent, no step-up is
required and the operation proceeds.


Mount the Challenge

import { createThreeDsChallenge } from '@wirexapp/card-3ds-web';

const challenge = createThreeDsChallenge({
  url: execute.three_ds_state.url,
  onComplete: status => finishTopUp(status),
  onError: message => {
    showToast(message);
    finishTopUp('Failed');
  },
  onLoad: () => hideSpinner(),
  title: '3DS Verification',
});

challenge.mount(document.querySelector('#threeds-container'));

// When the user cancels from your own UI:
challenge.destroy();
FieldTypeRequiredDescription
urlstringYesChallenge URL from the API response. Must be https://
onComplete(status: string) => voidYesThe orchestrator finished with a status
onError(message: string) => voidYesThe step-up failed before producing a status. The message is safe to display
onLoad() => voidNoThe iframe document finished loading
titlestringNoAccessible iframe title. Default 3DS Verification

onComplete and onError fire exactly once. Mounting an element twice throws
ThreeDsChallenge is already mounted.


Outcome Statuses

onComplete receives the backend's status string, matched case-insensitively.

StatusMeaningAction
CompletedThe step-up succeededContinue the flow to its settled outcome
PendingThe outcome is not yet knownReconcile from the activity feed or webhooks
FailedThe step-up failedReport the failure to the user

Treat any other value as unknown and direct the user to their activity feed. A step-up outcome is not the
final state of the operation — the operation's own status and its webhooks own that.


Sizing and Cancellation

  • The iframe fills its container at 100% width and height. Give the container explicit dimensions; issuer
    challenge pages are commonly designed for 500×480 pixels or larger.
  • Render a light background behind the iframe. Many issuer pages assume a light container.
  • Cancel and back navigation are yours. Render your own control and call destroy().

Treat a user-cancelled challenge as Pending, not Failed. The operation can still complete after
the challenge iframe is removed. Reconcile from your activity feed or webhooks rather than reporting a
failure to the user.


What the Element Enforces

  • Messages are accepted only from the challenge URL's HTTPS origin and only from the exact iframe the
    element created. Messages from any other frame or origin are ignored.
  • A challenge URL that is not parseable or not https:// fails through onError with
    3DS verification URL is invalid, and no message listener is attached.
  • A stepUp.complete message carrying no status fails through onError with
    3DS verification returned no status.
  • An enrollment error riding inside an otherwise-successful message is detected and surfaced through
    onError with the backend's reason.

Content Security Policy

The orchestrator page is served by a Wirex backend origin, not by the card-frame origin. Add that origin —
named in your onboarding pack — to frame-src alongside the frame origin. See
SDK Setup.


Did this page help you?