Skip to main content
This guide covers two primary 3DS strategies in the Paysight Widget:
  1. Standard 3DS (with optional fallback if 3DS fails), and 2) Frictionless-only (no challenge UI).

Overview

3D Secure (3DS) adds an extra authentication step to reduce fraud and can provide liability shift benefits. Within the Paysight Widget, you control 3DS behavior via configuration flags and handle progress through widget events.

When to use which flow

  • Standard 3DS: Maximize approvals and liability shift by allowing challenge flows when required by the issuer.
  • Standard 3DS with fallback: Attempt 3DS, but if the authentication fails, continue without 3DS to reduce drop-offs.
  • Frictionless-only: Only allow frictionless 3DS (no challenge UI). If a challenge would be required, skip 3DS and proceed.
Skipping or falling back from 3DS may remove liability shift benefits. Validate policy with your risk team and acquiring agreements.

Prerequisites

1

Install and load the Widget

Ensure you have the Paysight Widget installed or loaded on your page. See Installation.
2

Confirm product and MID support

Your product/MID must be enabled to support 3DS. Confirm configuration with your Paysight account manager if unsure.
3

Implement event handling

Add an onMessage handler for 3DS and payment events. See Event Handling.

3DS Configuration Options

These options control 3DS behavior:
  • threeDSRequired (boolean): Turn on 3DS for the payment.
  • failOnThreeDSChallenge (boolean): If true, do not show a challenge UI. If a challenge is required, proceed without 3DS.
  • cancelOnThreeDSFailure (boolean): If true, cancel the payment when 3DS is not successfully completed.
The widget will emit 3DS-related events during the flow: PAYMENT_3DS_START, PAYMENT_3DS_SUCCESS, PAYMENT_3DS_ERROR, and PAYMENT_3DS_FAILURE.

Flow 1: Standard 3DS

Two configuration variants:
  1. Strict 3DS (challenge allowed, cancel on failure)
  • threeDSRequired: true
  • failOnThreeDSChallenge: false
  • cancelOnThreeDSFailure: true
  1. 3DS with fallback (challenge allowed, continue if 3DS fails)
  • threeDSRequired: true
  • failOnThreeDSChallenge: false
  • cancelOnThreeDSFailure: false
import { useEffect, useRef } from 'react';

export function Checkout3DSStrict() {
  const widgetRef = useRef<any>(null);

  useEffect(() => {
    widgetRef.current = (window as any).PaysightSDK?.createWidget({
      targetId: 'widget-container-3ds-strict',
      config: {
        productId: 7900,
        sessionId: `session_${Date.now()}`,
        environment: 'production',
        amount: 1.00,
        threeDSRequired: true,
        failOnThreeDSChallenge: false,
        cancelOnThreeDSFailure: true,
        currency: 'USD',
        locale: 'en-US',
      },
      onMessage: (message: any) => {
        switch (message.type) {
          case 'PAYMENT_3DS_START':
            // show loading UI for 3DS
            break;
          case 'PAYMENT_3DS_SUCCESS':
            // hide loading, proceed to confirmation
            break;
          case 'PAYMENT_3DS_ERROR':
          case 'PAYMENT_3DS_FAILURE':
            // 3DS failed -> with cancelOnThreeDSFailure: true the payment will not proceed
            // show retry UI
            break;
          case 'PAYMENT_SUCCESS':
            // order success UI
            break;
          case 'PAYMENT_ERROR':
            // show error UI
            break;
        }
      },
      onError: (error: any) => {
        console.error('Widget error:', error);
      },
    });
    return () => widgetRef.current?.destroy?.();
  }, []);

  return <div id="widget-container-3ds-strict" />;
}

Flow 2: 3DS Frictionless-only

Frictionless-only means you will not show a 3DS challenge UI. If the issuer requires a challenge, the widget will proceed without performing 3DS.
  • threeDSRequired: true
  • failOnThreeDSChallenge: true (skip challenge, only frictionless allowed)
  • cancelOnThreeDSFailure: choose behavior if frictionless fails
    • true: cancel payment if frictionless fails
    • false: continue without 3DS even if frictionless fails
import { useEffect, useRef } from 'react';

export function Checkout3DSFrictionlessOnly() {
  const widgetRef = useRef<any>(null);

  useEffect(() => {
    widgetRef.current = (window as any).PaysightSDK?.createWidget({
      targetId: 'widget-container-3ds-frictionless',
      config: {
        productId: 7900,
        sessionId: `session_${Date.now()}`,
        environment: 'production',
        amount: 1.00,
        threeDSRequired: true,
        failOnThreeDSChallenge: true, // enforce frictionless-only
        cancelOnThreeDSFailure: false, // continue even if frictionless fails
        currency: 'USD',
        locale: 'en-US',
      },
      onMessage: (message: any) => {
        switch (message.type) {
          case 'PAYMENT_3DS_START':
            // frictionless check started
            break;
          case 'PAYMENT_3DS_SUCCESS':
            // frictionless succeeded
            break;
          case 'PAYMENT_3DS_ERROR':
          case 'PAYMENT_3DS_FAILURE':
            // frictionless failed; with cancelOnThreeDSFailure: false, payment will continue
            break;
          case 'PAYMENT_SUCCESS':
            // success UI
            break;
          case 'PAYMENT_ERROR':
            // error UI
            break;
        }
      },
    });
    return () => widgetRef.current?.destroy?.();
  }, []);

  return <div id="widget-container-3ds-frictionless" />;
}

Event Handling Essentials

Handle these events to keep users informed and manage edge cases:
onMessage: (message) => {
  switch (message.type) {
    case 'PAYMENT_START':
      // Disable submit, show "Processing"
      break;
    case 'PAYMENT_3DS_START':
      // Show "Verifying with 3D Secure..."
      break;
    case 'PAYMENT_3DS_SUCCESS':
      // Update UI and continue
      break;
    case 'PAYMENT_3DS_ERROR':
    case 'PAYMENT_3DS_FAILURE':
      // Depending on config, either retry or continue without 3DS
      break;
    case 'PAYMENT_SUCCESS':
      // Confirmation UI / redirect
      break;
    case 'PAYMENT_ERROR':
      // Show error and allow retry
      break;
  }
}
Full event details and patterns: Event Handling and Events Reference.

Testing

1

3DS Testing Flow

To test the 3DS flow, use the widget in production and use a real card to perform a 3DS flow test. Please note that you may receive a frictionless flow or a challenge flow depending on the card you use.
2

Expect variability

Whether a challenge is required depends on issuer risk. Test multiple times and with different cards to observe 3DS vs frictionless behavior.
3

Track outcomes

Log all PAYMENT_3DS_* and PAYMENT_* events in development to validate your UX and fallback logic.

Best Practices

  • Communicate clearly: Tell users when additional verification may be required.
  • Be intentional with fallback: Only continue without 3DS if your risk policy allows it.
  • Measure conversion: A/B test strict vs fallback vs frictionless-only to find the best balance of security and UX.
  • Surface failures: If you continue without 3DS, consider showing a subtle banner indicating verification was skipped.

See Also