ISO 8583 message parser and builder
Decode the MTI, bitmap and data elements of an ISO 8583 message, or assemble one field by field with the bitmap computed for you.
Runs in your browser — nothing you paste is sent to a server
How an ISO 8583 message is laid out
- MTI (4 digits) — version, message class, function and origin, one digit each.
0200is a 1987 financial request from an acquirer;0210is the response to it. - Primary bitmap (16 hex characters) — 64 bits, one per field. Bit 1 is not a data field: it flags that a secondary bitmap follows.
- Secondary bitmap — another 64 bits covering fields 65 to 128, present only when bit 1 is set.
- Data elements — in ascending field order. Fixed-length fields are padded; variable-length fields carry a 2 or 3 digit length prefix (LLVAR, LLLVAR) that is itself part of the message.
Building a message: what the builder decides for you
- The bitmap is computed from the fields you set — turn on any field above 64 and bit 1 is set and a secondary bitmap appears, which is the part people most often get wrong by hand.
- Fixed-length fields are padded — numeric fields with zeros on the left, text fields with spaces on the right. The builder shows the padded result under each input, with spaces drawn as dots so you can see them.
- Variable-length fields get their prefix — the two or three length digits an LLVAR or LLLVAR field carries are counted for you and shown in the encoded value.
- A value too long for a fixed field is an error, not a truncation — silently trimming it would shift every following field. A value that is the right length but the wrong character set is a warning: the message still parses, but a switch will reject it.
Scope and limits
- Handles two layouts. Text is ASCII characters with a hex bitmap, which is what application logs contain. Packed is a binary bitmap with packed-BCD lengths and numerics, usually alongside EBCDIC character data — what comes off a mainframe or an older switch. Paste those as a hex dump and set the two dropdowns.
- EBCDIC support covers the printable subset of code page 037 — letters, digits, space and the punctuation payments traffic uses. A byte outside that set is shown as
\xNNrather than guessed at, so a message that is not really EBCDIC looks obviously wrong instead of plausible. - Packed BCD cannot hold an odd number of digits in whole bytes, and the standard does not fix which end the padding nibble goes. A leading pad is assumed, which is the common convention, and the parser says so whenever it applied that assumption.
- Field definitions follow ISO 8583:1987. Fields 60 to 63 and 120 to 127 are reserved for private use — their layout is defined by your processor, not the standard, so they are shown structurally but not interpreted.
- Parsing stops at the first field it cannot locate, and names it. That field is where your layout and the standard diverge.
Worked example
A 0200 authorization request from an acquirer — a purchase of 499.00 INR at a grocery merchant, read from a chip card. Paste it into the parser above, then delete a single character from the middle to watch the field alignment collapse.
0200723C448108E080001641111111111111110000000000000499000214093015004321093015021428125411051001112345678901405512340001TERM0042MERCHANT123456 Bharat Grocers Kochi IN 356
The raw message above is shown in full so you can paste it — its PAN is 4111111111111111, the standard test number, and no real cardholder data appears anywhere on this site. The table below is what the parser shows you: the same message with the PAN, expiry and any track data masked.
- MTI
- 0200 — Financial, Request
- Primary bitmap
- 723C448108E08000
- Fields present
- 2, 3, 4, 7, 11, 12, 13, 14, 18, 22, 25, 32, 37, 41, 42, 43, 49
- Characters consumed
- 186 of 186
| # | Field | Value |
|---|---|---|
| 2 | Primary account number (PAN) LLVAR n..19 | 411111******1111 |
| 3 | Processing code n 6 | 000000 Purchase (goods and services); from default / unspecified, to default / unspecified |
| 4 | Amount, transaction n 12 | 000000049900 49900 minor units (divide by the exponent for the currency in field 49) |
| 7 | Transmission date and time n 10 MMDDhhmmss | 0214093015 14/02 at 09:30:15 UTC (no year in this field) |
| 11 | System trace audit number (STAN) n 6 | 004321 |
| 12 | Time, local transaction n 6 hhmmss | 093015 |
| 13 | Date, local transaction n 4 MMDD | 0214 |
| 14 | Date, expiration n 4 YYMM | **** |
| 18 | Merchant category code (MCC) n 4 | 5411 |
| 22 | Point of service entry mode n 3 | 051 PAN read by chip (ICC), CVV reliable; terminal can accept a PIN |
| 25 | Point of service condition code n 2 | 00 |
| 32 | Acquiring institution identification code LLVAR n..11 | 12345678901 |
| 37 | Retrieval reference number an 12 | 405512340001 |
| 41 | Card acceptor terminal identification ans 8 | TERM0042 |
| 42 | Card acceptor identification code ans 15 | MERCHANT123456 |
| 43 | Card acceptor name / location ans 40 | Bharat Grocers Kochi IN |
| 49 | Currency code, transaction an 3 | 356 INR |
Frequently asked questions
- Why does my message stop parsing partway through?
- Almost always a length mismatch: once one field consumes the wrong number of characters, every field after it starts at the wrong offset and the message turns to noise. The usual causes are a private-use field (60 to 63, 120 to 127) whose layout your processor defines rather than the standard, a variable-length field whose prefix is packed rather than ASCII, or a message that is not ASCII at all. This tool stops at the first field it cannot locate and tells you which one, so the field it names is where your layout and the standard diverge.
- What is the secondary bitmap and when is it present?
- The primary bitmap is 64 bits covering fields 1 to 64. Bit 1 is not a data field — it is the flag that says a secondary bitmap follows, covering fields 65 to 128. So a message using any field above 64 will always have bit 1 set and 16 extra hex characters after the primary bitmap. A tertiary bitmap for fields 129 to 192 exists and is flagged by bit 65, but is rare in practice.
- How do I work out the bitmap for the fields I want to send?
- You do not have to: switch to the build tab, add the fields you need, and the bitmap is computed from them. Each field number is a bit, counting from 1 at the most significant bit of the first byte, so fields 3 and 4 give 0011 0000 in the first byte — hex 30. The rule people miss is bit 1, which is not field 1: it is the flag saying a secondary bitmap follows, and it must be set whenever you use any field above 64. The builder sets it and appends the second bitmap automatically, and shows both in hex so you can check them against what your switch expects.
- Does this handle packed BCD or EBCDIC messages?
- Yes. Set the input to a hex dump, the layout to packed, and the character encoding to EBCDIC. Packed layout means a binary 8-byte bitmap, length prefixes and numeric fields in BCD at two digits per byte, and binary fields as raw bytes; EBCDIC covers the printable subset of code page 037. Two things are worth knowing. Packed BCD cannot hold an odd number of digits in whole bytes, and the standard does not say which end the padding nibble goes, so a leading pad is assumed and the parser tells you which fields that affected. And a byte with no EBCDIC mapping is shown as an escape rather than guessed at, so a message that is not really EBCDIC looks wrong instead of plausible. If the MTI will not read as four digits, the layout or encoding is usually the reason.
- Is it safe to paste a production message?
- Parsing happens entirely in your browser and nothing is transmitted. That said, a real ISO 8583 message contains a PAN, often track data, and sometimes a PIN block, so cardholder data is masked by default here — a parsed message is exactly the kind of thing that ends up screenshotted into a ticket. Prefer test data where you can, and treat anything you unmask as being in PCI scope.