3D Secure

Enhance your online payment security with 3D Secure, the standard authentication protocol. Reduce unauthorized transactions with an extra verification layer, protecting your business and customers without compromising the user experience.

3D Secure (3DS) is an authentication protocol designed to enhance the security of online card transactions. It helps prevent unauthorized card use by requiring additional verification from the cardholder during the payment process. This extra authentication layer reduces fraud and ensures that the transaction is being carried out by the rightful owner of the card.

3D Secure is widely used by merchants, payment providers, and financial institutions to improve transaction security while maintaining a smooth customer experience.


How 3D Secure Works

When a customer initiates an online purchase and the processor has 3D Secure enabled, the following process occurs:

  1. Transaction Initiation: The customer enters their card details on your website.
  2. Authentication Request: The transaction is sent to Localpayment, who evaluates whether authentication is needed.
  3. User Verification: If authentication is required, the customer is redirected to a secure page where they must verify their identity (e.g., using a one-time password, biometrics, or bank app authentication). If no cardholder authentication is required (frictionless flow), the payment flow established on your website continues according to the result of the request processing.
  4. Authentication Result:
    • If authentication is successful, the customer will be redirected to the URL specified in the redirectUrl.onSuccess property of the request.
    • If authentication fails, the customer will be redirected to the URL specified in the redirectUrl.onError property.
    • The authentication result will also be returned in the API response.
  5. Payment Completion: If successfully authenticated, the transaction proceeds as usual. If authentication fails, the payment is declined.

Authentication Flow Diagram

The sequence below shows both possible outcomes: the frictionless flow (no challenge) and the challenge flow, where the cardholder must enter a one-time password (OTP) on the issuer's authentication page.

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#31467c', 'primaryTextColor': '#ffffff', 'primaryBorderColor': '#0c1a29', 'actorBkg': '#31467c', 'actorBorder': '#0c1a29', 'actorTextColor': '#ffffff', 'actorLineColor': '#0c1a29', 'signalColor': '#0c1a29', 'signalTextColor': '#0c1a29', 'labelBoxBkgColor': '#31467c', 'labelBoxBorderColor': '#0c1a29', 'labelTextColor': '#ffffff', 'loopTextColor': '#0c1a29', 'noteBkgColor': '#ffffff', 'noteBorderColor': '#31467c', 'noteTextColor': '#0c1a29'}}}%%
sequenceDiagram
    actor Cardholder
    participant Merchant
    participant LP as Localpayment
    participant Issuer as Card Issuer

    Cardholder->>Merchant: Pay with card
    Merchant->>LP: Create payin
    LP->>Issuer: Request authentication

    alt Frictionless
        Issuer-->>LP: Approved, no challenge
        LP-->>Merchant: Response with final status
    else Challenge (OTP)
        Issuer-->>LP: Challenge required
        LP-->>Merchant: Response with status INPROGRESS and redirectUrl
        Issuer-->>Cardholder: Redirect to challenge page
        Cardholder->>Issuer: Enter OTP
        alt OTP valid
            Issuer-->>LP: Authenticated
            LP->>Merchant: Webhook with final status
        else OTP invalid or expired
            Issuer-->>LP: Authentication failed
            LP->>Merchant: Webhook with status REJECTED
        end
    end

The final status Localpayment sends to the merchant (in the API response or the webhook) depends on the payment's capture flow:

  • AUTHORIZED: for two-step transactions (authorization and capture happen separately).
  • APPROVED: the transaction is confirmed but the funds have not settled yet.
  • COMPLETE: the funds settled in real time.
  • REJECTED: authentication failed or expired, or the transaction was declined for another reason (for example, insufficient funds).

What the Cardholder Sees During the Challenge Flow

ℹ️

The challenge screens below belong to the cardholder's issuing bank and the card network (for example, Visa or Mastercard), not to Localpayment. Exact wording, branding, and layout vary by issuer. The mockups below use fictitious data to illustrate the general pattern.

Step 1 — Choose a verification method

Depending on the card issuer, the challenge flow may let the cardholder choose how to receive the OTP (for example, email or SMS), as shown below. Other issuers skip this choice and send the code through a single, fixed channel.

Step 2 — Enter the verification code

If the cardholder does not complete the challenge or enters an invalid code, the transaction is rejected and they are redirected to redirectUrl.onError, as described in Step 2 below.

Key Actors Involved

Several entities are involved in the 3D Secure process:

  • Cardholder: The person making the transaction with their credit or debit card.
  • Merchant: The online business accepting card payments.
  • Issuer: The financial institution that issued the customer’s card (e.g., a bank).
  • Acquirer: The financial institution that manages the merchant’s transactions (Localpayment).
  • 3D Secure Server (3DSS): A system that facilitates authentication between the merchant, issuer, and payment networks.
  • Access Control Server (ACS): A system managed by the issuer that verifies the cardholder’s identity during authentication.
  • Directory Server: A system managed by the card network (e.g., Visa, Mastercard) that helps route authentication requests to the correct issuer.

Benefits of 3D Secure

Implementing 3D Secure offers multiple benefits for both merchants and customers:

  • Enhanced Security: Reduces the risk of fraudulent transactions by ensuring only the cardholder can authorize payments.
  • Improved Customer Trust: Provides an added layer of protection, giving customers confidence when shopping online.
  • Reduced Fraud Rates: Significantly lowers unauthorized transactions and potential financial losses.

Before You Begin

Ensure you have:


Step 1: 3D Secure Authentication

Send the redirectUrl object when making a One-time payment or a Subscription , including the properties onSuccess and onError. These properties define the URLs where your customer will be redirected upon successful authentication or in case of an error, respectively.

Example Request

Below is an example using curl:

curl --request POST \
  --url https://api.stage.localpayment.com/api/payin/ \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <your_access_token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "paymentMethod": {
        "type": "CreditCard",
        "code": "1600",
        "flow": "DIRECT"
    },
    "externalId": "dffbd2a6-6e65-469b-8bbe-dac269882220",
    "country": "MEX",
    "currency": "MXN",
    "amount": 1000,
    "accountNumber": "{{accountNumber}}",
    "conceptCode": "0001",
    "merchant": {
        "type": "COMPANY",
        "name": "Company",
        "document": {
            "type": "RFC",
            "id": "XXX840510XX1"
        },
        "email": "[email protected]"
    },
    "payer": {
        "type": "INDIVIDUAL",
        "name": "John",
        "lastname": "Doe",
        "document": {
            "type": "RFC",
            "id": "YYY180222YY6"
        },
        "email": "[email protected]"
    },
    "card": {
        "number": "4000000000000002",
        "cvv": "123",
        "expirationMonth": "12",
        "expirationYear": "2029"
    },
    "redirectUrl": {
        "onSuccess": "https://example.com/success/?id={externalId}",
        "onError": "https://example.com/error/?id={externalId}"
    }
}'

Step 2: Handle the Response

Successful Response

If additional authentication is required during the payment process, the API response will include the redirectUrl property. This URL points to a modal or page that should be displayed to the cardholder, enabling them to complete the authentication challenge with their card issuer.

{
  "transactionType": "PayIn",
  "externalId": "dffbd2a6-6e65-469b-8bbe-dac269882220",
  "internalId": "22b29c98-92af-44bd-a164-1863ae2f1bb3",
  "paymentMethod": {
    "type": "CreditCard",
    "code": "1000",
    "flow": "DIRECT"
  },
  "country": "MEX",
  "currency": "MXN",
  "amount": 1000,
  "accountNumber": "{{accountNumber}}",
  "confirmed": {
    "currency": "MXN",
    "amount": 1000,
    "fxQuote": 1,
    "exchangeRateToken": null
  },
  "payment": {
    "installment": null,
    "currency": "MXN",
    "fxQuote": 1,
    "financingFee": 0,
    "amount": 1000
  },
  "localTaxes": [],
  "withHoldings": [],
  "fees": {
    "description": "Fee",
    "currency": "MXN",
    "fxSource": 210.8,
    "fxQuote": 1,
    "amount": 13.02,
    "account": "{{accountNumber}}"
  },
  "status": {
    "code": "103",
    "description": "APPROVED",
    "detail": "The payin was confirmed but not credited yet"
  },
  "ticket": null,
  "qr": null,
  "beneficiary": null,
  "merchant": {
    "type": "COMPANY",
    "name": "Company"
  },
  "payer": {
    "type": "INDIVIDUAL",
    "name": "John",
    "lastname": "Doe",
    "document": {
      "id": "YYY180222YY6",
      "type": "RFC"
    },
    "email": "[email protected]",
    "address": null,
    "birthdate": null,
    "nationality": null
  },
  "intermediaries": [],
  "wireInstructions": null,
  "date": {
    "creationDate": "2024-05-19T19:02:44.018+00:00",
    "processedDate": "2024-05-19T19:02:44.799618",
    "expirationDate": "0001-01-01T00:00:00"
  },
  "card": {
    "bin": "400000",
    "brand": "VISA",
    "country": "RS",
    "name": "John Doe",
    "last4": "0002",
    "expirationYear": 2029,
    "expirationMonth": 12
  },
  "errors": [],
  "redirectUrl": "https://web-checkout.stage.localpayment.com/redirect/aXX0cXX6Ly9ob29xxx5zdHJpcXXuY29tLzNkX3NlY0VyXX0yL0hvc3RlZD9tZXJjaGFudX1hY0N0XzFKdHJmYkw5RVZiU1oySkgmcGF5bWVudF9xxxRlbnQ9cXlfM05weERZTDlFVmXXXjXXXXXXXXXXa2kyJnBheW1lbnRfaW50ZW50X2NsaWVudF9zXXXyZXQ9cGlfM05weERZTDlFVmJTWjXXXXXXXXXXXa2kyX3NlY3JldF9hek5FV1cyQm1BU3RDZHpjRzF0MkVTQ3BuJnB1Ymxpc2hhYmxlX2tleT1wa190ZXN0XzUxSnRyZmJMOUVWYlNaMkpISUF2WjJGREh0aWpwd0JFUWE5SG4xbTA1WHlPS0d3MjlncW1PTGJ6R3hUTm01M0V6VGVBbkk0aTRHWnFpUDliNkJuME5DWDFjMDBrbFNZdmwxQiZzb3VyY2U9cGF5YXR0XzNOcHhXXXw5RVZiU1oySkgxbXX1Q3XrxX"
}

If the transaction requires authentication by the cardholder, it remains in the INPROGRESS status until authentication completes. Depending on the payment's capture flow, a successful authentication moves the transaction to AUTHORIZED (two-step transactions awaiting capture), APPROVED (awaiting settlement), or COMPLETE (funds settled in real time). If authentication fails, expires, or the transaction is declined for another reason (for example, insufficient funds), the status is REJECTED.

Following customer authentication (whether successful or failed), the customer will be redirected to the URL specified in the request based on the outcome. The internalId and externalId properties will be included as query parameters, enabling you to implement necessary logic (e.g., checking the transaction status and displaying a message to the user).


Did this page help you?