Module 1: ISO8583 Foundations
Slides & Visual Reference
1 / 24
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:
00 C8 = 200 bytes (big-endian)30 32 30 30 = "0200"02 00 = 200 bytesThe "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
┌────────────────────────────────────────────────────────────────────┐
│ 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.
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
| Value | Spec Year |
|---|---|
| 0 | 1987 |
| 1 | 1993 |
| 2 | 2003 |
| Value | Type | Example |
|---|---|---|
| 1 | Authorization | Card purchase |
| 2 | Financial | Store-forward |
| 4 | Reversal | Cancel/void |
| 8 | Network Mgmt | Echo, sign-on |
| Value | Meaning |
|---|---|
| 0 | Request |
| 1 | Response |
| 2 | Advice |
┌────────┬──────────────────────────────────────────┐
│ 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
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
┌─────────────────────────────────────────────────────────────────┐
│ │
│ 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)
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.
┌─────────────────────────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────────────────────────┘
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)
...
┌────────────────────────────────────────────────────────────────┐
│ 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!
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
┌──────────┐ 0100 ┌──────────┐ 0100 ┌──────────┐ 0100 ┌──────────┐
│ TERMINAL │ ────────► │ ACQUIRER │ ────────► │ NETWORK │ ────────► │ ISSUER │
│ │ │ (Chase) │ │ (Visa) │ │ (BofA) │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
│ │ │ │
│ │ │ ▼
│ │ │ ┌─────────┐
│ │ │ │ APPROVE │
│ │ │ │ or │
│ │ │ │ DECLINE │
│ │ │ └─────────┘
│ │ │ │
│ 0110 │ 0110 │ 0110 │
│ ◄────────────────────│ ◄────────────────────│ ◄─────────────────────│
▼
┌──────────┐
│ PRINT │
│ RECEIPT │
└──────────┘
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.
┌──────┬────────────────────────────────────────┐
│ 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 │
└──────┴────────────────────────────────────────┘
┌────────────────────┬───────────────────┬───────────────────┐
│ 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
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.
┌────────────────────────────────────────────────────────────────┐
│ 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 │
└────────────────────────────────────────────────────────────────┘
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
1) Frame-only test:
00 C8 30 31 30 30 ...2) Bitmap expansion failure test:
ERR_BITMAP_TOO_SHORT3) Variable length boundary test:
ERR_INVALID_LENGTH_PREFIX4) Reversed-encoding regression test:
ERR_ENCODING_MISMATCH, not mid-field corruption5) Late response handling test:
0100 pending, reversal sent, 0110 arrives0110 after reversal is not normal and must be explicitly handled.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)