Module 1: ISO8583 Foundations

Slides & Visual Reference

1 / 24

Slide 0: Message Framing (Before ISO8583)

What you receive on the wire:

┌─────────────┬──────────────┬────────────────────────────────────┐
│   Length    │    TPDU      │         ISO8583 Message            │
│  (2 bytes)  │  (optional)  │                                    │
│   00 C8     │  60 00 00... │  30 31 30 30 72 3A ...             │
└─────────────┴──────────────┴────────────────────────────────────┘
      ↑              ↑                    ↑
   200 bytes    Transport         The actual message
                 header           (MTI + bitmap + fields)

Critical: Your parser must handle framing BEFORE parsing ISO8583!

Common length header formats:

  • Binary 2-byte: 00 C8 = 200 bytes (big-endian)
  • ASCII 4-char: 30 32 30 30 = "0200"
  • BCD 2-byte: 02 00 = 200 bytes
2 / 24

Slide 1: What is ISO8583?

The "JSON" of payment systems since 1987

┌─────────────────────────────────────────────────────────┐
│  A standardized message format for card-originated      │
│  financial transactions                                 │
├─────────────────────────────────────────────────────────┤
│  ✓ Common language between banks                        │
│  ✓ Compact binary encoding                              │
│  ✓ Used by Visa, Mastercard, ATM networks              │
│  ✓ Still dominant 35+ years later                       │
└─────────────────────────────────────────────────────────┘

What it defines: Message types, field formats, encoding rules What it doesn't: Transport, encryption, business logic

3 / 24

Slide 2: Message Structure Overview

┌────────────────────────────────────────────────────────────────────┐
│                      ISO8583 MESSAGE                               │
├──────────┬─────────────────────┬───────────────────────────────────┤
│   MTI    │      BITMAP(S)      │         DATA ELEMENTS             │
│ 4 bytes  │     8-24 bytes      │         variable length           │
├──────────┼─────────────────────┼───────────────────────────────────┤
│  "What   │  "Which fields      │  "The actual                      │
│   is     │   are present?"     │   payload"                        │
│  this?"  │                     │                                   │
└──────────┴─────────────────────┴───────────────────────────────────┘

Always this order. Always these three parts.

4 / 24

Slide 3: The MTI Decoded

        0         1         0         0
        │         │         │         │
        ▼         ▼         ▼         ▼
    ┌───────┬─────────┬──────────┬────────┐
    │VERSION│  CLASS  │ FUNCTION │ ORIGIN │
    └───────┴─────────┴──────────┴────────┘
        │         │         │         │
        │         │         │         └─► 0=Acquirer, 1=Repeat, 2=Issuer
        │         │         └─► 0=Request, 1=Response, 2=Advice
        │         └─► 1=Auth, 2=Financial, 4=Reversal, 8=Network
        └─► 0=1987, 1=1993, 2=2003
5 / 24

Slide 4: MTI Quick Reference

Version (Position 0)

ValueSpec Year
01987
11993
22003

Class (Position 1)

ValueTypeExample
1AuthorizationCard purchase
2FinancialStore-forward
4ReversalCancel/void
8Network MgmtEcho, sign-on

Function (Position 2)

ValueMeaning
0Request
1Response
2Advice
6 / 24

Slide 5: Common MTIs in Production

┌────────┬──────────────────────────────────────────┐
│  MTI   │  Meaning                                 │
├────────┼──────────────────────────────────────────┤
│  0100  │  Authorization Request                   │
│  0110  │  Authorization Response                  │
│  0120  │  Authorization Advice                    │
│  0130  │  Authorization Advice Response           │
├────────┼──────────────────────────────────────────┤
│  0400  │  Reversal Request                        │
│  0410  │  Reversal Response                       │
│  0420  │  Reversal Advice                         │
│  0430  │  Reversal Advice Response                │
├────────┼──────────────────────────────────────────┤
│  0800  │  Network Management Request              │
│  0810  │  Network Management Response             │
└────────┴──────────────────────────────────────────┘

Pattern: x0=request, x1=response

7 / 24

Slide 6: The Bitmap System

Primary Bitmap: 8 bytes = 64 bits

Byte:    72       3A       44       81       08       E1       80       00
Binary:  01110010 00111010 01000100 10000001 00001000 11100001 10000000 00000000
Bit #:   12345678 9....                                               ...64

Bit 1 = 0  →  No secondary bitmap
Bit 2 = 1  →  Field 2 (PAN) is present
Bit 3 = 1  →  Field 3 (Processing Code) is present
Bit 4 = 1  →  Field 4 (Amount) is present
Bit 5 = 0  →  Field 5 is NOT present
...

Rule: If bit N = 1, then Data Element N is in the message

8 / 24

Slide 7: Secondary Bitmap Trigger

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│   Primary Bitmap Bit 1 = 0                                      │
│   ─────────────────────────                                     │
│   Only fields 1-64 possible                                     │
│   Message has 8-byte bitmap                                     │
│                                                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   Primary Bitmap Bit 1 = 1                                      │
│   ─────────────────────────                                     │
│   Secondary bitmap follows immediately                          │
│   Fields 65-128 possible                                        │
│   Message has 16-byte bitmap                                    │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

2003 spec: Bit 65 = 1 triggers tertiary bitmap (fields 129-192)

9 / 24

Slide 8: Data Element Ordering

Bitmap indicates: Fields 2, 3, 4, 11, 12 present

Data appears in STRICT ORDER:

┌────────┬────────┬────────┬─────────┬─────────┐
│ DE 2   │ DE 3   │ DE 4   │ DE 11   │ DE 12   │
│ (PAN)  │(ProcCd)│(Amount)│ (STAN)  │ (Time)  │
└────────┴────────┴────────┴─────────┴─────────┘

No field markers between elements.
No separators.
Must know field lengths from specification.
10 / 24

Slide 9: Field Length Types

┌─────────────────────────────────────────────────────────────────┐
│  FIXED LENGTH                                                   │
│  ─────────────                                                  │
│  Spec says: "Field 4 is 12 numeric digits"                      │
│  Data:      000000010000  (always exactly 12)                   │
├─────────────────────────────────────────────────────────────────┤
│  LLVAR (2-digit length prefix)                                  │
│  ──────                                                         │
│  Data:      16 5412345678901234                                 │
│             ││ └─── 16 characters of PAN                        │
│             └─ Length = 16                                      │
├─────────────────────────────────────────────────────────────────┤
│  LLLVAR (3-digit length prefix)                                 │
│  ───────                                                        │
│  Data:      099 [99 bytes of data...]                           │
│             └── Length = 99                                     │
└─────────────────────────────────────────────────────────────────┘
11 / 24

Slide 10: Wire Format Example

Raw hex (ASCII-encoded MTI):
30313030 723A448108E18000 16541234567890123400000001000...
│______│ │______________│ │_______________________________...
   MTI       Bitmap              Data Elements

Decoded:
MTI:  0100 (Auth Request)
Bitmap: 723A448108E18000
  → Fields present: 2, 3, 4, 7, 11, 12, 14, 22, 23, 25, 26, 32, 35, 41, 42, 49, 52

Field 2 (LLVAR): "16" + "5412345678901234" = PAN
Field 3 (Fixed 6): "000000" = Processing Code (Purchase)
Field 4 (Fixed 12): "000000010000" = Amount (100.00)
...
12 / 24

Slide 10a: BCD vs ASCII Encoding

┌────────────────────────────────────────────────────────────────┐
│  ASCII Encoding (most common)                                  │
│  ─────────────────────────────                                 │
│  MTI "0100" →  30 31 30 30  (4 bytes)                          │
│  Number "1234" → 31 32 33 34 (4 bytes)                         │
│                                                                │
│  Telltale sign: Bytes in 0x30-0x39 range                       │
├────────────────────────────────────────────────────────────────┤
│  BCD Encoding (Binary Coded Decimal)                           │
│  ──────────────────────────────────────                        │
│  MTI "0100" →  01 00  (2 bytes)                                │
│  Number "1234" → 12 34 (2 bytes)                               │
│                                                                │
│  Telltale sign: Bytes look like the actual digits              │
└────────────────────────────────────────────────────────────────┘

When parsing fails: Check if you have the wrong encoding assumption!

13 / 24

Slide 10b: Processing Code (DE3) Structure

Processing Code: XX YY ZZ
                 │  │  │
                 │  │  └─ To Account Type
                 │  └──── From Account Type
                 └─────── Transaction Type

Transaction Types (XX):        Account Types (YY/ZZ):
  00 = Purchase                  00 = Default
  01 = Cash withdrawal           10 = Savings
  09 = Purchase + cashback       20 = Checking
  20 = Refund                    30 = Credit
  30 = Balance inquiry

Examples:
  000000 = Purchase from default to default
  011020 = Cash withdrawal from savings to checking
  200000 = Refund to default account
14 / 24

Slide 11: Authorization Flow

┌──────────┐    0100    ┌──────────┐    0100    ┌──────────┐    0100    ┌──────────┐
│ TERMINAL │ ────────►  │ ACQUIRER │ ────────►  │ NETWORK  │ ────────►  │  ISSUER  │
│          │            │ (Chase)  │            │  (Visa)  │            │  (BofA)  │
└──────────┘            └──────────┘            └──────────┘            └──────────┘
     │                       │                       │                       │
     │                       │                       │                       ▼
     │                       │                       │                  ┌─────────┐
     │                       │                       │                  │ APPROVE │
     │                       │                       │                  │    or   │
     │                       │                       │                  │ DECLINE │
     │                       │                       │                  └─────────┘
     │                       │                       │                       │
     │    0110               │    0110               │    0110               │
     │ ◄────────────────────│ ◄────────────────────│ ◄─────────────────────│
     ▼
┌──────────┐
│  PRINT   │
│ RECEIPT  │
└──────────┘
15 / 24

Slide 12: Message Matching Fields

Request (0100) goes out:
┌────────────────────────────────────────────┐
│  DE11: 123456  (STAN - unique trace)       │
│  DE12: 143052  (Local time)                │
│  DE13: 1229    (Local date)                │
│  DE32: 123456  (Acquirer ID)               │
│  DE37: RRN12345678  (Retrieval ref)        │
└────────────────────────────────────────────┘

Response (0110) must echo these:
┌────────────────────────────────────────────┐
│  DE11: 123456  ← MUST MATCH                │
│  DE12: 143052  ← MUST MATCH                │
│  DE13: 1229    ← MUST MATCH                │
│  DE32: 123456  ← MUST MATCH                │
│  DE37: RRN12345678  ← MUST MATCH           │
│                                            │
│  DE38: ABC123  (Auth code) ← NEW           │
│  DE39: 00      (Response code) ← NEW       │
└────────────────────────────────────────────┘

Acquirer uses these fields to match response to request.
16 / 24

Slide 13: Response Code Quick Reference

┌──────┬────────────────────────────────────────┐
│ Code │  Meaning                               │
├──────┼────────────────────────────────────────┤
│  00  │  Approved                              │
│  01  │  Refer to card issuer                  │
│  03  │  Invalid merchant                      │
│  05  │  Do not honor                          │
│  12  │  Invalid transaction                   │
│  13  │  Invalid amount                        │
│  14  │  Invalid card number                   │
│  41  │  Lost card, pick up                    │
│  43  │  Stolen card, pick up                  │
│  51  │  Insufficient funds                    │
│  54  │  Expired card                          │
│  55  │  Incorrect PIN                         │
│  61  │  Exceeds withdrawal limit              │
│  91  │  Issuer unavailable                    │
│  96  │  System malfunction                    │
└──────┴────────────────────────────────────────┘
17 / 24

Slide 14: 1987 vs 2003 Comparison

┌────────────────────┬───────────────────┬───────────────────┐
│      Aspect        │      1987         │       2003        │
├────────────────────┼───────────────────┼───────────────────┤
│ MTI prefix         │        0          │         2         │
│ Max fields         │       128         │        192        │
│ Bitmap bytes       │      8 or 16      │    8, 16, or 24   │
│ TLV support        │     Limited       │      Native       │
│ Character sets     │  ASCII/EBCDIC     │   UTF-8 support   │
│ Market share       │      ~80%         │       ~20%        │
└────────────────────┴───────────────────┴───────────────────┘

Most production systems: Still 1987 spec
Newer implementations: Moving to 2003
18 / 24

Slide 15: Key Takeaways

1. MTI = First 4 chars = Message identity
   └─► Version + Class + Function + Origin

2. Bitmap = Which fields are present
   └─► Bit N set = Field N present

3. Data Elements = Actual payload
   └─► Ordered by field number, no separators

4. Common patterns:
   └─► 0100/0110 = Auth request/response
   └─► 0400/0410 = Reversal request/response
   └─► 0800/0810 = Network mgmt request/response

5. Debugging tip:
   └─► Always check MTI first. It tells you everything.
19 / 24

Slide 16: Common Pitfalls

┌────────────────────────────────────────────────────────────────┐
│  1. OFF-BY-ONE IN BITMAP                                       │
│     Bit 1 is leftmost bit of first byte (not index 0!)         │
│                                                                │
│  2. ENCODING MISMATCH                                          │
│     ASCII (30 31 30 30) vs BCD (01 00) for same MTI            │
│                                                                │
│  3. MISSING LENGTH HEADER                                      │
│     First 2-4 bytes might be length, not MTI                   │
│                                                                │
│  4. AMOUNT DECIMALS                                            │
│     JPY has 0 decimals, USD has 2, KWD has 3                   │
│                                                                │
│  5. FIELD 1 CONFUSION                                          │
│     Field 1 IS the secondary bitmap, not separate data         │
│                                                                │
│  6. STAN UNIQUENESS                                            │
│     Unique per terminal per day, resets at midnight            │
└────────────────────────────────────────────────────────────────┘
20 / 24

Slide 17: Parse Contract Ladder

STAGE 0: Frame
  1) Read length header (if configured)
  2) Read TPDU (if configured)
  3) Read MTI (ASCII or BCD contract)

STAGE 1: Bitmap
  4) Read primary bitmap (8 or 16 chars/bytes)
  5) If primary bit1=1 -> read secondary
  6) If secondary bit1=1 and 2003 enabled -> read tertiary

STAGE 2: Fields
  7) For each "present" field, apply fixed/LLVAR/LLLVAR spec
  8) Validate each parsed field length before moving cursor

STAGE 3: Correlation
  9) Validate mandatory echo/validation keys (DE11/DE12/DE13/DE32)
 10) Persist for response matching and idempotency
21 / 24

Slide 17b: Progressive Parser Tests

1) Frame-only test:

  • 00 C8 30 31 30 30 ...
  • Expect: parsed length=200, MTI=0100, parser phase=bitmap

2) Bitmap expansion failure test:

  • Bit 1=1 but missing secondary bytes
  • Expect: ERR_BITMAP_TOO_SHORT

3) Variable length boundary test:

  • DE2 length says 99 but only 50 bytes remain
  • Expect: ERR_INVALID_LENGTH_PREFIX

4) Reversed-encoding regression test:

  • ASCII MTI bytes with BCD parser config
  • Expect: early ERR_ENCODING_MISMATCH, not mid-field corruption

5) Late response handling test:

  • 0100 pending, reversal sent, 0110 arrives
  • Expect: response suppressed if reversal state is terminal
22 / 24

Slide 18: Deep Pitfalls for Operations

  • Cursor discipline: one cursor, one stage machine, one fail-fast point.
  • Idempotency: cache retries keyed by STAN + date/time + terminal.
  • Correlation: never treat response codes as user-facing errors directly.
  • Encoding: validate MTI/bitmap encoding before reading variable fields.
  • Reversal races: a late 0110 after reversal is not normal and must be explicitly handled.
23 / 24

Quick Reference Card

MTI Structure:        [V][C][F][O]
                       │  │  │  │
Version ──────────────►│  │  │  │◄────── Origin (0=Acq, 2=Iss)
  0=1987, 2=2003          │  │
                          │  └─► Function (0=Req, 1=Resp)
                          └─► Class (1=Auth, 4=Rev, 8=Net)

Common MTIs:
  0100/0110  Authorization
  0400/0410  Reversal
  0800/0810  Network Management

Response Codes:
  00=Approved  51=NSF  54=Expired  55=Bad PIN

Length Header Check:
  First bytes 00 XX?  →  Probably 2-byte length header
  First bytes 30 31?  →  Probably ASCII MTI (no header or after header)
24 / 24
Use arrow keys or click edges to navigate. Press H to toggle help, F for fullscreen.