Project 4: 3D Secure Authentication Flow

Project 4: 3D Secure Authentication Flow

Project Overview

Attribute Value
Difficulty Level 3: Advanced
Time Estimate 2 weeks
Programming Language C / Web (HTML/JS for frontend simulation)
Knowledge Area Payment Protocols / Authentication
Key Technologies 3D Secure 2.0, EMVCo Specs, Digital Signatures
Coolness Level Level 3: Genuinely Clever
Business Potential 3. The โ€œService & Supportโ€ Model

Learning Objectives

By completing this project, you will:

  1. Understand the 3D Secure protocol - Learn how cardholder authentication works for online payments
  2. Implement the three-party model - Build merchant, issuer, and directory server components
  3. Handle challenge and frictionless flows - Implement risk-based authentication decisions
  4. Verify cryptographic assertions - Validate signatures between parties
  5. Manage redirect flows securely - Prevent session hijacking and CSRF
  6. Understand liability shift - Learn how authentication affects fraud liability

The Core Question Youโ€™re Answering

โ€œHow can a bank verify that the person making an online purchase actually owns the card?โ€

Unlike in-store transactions where you physically present the card, online transactions have no way to verify cardholder presence. 3D Secure solves this:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    THE CARD-NOT-PRESENT PROBLEM                          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                          โ”‚
โ”‚  IN-STORE TRANSACTION                  ONLINE TRANSACTION                โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                โ”‚
โ”‚                                                                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                 โ”‚
โ”‚  โ”‚   Customer   โ”‚                      โ”‚   Customer   โ”‚                 โ”‚
โ”‚  โ”‚   with card  โ”‚                      โ”‚   (remote)   โ”‚                 โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                 โ”‚
โ”‚         โ”‚                                     โ”‚                          โ”‚
โ”‚         โ”‚ Presents card                       โ”‚ Types card number        โ”‚
โ”‚         โ”‚ Enters PIN                          โ”‚ ...that's it?           โ”‚
โ”‚         โ”‚ Signs receipt                       โ”‚                          โ”‚
โ”‚         โ–ผ                                     โ–ผ                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                 โ”‚
โ”‚  โ”‚   Terminal   โ”‚                      โ”‚   Website    โ”‚                 โ”‚
โ”‚  โ”‚   verifies:  โ”‚                      โ”‚   has:       โ”‚                 โ”‚
โ”‚  โ”‚   โ€ข Card     โ”‚                      โ”‚   โ€ข PAN      โ”‚                 โ”‚
โ”‚  โ”‚   โ€ข PIN      โ”‚                      โ”‚   โ€ข CVV      โ”‚                 โ”‚
โ”‚  โ”‚   โ€ข Chip     โ”‚                      โ”‚   โ€ข Expiry   โ”‚                 โ”‚
โ”‚  โ”‚   โ€ข Signatureโ”‚                      โ”‚              โ”‚                 โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                 โ”‚
โ”‚                                                                          โ”‚
โ”‚  Authentication: Strong                Authentication: WEAK!             โ”‚
โ”‚  (something you have +                 (something you know +             โ”‚
โ”‚   something you know)                   ...nothing else)                 โ”‚
โ”‚                                                                          โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€   โ”‚
โ”‚                                                                          โ”‚
โ”‚  3D SECURE ADDS:                                                         โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                                                         โ”‚
โ”‚                                                                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”          โ”‚
โ”‚  โ”‚   Customer   โ”‚      โ”‚   Merchant   โ”‚      โ”‚   Issuer     โ”‚          โ”‚
โ”‚  โ”‚              โ”‚โ—„โ”€โ”€โ”€โ”€โ–บโ”‚   (website)  โ”‚โ—„โ”€โ”€โ”€โ”€โ–บโ”‚   (bank)     โ”‚          โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜          โ”‚
โ”‚         โ”‚                                           โ”‚                    โ”‚
โ”‚         โ”‚                                           โ”‚                    โ”‚
โ”‚         โ”‚         Challenge (if needed)             โ”‚                    โ”‚
โ”‚         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚                    โ”‚
โ”‚                   OTP, biometric, app notification  โ”‚                    โ”‚
โ”‚                                                                          โ”‚
โ”‚  Now the ISSUER verifies the cardholder!                                โ”‚
โ”‚                                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Security Model: 3D Secure lets the card-issuing bank authenticate its own customer, rather than trusting the merchant.


Deep Theoretical Foundation

1. The Three Domains

โ€œ3Dโ€ refers to Three Domains:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        THREE DOMAIN MODEL                                โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                          โ”‚
โ”‚  DOMAIN 1: ISSUER DOMAIN                                                 โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                                                 โ”‚
โ”‚  โ€ข Card-issuing bank                                                     โ”‚
โ”‚  โ€ข Access Control Server (ACS)                                          โ”‚
โ”‚  โ€ข Authenticates the cardholder                                          โ”‚
โ”‚  โ€ข Example: Your bank (Chase, BofA, etc.)                               โ”‚
โ”‚                                                                          โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€   โ”‚
โ”‚                                                                          โ”‚
โ”‚  DOMAIN 2: ACQUIRER DOMAIN                                               โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                                               โ”‚
โ”‚  โ€ข Merchant's payment processor                                          โ”‚
โ”‚  โ€ข 3DS Server (MPI - Merchant Plug-In)                                  โ”‚
โ”‚  โ€ข Initiates authentication                                              โ”‚
โ”‚  โ€ข Example: Stripe, Square, Adyen                                        โ”‚
โ”‚                                                                          โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€   โ”‚
โ”‚                                                                          โ”‚
โ”‚  DOMAIN 3: INTEROPERABILITY DOMAIN                                       โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                                       โ”‚
โ”‚  โ€ข Card network infrastructure                                           โ”‚
โ”‚  โ€ข Directory Server (DS)                                                 โ”‚
โ”‚  โ€ข Routes messages between domains                                       โ”‚
โ”‚  โ€ข Example: Visa, Mastercard                                             โ”‚
โ”‚                                                                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚                                                                  โ”‚    โ”‚
โ”‚  โ”‚   ISSUER           INTEROPERABILITY           ACQUIRER          โ”‚    โ”‚
โ”‚  โ”‚   DOMAIN               DOMAIN                 DOMAIN            โ”‚    โ”‚
โ”‚  โ”‚                                                                  โ”‚    โ”‚
โ”‚  โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  ACS  โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚  DS   โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚ 3DS Serverโ”‚         โ”‚    โ”‚
โ”‚  โ”‚   โ”‚       โ”‚         โ”‚       โ”‚            โ”‚   (MPI)   โ”‚         โ”‚    โ”‚
โ”‚  โ”‚   โ””โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”˜         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜            โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜         โ”‚    โ”‚
โ”‚  โ”‚       โ”‚                                        โ”‚               โ”‚    โ”‚
โ”‚  โ”‚       โ”‚         Challenge Flow                 โ”‚               โ”‚    โ”‚
โ”‚  โ”‚       โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚               โ”‚    โ”‚
โ”‚  โ”‚       โ”‚                                        โ”‚               โ”‚    โ”‚
โ”‚  โ”‚   โ”Œโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”                              โ”Œโ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”         โ”‚    โ”‚
โ”‚  โ”‚   โ”‚Issuer โ”‚                              โ”‚ Merchant  โ”‚         โ”‚    โ”‚
โ”‚  โ”‚   โ”‚ Bank  โ”‚                              โ”‚  Website  โ”‚         โ”‚    โ”‚
โ”‚  โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜         โ”‚    โ”‚
โ”‚  โ”‚                                                                  โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

2. 3D Secure 2.0 vs 1.0

3D Secure 1.0 (Deprecated):

  • Every transaction required a redirect
  • Full-page redirect to bankโ€™s authentication page
  • Poor mobile experience
  • High cart abandonment

3D Secure 2.0 (Current):

  • Risk-based authentication
  • Frictionless flow for low-risk transactions
  • Embedded challenge (iframe, not redirect)
  • Mobile SDK support
  • Better data sharing for risk decisions
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    3DS 1.0 vs 3DS 2.0 FLOW                               โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                          โ”‚
โ”‚  3DS 1.0 (old)                         3DS 2.0 (current)                โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                         โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                 โ”‚
โ”‚                                                                          โ”‚
โ”‚  Every transaction:                    Risk assessment first:           โ”‚
โ”‚                                                                          โ”‚
โ”‚  Customer โ†’ Merchant โ†’ Redirect โ†’      Customer โ†’ Merchant โ†’ DS โ†’       โ”‚
โ”‚  Bank Page โ†’ Password โ†’ Redirect โ†’     โ”‚                                โ”‚
โ”‚  Merchant                               โ”œโ”€โ–บ Low risk? Frictionless      โ”‚
โ”‚                                        โ”‚    (no customer action)        โ”‚
โ”‚                                        โ”‚                                โ”‚
โ”‚                                        โ””โ”€โ–บ High risk? Challenge         โ”‚
โ”‚                                             (OTP, biometric, etc.)      โ”‚
โ”‚                                                                          โ”‚
โ”‚  Friction: 100%                        Friction: ~5% (typical)          โ”‚
โ”‚  Abandonment: High                     Abandonment: Low                  โ”‚
โ”‚                                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

3. The Authentication Request (AReq)

The merchant (via 3DS Server) sends rich data to the Directory Server:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    AUTHENTICATION REQUEST (AReq)                         โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                          โ”‚
โ”‚  REQUIRED FIELDS:                                                        โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                                                        โ”‚
โ”‚  โ€ข messageType: "AReq"                                                  โ”‚
โ”‚  โ€ข messageVersion: "2.2.0"                                              โ”‚
โ”‚  โ€ข threeDSServerTransID: unique transaction ID                          โ”‚
โ”‚  โ€ข acctNumber: PAN (encrypted)                                          โ”‚
โ”‚  โ€ข cardExpiryDate: "2512" (YYMM)                                        โ”‚
โ”‚  โ€ข purchaseAmount: "10000" (in minor units)                             โ”‚
โ”‚  โ€ข purchaseCurrency: "840" (USD)                                        โ”‚
โ”‚  โ€ข merchantName: "Example Store"                                        โ”‚
โ”‚  โ€ข deviceChannel: "02" (browser) / "01" (app)                          โ”‚
โ”‚                                                                          โ”‚
โ”‚  RISK ASSESSMENT DATA:                                                   โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                                                   โ”‚
โ”‚  โ€ข browserAcceptHeader: from HTTP request                               โ”‚
โ”‚  โ€ข browserIP: customer's IP address                                      โ”‚
โ”‚  โ€ข browserLanguage: "en-US"                                             โ”‚
โ”‚  โ€ข browserUserAgent: full user agent string                             โ”‚
โ”‚  โ€ข browserJavaEnabled: true/false                                       โ”‚
โ”‚  โ€ข browserColorDepth: "24"                                              โ”‚
โ”‚  โ€ข browserScreenHeight: "1080"                                          โ”‚
โ”‚  โ€ข browserScreenWidth: "1920"                                           โ”‚
โ”‚  โ€ข browserTZ: "-300" (timezone offset)                                  โ”‚
โ”‚                                                                          โ”‚
โ”‚  โ€ข cardholderEmail: "customer@example.com"                              โ”‚
โ”‚  โ€ข cardholderName: "John Doe"                                           โ”‚
โ”‚  โ€ข billAddrLine1, billAddrCity, billAddrPostCode, billAddrCountry       โ”‚
โ”‚  โ€ข shipAddrLine1, shipAddrCity, shipAddrPostCode, shipAddrCountry       โ”‚
โ”‚                                                                          โ”‚
โ”‚  โ€ข threeDSRequestorAuthenticationInd: "01" (payment)                    โ”‚
โ”‚  โ€ข transType: "01" (goods/service purchase)                             โ”‚
โ”‚                                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

4. Risk-Based Authentication

The ACS (issuer) analyzes the AReq data to decide:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    RISK-BASED DECISION MATRIX                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                          โ”‚
โ”‚  SIGNALS FOR FRICTIONLESS (low risk):                                   โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                                    โ”‚
โ”‚  โ€ข Known device (browser fingerprint matches history)                   โ”‚
โ”‚  โ€ข Known IP range (customer's usual location)                           โ”‚
โ”‚  โ€ข Low transaction amount                                                โ”‚
โ”‚  โ€ข Shipping to billing address                                          โ”‚
โ”‚  โ€ข Trusted merchant                                                      โ”‚
โ”‚  โ€ข Recent successful authentication                                      โ”‚
โ”‚                                                                          โ”‚
โ”‚  SIGNALS FOR CHALLENGE (high risk):                                     โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                                      โ”‚
โ”‚  โ€ข New device                                                            โ”‚
โ”‚  โ€ข Unusual location/IP                                                   โ”‚
โ”‚  โ€ข High transaction amount                                               โ”‚
โ”‚  โ€ข Different shipping address                                            โ”‚
โ”‚  โ€ข Unusual purchase time                                                 โ”‚
โ”‚  โ€ข Card recently compromised (data breach)                              โ”‚
โ”‚  โ€ข Multiple failed attempts                                              โ”‚
โ”‚                                                                          โ”‚
โ”‚  DECISION MATRIX:                                                        โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                                                         โ”‚
โ”‚                                                                          โ”‚
โ”‚          Low Amount โ”‚ High Amount                                        โ”‚
โ”‚         โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                                        โ”‚
โ”‚  Known     โ”‚ โœ“ Frictionless โ”‚ ? Maybe Challenge                          โ”‚
โ”‚  Device    โ”‚                โ”‚                                            โ”‚
โ”‚         โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                                        โ”‚
โ”‚  New       โ”‚ ? Maybe       โ”‚ โœ— Challenge Required                        โ”‚
โ”‚  Device    โ”‚   Challenge   โ”‚                                             โ”‚
โ”‚         โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                                        โ”‚
โ”‚                                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

5. Authentication Response (ARes)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    AUTHENTICATION RESPONSE (ARes)                        โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                          โ”‚
โ”‚  FRICTIONLESS APPROVAL:                                                  โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                                                   โ”‚
โ”‚  {                                                                       โ”‚
โ”‚    "messageType": "ARes",                                               โ”‚
โ”‚    "transStatus": "Y",              // Authenticated                    โ”‚
โ”‚    "transStatusReason": null,                                           โ”‚
โ”‚    "eci": "05",                     // Fully authenticated              โ”‚
โ”‚    "authenticationValue": "CAVV...", // Cryptographic proof            โ”‚
โ”‚    "acsTransID": "uuid"                                                 โ”‚
โ”‚  }                                                                       โ”‚
โ”‚                                                                          โ”‚
โ”‚  CHALLENGE REQUIRED:                                                     โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                                                      โ”‚
โ”‚  {                                                                       โ”‚
โ”‚    "messageType": "ARes",                                               โ”‚
โ”‚    "transStatus": "C",              // Challenge required               โ”‚
โ”‚    "acsChallengeMandated": "Y",                                         โ”‚
โ”‚    "acsURL": "https://acs.issuer.com/challenge",                       โ”‚
โ”‚    "acsTransID": "uuid",                                                โ”‚
โ”‚    "authenticationType": "01"        // OTP                             โ”‚
โ”‚  }                                                                       โ”‚
โ”‚                                                                          โ”‚
โ”‚  FAILED/REJECTED:                                                        โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                                                         โ”‚
โ”‚  {                                                                       โ”‚
โ”‚    "messageType": "ARes",                                               โ”‚
โ”‚    "transStatus": "N",              // Not authenticated                โ”‚
โ”‚    "transStatusReason": "01",       // Card not enrolled               โ”‚
โ”‚    "eci": "07"                      // Attempted (no liability shift)  โ”‚
โ”‚  }                                                                       โ”‚
โ”‚                                                                          โ”‚
โ”‚  TRANSACTION STATUS VALUES:                                              โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                                              โ”‚
โ”‚  Y = Authenticated                                                       โ”‚
โ”‚  N = Not authenticated / Authentication failed                          โ”‚
โ”‚  U = Authentication could not be performed                              โ”‚
โ”‚  A = Attempted (ACS not available)                                      โ”‚
โ”‚  C = Challenge required                                                  โ”‚
โ”‚  R = Rejected by issuer                                                 โ”‚
โ”‚                                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

6. ECI (E-Commerce Indicator) Values

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                           ECI VALUES                                     โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                          โ”‚
โ”‚  VISA:                                MASTERCARD:                       โ”‚
โ”‚  โ€ข 05: Fully authenticated            โ€ข 02: Fully authenticated         โ”‚
โ”‚  โ€ข 06: Attempted authentication       โ€ข 01: Attempted authentication    โ”‚
โ”‚  โ€ข 07: No authentication              โ€ข 00: No authentication           โ”‚
โ”‚                                                                          โ”‚
โ”‚  LIABILITY SHIFT:                                                        โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                                                        โ”‚
โ”‚                                                                          โ”‚
โ”‚  ECI 05/02 (Authenticated):                                             โ”‚
โ”‚  โ€ข Liability shifts to ISSUER                                           โ”‚
โ”‚  โ€ข Merchant protected from chargebacks (fraud)                          โ”‚
โ”‚  โ€ข Best outcome for merchant                                             โ”‚
โ”‚                                                                          โ”‚
โ”‚  ECI 06/01 (Attempted):                                                 โ”‚
โ”‚  โ€ข Partial liability shift in some cases                                โ”‚
โ”‚  โ€ข Card enrolled but ACS unavailable                                    โ”‚
โ”‚                                                                          โ”‚
โ”‚  ECI 07/00 (No Authentication):                                         โ”‚
โ”‚  โ€ข No liability shift                                                    โ”‚
โ”‚  โ€ข Merchant bears fraud risk                                             โ”‚
โ”‚  โ€ข Card not enrolled or merchant opted out                              โ”‚
โ”‚                                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

7. The Challenge Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        CHALLENGE FLOW                                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”‚
โ”‚  โ”‚ Customer โ”‚     โ”‚ Merchant โ”‚     โ”‚    DS    โ”‚     โ”‚   ACS    โ”‚       โ”‚
โ”‚  โ”‚ Browser  โ”‚     โ”‚   3DS    โ”‚     โ”‚          โ”‚     โ”‚ (Issuer) โ”‚       โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜       โ”‚
โ”‚       โ”‚                โ”‚                โ”‚                โ”‚              โ”‚
โ”‚       โ”‚    Checkout    โ”‚                โ”‚                โ”‚              โ”‚
โ”‚       โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚                โ”‚                โ”‚              โ”‚
โ”‚       โ”‚                โ”‚     AReq       โ”‚                โ”‚              โ”‚
โ”‚       โ”‚                โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚                โ”‚              โ”‚
โ”‚       โ”‚                โ”‚                โ”‚     AReq       โ”‚              โ”‚
โ”‚       โ”‚                โ”‚                โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚              โ”‚
โ”‚       โ”‚                โ”‚                โ”‚                โ”‚              โ”‚
โ”‚       โ”‚                โ”‚                โ”‚     ARes       โ”‚              โ”‚
โ”‚       โ”‚                โ”‚                โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚              โ”‚
โ”‚       โ”‚                โ”‚     ARes       โ”‚    (C=Challenge)              โ”‚
โ”‚       โ”‚                โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚                โ”‚              โ”‚
โ”‚       โ”‚                โ”‚                โ”‚                โ”‚              โ”‚
โ”‚       โ”‚   Challenge    โ”‚                โ”‚                โ”‚              โ”‚
โ”‚       โ”‚   (iframe)     โ”‚                โ”‚                โ”‚              โ”‚
โ”‚       โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚                โ”‚                โ”‚              โ”‚
โ”‚       โ”‚                โ”‚                โ”‚                โ”‚              โ”‚
โ”‚       โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ              โ”‚
โ”‚       โ”‚                        CReq (challenge request)  โ”‚              โ”‚
โ”‚       โ”‚                                                  โ”‚              โ”‚
โ”‚       โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€              โ”‚
โ”‚       โ”‚                        Challenge UI (OTP form)   โ”‚              โ”‚
โ”‚       โ”‚                                                  โ”‚              โ”‚
โ”‚       โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ              โ”‚
โ”‚       โ”‚                        CRes (OTP entered)        โ”‚              โ”‚
โ”‚       โ”‚                                                  โ”‚              โ”‚
โ”‚       โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€              โ”‚
โ”‚       โ”‚                        RReq (result)             โ”‚              โ”‚
โ”‚       โ”‚                โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚              โ”‚
โ”‚       โ”‚                โ”‚                โ”‚                โ”‚              โ”‚
โ”‚       โ”‚    Result      โ”‚                โ”‚                โ”‚              โ”‚
โ”‚       โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚                โ”‚                โ”‚              โ”‚
โ”‚       โ”‚                โ”‚                โ”‚                โ”‚              โ”‚
โ”‚                                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Project Specification

What Youโ€™ll Build

A working 3D Secure 2.0 simulation including:

  1. Merchant 3DS Server: Initiates authentication
  2. Directory Server (Mock): Routes between merchant and issuer
  3. Access Control Server (Mock): Makes authentication decisions
  4. Checkout Page: Demonstrates the customer experience
  5. Challenge Interface: OTP/password challenge flow

Expected Output

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘                    3D SECURE DEMO CHECKOUT                             โ•‘
โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ
โ•‘                                                                        โ•‘
โ•‘  Purchase Details                                                      โ•‘
โ•‘  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                                                       โ•‘
โ•‘  Item: "Wireless Headphones"                                          โ•‘
โ•‘  Amount: $149.99                                                       โ•‘
โ•‘  Merchant: Demo Store                                                  โ•‘
โ•‘                                                                        โ•‘
โ•‘  Card Information                                                      โ•‘
โ•‘  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                                                       โ•‘
โ•‘  Card Number: 4111111111111111                                        โ•‘
โ•‘  Expiry: 12/25                                                         โ•‘
โ•‘  CVV: 123                                                              โ•‘
โ•‘  Name: John Doe                                                        โ•‘
โ•‘                                                                        โ•‘
โ•‘  [PAY NOW]                                                             โ•‘
โ•‘                                                                        โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

[User clicks PAY NOW]

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘                    3DS AUTHENTICATION IN PROGRESS                      โ•‘
โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ
โ•‘                                                                        โ•‘
โ•‘  [3DS Server] Collecting browser data...                              โ•‘
โ•‘  [3DS Server] Browser: Chrome 121.0.0.0                               โ•‘
โ•‘  [3DS Server] IP: 192.168.1.100                                       โ•‘
โ•‘  [3DS Server] Screen: 1920x1080                                       โ•‘
โ•‘                                                                        โ•‘
โ•‘  [3DS Server] Sending AReq to Directory Server...                     โ•‘
โ•‘  {                                                                     โ•‘
โ•‘    "messageType": "AReq",                                             โ•‘
โ•‘    "acctNumber": "4111111111111111",                                  โ•‘
โ•‘    "purchaseAmount": "14999",                                         โ•‘
โ•‘    "browserIP": "192.168.1.100"                                       โ•‘
โ•‘  }                                                                     โ•‘
โ•‘                                                                        โ•‘
โ•‘  [DS] Received AReq, routing to ACS for BIN 411111...                 โ•‘
โ•‘                                                                        โ•‘
โ•‘  [ACS] Risk Assessment:                                                โ•‘
โ•‘        โ€ข Known device: NO                                              โ•‘
โ•‘        โ€ข Known IP: NO                                                  โ•‘
โ•‘        โ€ข Amount: $149.99 (MEDIUM)                                     โ•‘
โ•‘        โ€ข Risk Score: 72/100                                           โ•‘
โ•‘        โ€ข Decision: CHALLENGE REQUIRED                                 โ•‘
โ•‘                                                                        โ•‘
โ•‘  [ACS] Sending ARes with transStatus="C"                              โ•‘
โ•‘                                                                        โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘                    CHALLENGE: Verify Your Identity                     โ•‘
โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ
โ•‘                                                                        โ•‘
โ•‘  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ•‘
โ•‘  โ”‚                                                                  โ”‚  โ•‘
โ•‘  โ”‚   ๐Ÿฆ Your Bank                                                   โ”‚  โ•‘
โ•‘  โ”‚                                                                  โ”‚  โ•‘
โ•‘  โ”‚   To verify this purchase, we've sent a one-time                โ”‚  โ•‘
โ•‘  โ”‚   password to your registered phone ending in **89              โ”‚  โ•‘
โ•‘  โ”‚                                                                  โ”‚  โ•‘
โ•‘  โ”‚   Purchase: $149.99 at Demo Store                               โ”‚  โ•‘
โ•‘  โ”‚                                                                  โ”‚  โ•‘
โ•‘  โ”‚   Enter OTP: [______]                                           โ”‚  โ•‘
โ•‘  โ”‚                                                                  โ”‚  โ•‘
โ•‘  โ”‚   [VERIFY]   [Cancel]                                           โ”‚  โ•‘
โ•‘  โ”‚                                                                  โ”‚  โ•‘
โ•‘  โ”‚   Didn't receive code? Resend                                   โ”‚  โ•‘
โ•‘  โ”‚                                                                  โ”‚  โ•‘
โ•‘  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ•‘
โ•‘                                                                        โ•‘
โ•‘  (This iframe is served by the issuer's ACS)                          โ•‘
โ•‘                                                                        โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

[User enters correct OTP: 123456]

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘                    AUTHENTICATION COMPLETE                             โ•‘
โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ
โ•‘                                                                        โ•‘
โ•‘  [ACS] OTP verified successfully                                      โ•‘
โ•‘  [ACS] Generating authentication value (CAVV)...                      โ•‘
โ•‘  [ACS] Sending RReq to 3DS Server                                     โ•‘
โ•‘                                                                        โ•‘
โ•‘  Authentication Result:                                                โ•‘
โ•‘  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                                                 โ•‘
โ•‘  Status: Y (AUTHENTICATED)                                            โ•‘
โ•‘  ECI: 05 (Visa fully authenticated)                                   โ•‘
โ•‘  CAVV: AAABBJlHYWUZ... (base64)                                       โ•‘
โ•‘                                                                        โ•‘
โ•‘  LIABILITY SHIFT: โœ“ Issuer accepts fraud liability                    โ•‘
โ•‘                                                                        โ•‘
โ•‘  [3DS Server] Authentication successful                                โ•‘
โ•‘  [3DS Server] Proceeding with authorization...                        โ•‘
โ•‘                                                                        โ•‘
โ•‘  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•  โ•‘
โ•‘                                                                        โ•‘
โ•‘                    โœ“ PAYMENT APPROVED                                  โ•‘
โ•‘                                                                        โ•‘
โ•‘  Authorization Code: A12345                                            โ•‘
โ•‘  Transaction ID: TXN-987654321                                        โ•‘
โ•‘                                                                        โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Project Structure

3ds_simulator/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ main.c                      # CLI/server entry
โ”‚   โ”œโ”€โ”€ merchant/
โ”‚   โ”‚   โ”œโ”€โ”€ checkout.c              # Checkout page handler
โ”‚   โ”‚   โ”œโ”€โ”€ threeds_server.c        # 3DS Server (MPI)
โ”‚   โ”‚   โ””โ”€โ”€ browser_data.c          # Browser fingerprinting
โ”‚   โ”œโ”€โ”€ directory_server/
โ”‚   โ”‚   โ”œโ”€โ”€ ds.c                    # Directory Server
โ”‚   โ”‚   โ”œโ”€โ”€ routing.c               # BIN to ACS routing
โ”‚   โ”‚   โ””โ”€โ”€ message_validation.c    # Schema validation
โ”‚   โ”œโ”€โ”€ acs/
โ”‚   โ”‚   โ”œโ”€โ”€ acs.c                   # Access Control Server
โ”‚   โ”‚   โ”œโ”€โ”€ risk_engine.c           # Risk-based decision
โ”‚   โ”‚   โ”œโ”€โ”€ challenge.c             # Challenge flow
โ”‚   โ”‚   โ””โ”€โ”€ otp.c                   # OTP generation/validation
โ”‚   โ”œโ”€โ”€ protocol/
โ”‚   โ”‚   โ”œโ”€โ”€ areq.c                  # AReq message
โ”‚   โ”‚   โ”œโ”€โ”€ ares.c                  # ARes message
โ”‚   โ”‚   โ”œโ”€โ”€ creq.c                  # CReq message
โ”‚   โ”‚   โ”œโ”€โ”€ cres.c                  # CRes message
โ”‚   โ”‚   โ””โ”€โ”€ rreq.c                  # RReq message
โ”‚   โ”œโ”€โ”€ crypto/
โ”‚   โ”‚   โ”œโ”€โ”€ signatures.c            # Message signatures
โ”‚   โ”‚   โ””โ”€โ”€ cavv.c                  # CAVV generation
โ”‚   โ””โ”€โ”€ web/
โ”‚       โ”œโ”€โ”€ http_server.c           # Basic HTTP server
โ”‚       โ””โ”€โ”€ json.c                  # JSON parsing
โ”œโ”€โ”€ static/
โ”‚   โ”œโ”€โ”€ checkout.html               # Checkout page
โ”‚   โ”œโ”€โ”€ challenge.html              # Challenge iframe
โ”‚   โ””โ”€โ”€ style.css
โ”œโ”€โ”€ tests/
โ”‚   โ”œโ”€โ”€ test_areq.c
โ”‚   โ”œโ”€โ”€ test_risk_engine.c
โ”‚   โ””โ”€โ”€ test_challenge.c
โ”œโ”€โ”€ Makefile
โ””โ”€โ”€ README.md

Core API Design

// threeds_server.h
typedef struct {
    char trans_id[37];                // UUID
    char merchant_id[32];
    char merchant_name[64];
    int purchase_amount;              // In minor units (cents)
    char purchase_currency[4];        // ISO currency code
} TransactionInfo;

typedef struct {
    char acct_number[20];
    char card_expiry[5];              // YYMM
    char cardholder_name[64];
} CardInfo;

typedef struct {
    char user_agent[256];
    char accept_header[128];
    char ip_address[46];
    char language[8];
    int screen_width;
    int screen_height;
    int color_depth;
    int timezone_offset;
    bool java_enabled;
    bool javascript_enabled;
} BrowserInfo;

// Build and send AReq
typedef struct {
    char trans_status;                // Y, N, C, U, A, R
    char eci[3];                      // 05, 06, 07
    char cavv[64];                    // Base64 encoded
    char acs_url[256];                // For challenge
    char acs_trans_id[37];
    bool challenge_required;
} AResResult;

AResResult initiate_authentication(
    const TransactionInfo* trans,
    const CardInfo* card,
    const BrowserInfo* browser
);

// acs.h
typedef struct {
    int risk_score;                   // 0-100
    char decision;                    // Y (frictionless), C (challenge), N (deny)
    char reason[64];
} RiskDecision;

RiskDecision assess_risk(
    const char* pan,
    int amount,
    const BrowserInfo* browser,
    const char* merchant_id
);

typedef struct {
    char otp[7];                      // 6 digits
    time_t expires_at;
    char trans_id[37];
} Challenge;

Challenge generate_challenge(const char* trans_id, const char* phone_last4);
bool verify_challenge(const char* trans_id, const char* otp_entered);

Solution Architecture

System Design

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    3DS SIMULATOR ARCHITECTURE                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                          โ”‚
โ”‚  BROWSER                                                                 โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•                                                                 โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚                    checkout.html                                 โ”‚    โ”‚
โ”‚  โ”‚                                                                  โ”‚    โ”‚
โ”‚  โ”‚   โ€ข Card form                                                    โ”‚    โ”‚
โ”‚  โ”‚   โ€ข Browser data collection (JS)                                 โ”‚    โ”‚
โ”‚  โ”‚   โ€ข 3DS Method iframe (device fingerprinting)                   โ”‚    โ”‚
โ”‚  โ”‚   โ€ข Challenge iframe container                                   โ”‚    โ”‚
โ”‚  โ”‚                                                                  โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                             โ”‚                                            โ”‚
โ”‚                             โ”‚ POST /initiate-3ds                        โ”‚
โ”‚                             โ”‚ {card, browser_data, transaction}          โ”‚
โ”‚                             โ–ผ                                            โ”‚
โ”‚  MERCHANT SERVER (3DS Server)                                            โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                                            โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚                    threeds_server.c                              โ”‚    โ”‚
โ”‚  โ”‚                                                                  โ”‚    โ”‚
โ”‚  โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”              โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  Build AReq        โ”‚   โ”‚  Parse ARes        โ”‚              โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  (protocol/areq.c) โ”‚   โ”‚  (protocol/ares.c) โ”‚              โ”‚    โ”‚
โ”‚  โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜              โ”‚    โ”‚
โ”‚  โ”‚             โ”‚                         โ”‚                         โ”‚    โ”‚
โ”‚  โ”‚             โ”‚ AReq JSON               โ”‚ ARes JSON               โ”‚    โ”‚
โ”‚  โ”‚             โ”‚                         โ”‚                         โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                โ”‚                         โ”‚                              โ”‚
โ”‚                โ–ผ                         โ”‚                              โ”‚
โ”‚  DIRECTORY SERVER                       โ”‚                              โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•                       โ”‚                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚                    ds.c                                          โ”‚    โ”‚
โ”‚  โ”‚                                                                  โ”‚    โ”‚
โ”‚  โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”              โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  Validate Message  โ”‚   โ”‚  Route by BIN      โ”‚              โ”‚    โ”‚
โ”‚  โ”‚   โ”‚                    โ”‚   โ”‚  (BIN โ†’ ACS URL)   โ”‚              โ”‚    โ”‚
โ”‚  โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜              โ”‚    โ”‚
โ”‚  โ”‚             โ”‚                         โ”‚                         โ”‚    โ”‚
โ”‚  โ”‚             โ”‚ AReq                    โ”‚ ARes                    โ”‚    โ”‚
โ”‚  โ”‚             โ–ผ                         โ”‚                         โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                โ”‚                         โ”‚                              โ”‚
โ”‚                โ–ผ                         โ”‚                              โ”‚
โ”‚  ACCESS CONTROL SERVER (ACS)            โ”‚                              โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•            โ”‚                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚                    acs.c                                         โ”‚    โ”‚
โ”‚  โ”‚                                                                  โ”‚    โ”‚
โ”‚  โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”              โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  Risk Engine       โ”‚   โ”‚  Challenge Logic   โ”‚              โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  (risk_engine.c)   โ”‚   โ”‚  (challenge.c)     โ”‚              โ”‚    โ”‚
โ”‚  โ”‚   โ”‚                    โ”‚   โ”‚                    โ”‚              โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  โ€ข Device history  โ”‚   โ”‚  โ€ข OTP generation  โ”‚              โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  โ€ข Amount analysis โ”‚   โ”‚  โ€ข OTP validation  โ”‚              โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  โ€ข Behavioral      โ”‚   โ”‚  โ€ข Timeout         โ”‚              โ”‚    โ”‚
โ”‚  โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜              โ”‚    โ”‚
โ”‚  โ”‚             โ”‚                         โ”‚                         โ”‚    โ”‚
โ”‚  โ”‚             โ–ผ                         โ”‚                         โ”‚    โ”‚
โ”‚  โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  Decision:                                              โ”‚   โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  โ€ข Frictionless (transStatus=Y) โ†’ Return ARes          โ”‚   โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  โ€ข Challenge (transStatus=C) โ†’ Serve challenge UI      โ”‚   โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  โ€ข Deny (transStatus=N) โ†’ Return ARes with reason      โ”‚   โ”‚    โ”‚
โ”‚  โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚    โ”‚
โ”‚  โ”‚                                                                  โ”‚    โ”‚
โ”‚  โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  CAVV Generation (crypto/cavv.c)                        โ”‚   โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  โ€ข Sign authentication result                          โ”‚   โ”‚    โ”‚
โ”‚  โ”‚   โ”‚  โ€ข Include transaction details                          โ”‚   โ”‚    โ”‚
โ”‚  โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚    โ”‚
โ”‚  โ”‚                                                                  โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Risk Engine Design

// risk_engine.c

typedef struct {
    // Device fingerprint
    char device_id[64];           // Hash of browser characteristics

    // History
    int previous_purchases;       // From this device
    int failed_attempts;          // Recent failures
    time_t last_purchase;

    // Current transaction
    int amount;
    bool shipping_matches_billing;
    char merchant_category[8];    // MCC code
} RiskFactors;

#define RISK_WEIGHT_DEVICE_NEW      25
#define RISK_WEIGHT_IP_NEW          15
#define RISK_WEIGHT_HIGH_AMOUNT     20
#define RISK_WEIGHT_DIFFERENT_SHIP  10
#define RISK_WEIGHT_ODD_TIME        5
#define RISK_WEIGHT_FAILED_RECENT   15
#define RISK_WEIGHT_SUSPICIOUS_MCC  10

int calculate_risk_score(const RiskFactors* factors) {
    int score = 0;

    // New device
    if (factors->previous_purchases == 0) {
        score += RISK_WEIGHT_DEVICE_NEW;
    }

    // High amount (threshold varies by merchant)
    if (factors->amount > 10000) {  // $100 in cents
        score += RISK_WEIGHT_HIGH_AMOUNT;
    }

    // Different shipping
    if (!factors->shipping_matches_billing) {
        score += RISK_WEIGHT_DIFFERENT_SHIP;
    }

    // Recent failures
    if (factors->failed_attempts > 0) {
        score += RISK_WEIGHT_FAILED_RECENT * factors->failed_attempts;
    }

    return score > 100 ? 100 : score;
}

RiskDecision assess_risk(/*...*/) {
    RiskFactors factors = gather_factors(/*...*/);
    int score = calculate_risk_score(&factors);

    RiskDecision decision;
    decision.risk_score = score;

    if (score < 30) {
        decision.decision = 'Y';  // Frictionless
        strcpy(decision.reason, "Low risk transaction");
    } else if (score < 70) {
        decision.decision = 'C';  // Challenge
        strcpy(decision.reason, "Moderate risk - verification needed");
    } else {
        decision.decision = 'N';  // Deny
        strcpy(decision.reason, "High risk - declined");
    }

    return decision;
}

Implementation Guide

Phase 1: Protocol Messages

Goal: Implement AReq/ARes message structures.

// areq.c
#include <json.h>

typedef struct {
    char message_type[8];           // "AReq"
    char message_version[8];        // "2.2.0"
    char three_ds_server_trans_id[37];
    char acct_number[20];
    char card_expiry_date[5];
    char purchase_amount[16];
    char purchase_currency[4];
    char merchant_name[64];
    char device_channel[3];
    // Browser info
    char browser_accept_header[256];
    char browser_ip[46];
    char browser_language[8];
    char browser_user_agent[512];
    // ... many more fields
} AReq;

char* areq_to_json(const AReq* areq) {
    json_t* root = json_object();

    json_object_set_new(root, "messageType",
                        json_string(areq->message_type));
    json_object_set_new(root, "messageVersion",
                        json_string(areq->message_version));
    // ... all fields

    char* json_str = json_dumps(root, JSON_COMPACT);
    json_decref(root);
    return json_str;
}

Phase 2: Basic Server

Goal: HTTP server to handle checkout flow.

// Using mongoose or libmicrohttpd

void handle_initiate_3ds(Request* req, Response* res) {
    // Parse card, browser data, transaction from request
    CardInfo card;
    BrowserInfo browser;
    TransactionInfo trans;
    parse_checkout_request(req->body, &card, &browser, &trans);

    // Build AReq
    AReq areq = build_areq(&card, &browser, &trans);

    // Send to DS (in production, over TLS mutual auth)
    AResResult ares = send_areq_to_ds(&areq);

    if (ares.challenge_required) {
        // Return challenge URL to browser
        json_response(res, 200, "{\"challenge\": true, \"acsUrl\": \"%s\"}",
                     ares.acs_url);
    } else if (ares.trans_status == 'Y') {
        // Proceed with authorization
        AuthResult auth = authorize_transaction(&trans, ares.cavv, ares.eci);
        json_response(res, 200, "{\"success\": true, \"authCode\": \"%s\"}",
                     auth.auth_code);
    } else {
        json_response(res, 200, "{\"success\": false, \"reason\": \"%s\"}",
                     ares.reason);
    }
}

Phase 3: Directory Server Routing

Goal: Route AReq to correct ACS by BIN.

// routing.c

typedef struct {
    char bin_start[9];
    char bin_end[9];
    char acs_url[256];
    char acs_id[32];
} BinRoute;

static BinRoute routes[] = {
    {"40000000", "49999999", "http://localhost:8082/acs", "VISA_ACS_001"},
    {"51000000", "55999999", "http://localhost:8083/acs", "MC_ACS_001"},
    {"34000000", "34999999", "http://localhost:8084/acs", "AMEX_ACS_001"},
    // ...
};

const char* route_to_acs(const char* pan) {
    char bin[9];
    strncpy(bin, pan, 8);
    bin[8] = '\0';

    for (int i = 0; i < sizeof(routes)/sizeof(routes[0]); i++) {
        if (strcmp(bin, routes[i].bin_start) >= 0 &&
            strcmp(bin, routes[i].bin_end) <= 0) {
            return routes[i].acs_url;
        }
    }
    return NULL;  // Card not enrolled
}

Phase 4: ACS Risk Engine

Goal: Make frictionless vs challenge decisions.

See Risk Engine Design section above.

Phase 5: Challenge Flow

Goal: Implement OTP challenge.

// challenge.c

// In-memory challenge store (use Redis in production)
static Challenge active_challenges[1000];
static int challenge_count = 0;

Challenge generate_challenge(const char* trans_id, const char* phone_last4) {
    Challenge c;
    strncpy(c.trans_id, trans_id, 36);
    c.trans_id[36] = '\0';

    // Generate 6-digit OTP
    unsigned int seed;
    RAND_bytes((unsigned char*)&seed, sizeof(seed));
    snprintf(c.otp, 7, "%06d", seed % 1000000);

    c.expires_at = time(NULL) + 300;  // 5 minutes

    // Store
    active_challenges[challenge_count++] = c;

    // In production: actually send SMS via Twilio, etc.
    printf("[ACS] Sending OTP %s to phone ending in %s\n", c.otp, phone_last4);

    return c;
}

bool verify_challenge(const char* trans_id, const char* otp_entered) {
    for (int i = 0; i < challenge_count; i++) {
        if (strcmp(active_challenges[i].trans_id, trans_id) == 0) {
            if (time(NULL) > active_challenges[i].expires_at) {
                return false;  // Expired
            }
            return strcmp(active_challenges[i].otp, otp_entered) == 0;
        }
    }
    return false;  // Not found
}

Phase 6: CAVV Generation

Goal: Generate cryptographic authentication value.

// cavv.c

// CAVV structure (simplified - real CAVV is more complex)
typedef struct {
    char algorithm;          // 0 = HMAC, 1 = CVN etc.
    char version;            // Protocol version
    char key_indicator[2];   // Which key was used
    char auth_result;        // Y/A/N etc.
    char trans_id[4];        // Abbreviated trans ID
    char mac[20];            // HMAC of above
} CAVV;

char* generate_cavv(const char* trans_id, char auth_result,
                    const unsigned char* key) {
    CAVV cavv;
    cavv.algorithm = 0;
    cavv.version = 2;
    cavv.auth_result = auth_result;

    // Copy first 4 bytes of trans ID
    memcpy(cavv.trans_id, trans_id, 4);

    // Generate HMAC
    unsigned char to_mac[8];
    to_mac[0] = cavv.algorithm;
    to_mac[1] = cavv.version;
    to_mac[2] = cavv.auth_result;
    memcpy(to_mac + 3, cavv.trans_id, 4);

    HMAC(EVP_sha1(), key, 16, to_mac, 7, cavv.mac, NULL);

    // Base64 encode entire structure
    char* b64 = base64_encode((unsigned char*)&cavv, sizeof(cavv));
    return b64;
}

Testing Strategy

Protocol Compliance Tests

void test_areq_required_fields() {
    AReq areq = {0};
    // Missing required field
    char* json = areq_to_json(&areq);

    // Should fail validation
    assert(validate_areq(json) == false);

    // Add required fields
    strcpy(areq.message_type, "AReq");
    strcpy(areq.message_version, "2.2.0");
    // ... add all required

    json = areq_to_json(&areq);
    assert(validate_areq(json) == true);
}

Risk Engine Tests

void test_low_risk_frictionless() {
    RiskFactors factors = {
        .previous_purchases = 10,
        .failed_attempts = 0,
        .amount = 1000,  // $10
        .shipping_matches_billing = true
    };

    int score = calculate_risk_score(&factors);
    assert(score < 30);  // Should be frictionless
}

void test_high_risk_challenge() {
    RiskFactors factors = {
        .previous_purchases = 0,  // New device
        .failed_attempts = 2,
        .amount = 50000,  // $500
        .shipping_matches_billing = false
    };

    int score = calculate_risk_score(&factors);
    assert(score >= 30);  // Should require challenge
}

End-to-End Flow Tests

#!/bin/bash
# test_3ds_flow.sh

# Start all servers
./ds_server &
./acs_server &
./merchant_server &
sleep 2

# Test frictionless flow (low amount, known device)
RESPONSE=$(curl -s -X POST http://localhost:8080/initiate-3ds \
  -H "Content-Type: application/json" \
  -d '{
    "pan": "4111111111111111",
    "amount": 1000,
    "browserInfo": {...}
  }')

assert_contains "$RESPONSE" '"transStatus":"Y"'

# Test challenge flow (high amount)
RESPONSE=$(curl -s -X POST http://localhost:8080/initiate-3ds \
  -H "Content-Type: application/json" \
  -d '{
    "pan": "4111111111111111",
    "amount": 100000,
    "browserInfo": {...}
  }')

assert_contains "$RESPONSE" '"challenge":true'

Common Pitfalls & Debugging

Pitfall 1: Incorrect Version Handling

Symptom: DS rejects messages.

Cause: Protocol version mismatch between components.

Fix: Ensure all components use same messageVersion.

Pitfall 2: CAVV Validation Failure

Symptom: Authorization fails despite successful authentication.

Cause: CAVV format doesnโ€™t match network expectations.

Fix: Follow EMVCo specification exactly for CAVV structure.

Pitfall 3: Challenge Iframe Issues

Symptom: Challenge doesnโ€™t display.

Cause: CSP blocking iframe, or cross-origin issues.

Fix: Set proper headers: X-Frame-Options: ALLOW-FROM merchant.com.


Extensions & Challenges

Extension 1: Device Fingerprinting

Implement 3DS Method for device fingerprinting before authentication.

Extension 2: SCA Exemptions

Implement Strong Customer Authentication exemptions (low value, recurring, etc.)

Extension 3: Decoupled Authentication

Implement app-based push notification authentication.

Extension 4: Real Card Network Integration

Integrate with Visa/Mastercard test environments.


Resources

Specifications

  • EMVCo 3D Secure 2.x Specification (free from emvco.com)
  • EMVCo 3D Secure SDK Specification
  • PCI 3DS Core Security Standard

Books

Topic Book
Digital Signatures Serious Cryptography Ch. 13
Web Security Bug Bounty Bootcamp by Vickie Li
Risk-Based Auth Security in Computing by Pfleeger

Self-Assessment Checklist

  • AReq/ARes messages comply with EMVCo spec
  • Risk engine makes reasonable decisions
  • Challenge flow works end-to-end
  • CAVV is generated correctly
  • Frictionless flow works for low-risk transactions
  • Can explain liability shift
  • Understand the three-domain model
  • Iframe security is properly handled

Whatโ€™s Next?

You now understand e-commerce authentication. Move to Project 5: Mini Payment Gateway to build a system that ties together tokenization, P2PE, and 3DS with PCI-compliant architecture.