The Authorization Sprint – Latency vs. Compute in Card Payment

A practitioner’s notes on financial infrastructure

A coffee shop in Tokyo (Merchant) accepts a Visa card issued by a small credit union in Ohio (Issuer). They share no database, no API contract, and no direct network path. 

The Cardholder taps their card. The POS terminal has exactly 2,000 milliseconds to reach a consensus with the Issuer. If the round-trip exceeds this hard SLA, the POS terminal’s state machine forces a timeout, drops the TCP connection, and prints “Declined.” 

To beat this clock, the transaction is handed off through a chain of specialized systems, each abstracting a layer of complexity. Here is the exact sync flow of an ISO 8583 authorization request.

Step 1: Merchant POS to Payment Gateway (Protocol Translation)

When the Cardholder taps, the POS terminal doesn’t send a JSON payload. If it’s a contactless EMV transaction, it executes the qVSDC (quick Visa Smart Debit/Credit) protocol locally. It generates a cryptogram (a MAC of the transaction data using the card’s chip key) and extracts the Track 2 Equivalent Data. 

If the Cardholder used a mobile wallet (Apple Pay), the terminal receives a Network Token formatted as a DPAN (Device PAN) with a dynamic cryptogram in Data Element (DE) 48 of the ISO message.

The terminal wraps this into a proprietary local protocol or a lightweight REST call and shoots it to the Payment Gateway. The Gateway’s primary function here is protocol translation. It takes this modern payload and constructs a strict, fixed-width ISO 8583:1987 or 1993 message. 

  •  MTI (Message Type Indicator): 0100 (Authorization Request)
  •  DE 2 (PAN): The primary account number (or token).
  •  DE 4 (Amount): 000000000500 ($5.00)
  •  DE 22 (POS Entry Mode): 071 (Contactless EMV)
  •  DE 48 & DE 55: The EMV cryptogram data.

The Gateway terminates the merchant’s TLS connection, establishes a new mutually authenticated TLS session (often using client certificates) with the Acquirer, and pushes the 0100 message.

Step 2: Gateway to Acquirer (The Front-End Processor & Sponsorship)

The Acquirer is a licensed financial institution, but it rarely processes messages directly. It relies on a Front-End Processor (FEP)—a highly available, horizontally scaled message broker. 

When the FEP receives the 0100, it executes a rapid series of local lookups:

  1. Terminal Lookup: Validates the Terminal ID (DE 41) against the Acquirer’s merchant database to ensure the merchant is active and not under a security block.
  2. BIN Routing: It checks DE 2 against a local BIN routing table. It sees the first 8 digits map to the Ohio Credit Union via the Visa network.
  3. Liability Assumption: By attaching its Acquirer ID (DE 32) to the message, the Acquirer legally sponsors this transaction to Visa. If the Merchant is a fraud ring generating fake authorizations, the Acquirer assumes the chargeback liability.

The FEP then routes the message to the Card Network (VisaNet). This connection is usually a persistent, highly redundant TCP/IP session (historically SNA, now VPN over dedicated MPLS circuits).

Step 3: Card Network to Issuer (VisaNet Routing)

Visa operates VISANet, arguably the highest-throughput payment routing engine on earth. It does not evaluate credit risk. It is a deterministic routing engine.

VISANet parses the BIN, looks up the Issuer’s routing destination (specifically, the Settlement Bank ID and the Issuer’s Member ID), and does something crucial: it replaces the Acquirer’s routing DEs with its own internal transaction identifiers. 

  •  It generates a System Trace Audit Number (STAN) to track this exact packet through its internal telemetry.
  •  It maps the transaction to a Retrieval Reference Number (RRN).

VISANet routes the 0100 to the Ohio Credit Union’s designated endpoint and waits for the 0110 (Authorization Response). 

Step 4: The Issuer’s Decision Engine (Latency vs. Compute)

The packet hits the Issuer’s switch (e.g., FIS, Fiserv, or a custom internal core). This is where the heaviest compute in the 2-second window occurs. The switch must deserialize the message and execute a distributed transaction across multiple subsystems:

  1. Account Lookup: The switch hashes the PAN and queries the core banking ledger. SELECT available_credit, card_status, exp_date FROM accounts WHERE pan_hash = X FOR UPDATE; (The row lock prevents race conditions if the user is doing dual-swipes).
  2. Fraud Scoring: The switch publishes an event to a real-time stream (e.g., Kafka) consumed by the fraud engine (like Falcon). The fraud engine runs feature extraction (velocity checks, geolocation distance from last swipe) and returns a score in ~50-100ms.
  3. EMV Validation: The switch forwards the cryptogram to an EMV HSM (Hardware Security Module) to validate that the card actually generated the cryptogram for this specific $5 amount and terminal.

The SLA Trade-off: If the fraud engine takes 400ms, the round trip risks breaching the 2-second SLA. Issuers strictly budget CPU cycles here. If the fraud engine times out, the system often falls back to a deterministic rules engine (e.g., “Amount < $50 AND domestic = Auto Approve”) to prevent a user-facing decline.

If available_credit >= 5.00 and fraud score is low, the core updates the state: available_credit = available_credit – 5.00 (a “memo post” or soft post).

Step 5: The Return Trip & Duplex Mismatch

The Issuer builds the 0110 response:

  •  DE 39 (Response Code): 00 (Approved)
  •  DE 38 (Auth Code): A1B2C3 (Generated by the Issuer for audit tracking)
  •  DE 55: EMV authorization response cryptogram (TC – Transaction Certificate).

This 0110 races back through VISANet, to the Acquirer’s FEP, to the Gateway, and finally to the POS. The POS verifies the TC against the card chip, and the screen turns green.

The Architectural Hazard (Duplex Mismatch): What if VISANet drops the 0110 on the return leg? The Cardholder walks away with coffee, the Issuer has reserved the $5, but the Merchant’s terminal says “Declined – No Response.” 

This is a classic distributed systems split-brain scenario. The Acquirer and Issuer must rely on asynchronous reconciliation (Part 2) to resolve this, because the synchronous window is closed. 

No money has moved. The ledger state is simply: pending_hold = true. The hard part begins now.

Leave a Reply

Your email address will not be published. Required fields are marked *