Decoding an ISO 8583 Payload

Goal: Understand the fixed‑position pieces that make up the ASCII string we receive in ISOFullMessage, so you can split it by eye or with any language / tool.


1. High‑level Structure

┌──────────────────────────────────────────────────────────────┐
│ Transport / Host header        (variable, host‑specific)     │
│ ──────────────────────────────────────────────────────────── │
│ MTI           4  n                                            │
│ Primary bitmap 16  n  (64 bits → 16 hex characters)          │
│ Secondary bitmap 16  n  (present only if bit 1 = 1)          │
│ Data elements  …   (1‑128, in ascending order)               │
└──────────────────────────────────────────────────────────────┘
  • All characters are ASCII.

  • Numeric fields (n) are right‑justified, zero‑padded.

  • Alphanumeric fields (ans) are left‑justified, space‑padded.

  • Variable‑length fields begin with a numeric length prefix:

    • LLVAR → 2 digits (00‑99)

    • LLLVAR → 3 digits (000‑999)


2. Example in the Wild

Below is the authorization message you saw (line‑wrapped & spaced):

ISO0260000700 | 0120 | B23AC4112EE1801C
0000000214000100 | 0000000000000000 | 0285
0724181349 | 863303 | 141300 | 0724 | 0724
554105 | 2C0000000006 | 12345621543464******6993=0000427704382626
185503 | 0000010003        | 127298000000000
EXXON UPPY'S #68 #2009CENTREVILLE  VA US
0100724141353840 | 0160000000
… (continues)

What those chunks are

Segment
Meaning
Why the spacing?

ISO0260000700

Transport header – prepended by the host to carry length, protocol version, routing info. Its size (12–20 bytes) is vendor‑defined.

Not part of ISO 8583 proper. Discard before parsing.

0120

MTI0 120 = Authorization Advice.

Always 4 numeric chars.

B23AC4112EE1801C

Primary bitmap (16 hex chars = 64 bits). Bit 1 is set (B = 1011), so a secondary bitmap follows.

Every 4 bits are packed into one hex char—no delimiter.

0000000214000100

Secondary bitmap (also 16 hex).

Present only because bit 1 in the primary bitmap = 1.

Remaining blocks

Data elements in ascending order (2, 3, 4, … ). Each occupies exactly its specified length, or LL/LLL prefix + value.

Padding (zeros / spaces) makes every fixed field keep its place so downstream systems can slice without delimiters.


3. Bitmap → Which Fields Follow?

  1. Convert each hex char to binary. Example: B23A…1011 0010 0011 1010 …

  2. Number bits 1‑64 (or 1‑128).

  3. If a bit = 1, its corresponding field immediately follows the bitmap(s).

  4. Move through the message in ascending field order, reading:

Field #
Format
Length
Notes

2 – PAN

LLVAR n

up to 19

LL tells you how many digits follow.

3 – Processing code

n

6

Always 000000 for POS sale in our messages.

4 – Amount, Txn

n

12

Right‑padded zeros: 00000000285 = $2.85

11 – STAN

n

6

185503 in the sample.

37 – Retrieval Ref # (RRN)

an

12

724181349863 – used to link auth ↔ purchase.

41 – Terminal ID

ans

8

00010003 (space‑padded if shorter).

(The complete ISO 8583 spec defines > 120 fields. Only the ones lit by the bitmap are present.)


4. Reading Variable‑length Fields

PAN (Field 2)  =  16  543464******6993
                 ──┘ └─────────────────
                 length indicator  (2 chars)
  • If the bitmap says Field 2 exists, take the next 2 chars, convert to an int (16), then read exactly that many chars for the PAN.

  • Immediately after that, continue with the next field (Field 3).


5. Padding Rules Cheat‑Sheet

Format
Justify
Pad with
Example

n (numeric)

right

0

00000000285

an, ans (alpha / alnum / special)

left

space (0x20)

00010003·· → becomes 00010003 <space><space>

Track / discretionary

fixed

F or = etc. as per card standards

543464******6993=...

Tip: When debugging, replace 0x20 with · so you can see trailing spaces.


6. Putting It All Together (Walk‑through)

  1. Strip transport header (ISO0260000700).

  2. Read MTI (0120).

  3. Read Primary bitmap (16 hex).

  4. Because bit 1 = 1, read Secondary bitmap (another 16 hex).

  5. Iterate fields:

    • bit 2 = 1 → Field 2 (LLVAR) → read length LL → read PAN.

    • bit 3 = 1 → Field 3 (6 n) → read 6 chars.

    • … continue until all 1 bits are consumed.

  6. You should land exactly on the last byte of the message. Extras mean parsing error.


7. Where the Retrieval Reference Number Hides

  • Field 37 (RRN) always shows up after Field 35/36 (Track2/Track3) for our host.

  • Because we never carry field 70+ in auth/purchase, the RRN is usually < halfway down the message.

  • Example auth vs. purchase pair:

Auth  – … 185503 | **724181349863** | 0000010003 …
Purchase – … 583719 | **724181349863** | 895229592889 …

Same RRN → same transaction lifecycle.


8. Appendix – Field Directory (Common in Our Webhooks)

Field
Length
Format
Meaning

2

LLVAR (≤ 19)

n

Primary account number (PAN)

3

6

n

Processing code

4

12

n

Amount, transaction

11

6

n

System trace audit number (STAN)

12

6

n

Local Txn time (hhmmss)

13

4

n

Local Txn date (MMDD)

37

12

an

Retrieval reference number (RRN)

41

8

ans

Terminal ID

42

15

ans

Merchant ID (sometimes blank)

43

40

ans

Card acceptor name / location

55

LLLVAR (≤ 999)

b

EMV data (if e‑com / chip)

(Fields differ per processor; consult the host spec if something new appears.)

Last updated