Worldpay.ThreeDS (Worldpay v1.0.0)

Copy Markdown View Source

Worldpay 3DS API — Strong Customer Authentication.

Handles the full 3DS authentication flow:

  1. Device data collection
  2. Authentication request (sends order + device data to card schemes)
  3. Challenge display (if outcome is "challenged")
  4. Apply eci + authenticationValue to the card payment

Web flow

# Step 1 — device data collection
{:ok, ddc} = Worldpay.ThreeDS.device_data(session_href, config)
# → render ddc["_links"]["3ds:deviceDataCollection"]["href"] in an iFrame

# Step 2 — authenticate
{:ok, auth} = Worldpay.ThreeDS.authenticate(auth_body, config)

# auth["outcome"] is "authenticated" | "challenged" | "unAuthenticated" | "authenticationOutage"

# Step 3 (if challenged) — render iFrame from auth["_links"]["3ds:challenge"]["href"]
# Customer completes challenge, then re-poll or receive webhook

# Step 4 — attach result to payment
three_ds = Worldpay.ThreeDS.build_auth_object(auth)

{:ok, payment} =
  Worldpay.CardPayments.authorize(
    Map.put(instruction, "threeDS", three_ds),
    config
  )

Outcomes

OutcomeAction
"authenticated"Apply eci + authenticationValue to payment
"challenged"Render challenge iFrame; await completion
"unAuthenticated"Do not proceed; SCA failed
"authenticationOutage"Issuer outage; exemption may auto-apply

Summary

Functions

Authenticate the customer (step 2).

Authenticate and extract the fields needed for a card payment.

Build the threeDS object to embed in a Card Payments authorize request from a successful authentication response map.

Initiate device data collection (step 1 of web 3DS flow).

Types

auth_result()

@type auth_result() :: %{
  eci: String.t() | nil,
  authentication_value: String.t() | nil,
  transaction_id: String.t() | nil,
  version: String.t() | nil
}

Functions

authenticate(body, config)

@spec authenticate(map(), Worldpay.Config.t()) ::
  {:ok, map()} | {:error, Worldpay.Error.t()}

Authenticate the customer (step 2).

Required body fields

  • sessionHref — from Checkout SDK
  • deviceData — from device data collection response
  • merchant.entity
  • instruction.value
  • instruction.paymentInstrument

Optional fields

  • challengePreference"noChallengeRequested" | "challengeRequested" | "challengeMandated" | "noChallengeRequestedTRAPerformed"

  • customerData — South Korea / Toss Pay domestic payments
  • bypassOn / continueOn — 3DS bypass controls (Jun 2026)

authenticate_and_extract(body, config)

@spec authenticate_and_extract(%{required(String.t()) => term()}, Worldpay.Config.t()) ::
  {:ok, auth_result()} | {:error, Worldpay.Error.t()}

Authenticate and extract the fields needed for a card payment.

Returns {:ok, %{eci: ..., authentication_value: ..., transaction_id: ..., version: ...}} on success, {:error, Error.t()} on challenge required or failure.

build_auth_object(resp)

@spec build_auth_object(%{required(String.t()) => term()}) :: %{
  required(String.t()) => String.t()
}
@spec build_auth_object(map()) :: map()

Build the threeDS object to embed in a Card Payments authorize request from a successful authentication response map.

device_data(session_href, device_info \\ %{}, config)

@spec device_data(String.t(), map(), Worldpay.Config.t()) ::
  {:ok, map()} | {:error, Worldpay.Error.t()}

Initiate device data collection (step 1 of web 3DS flow).