ISO 8583 Parser
Free Β· Reference Β· ~12 min read Β· Updated 2026-08-21

What Is ISO 8583?

ISO 8583 is the message format that card systems use to talk to each other. When a card is tapped, an ISO 8583 message travels from the terminal to the acquirer, on to the card network, and to the issuer that says yes or no. A message is three things: a four-digit MTI that says what kind of message this is, a bitmap that says which fields are present, and the data elements themselves. Everything below is on this page β€” the structure, a decoded example, and the tables you look codes up in.
On this page: What ISO 8583 actually is Β· The shape of a message Β· A message, decoded Β· The fields you will actually touch Β· The code tables Β· Where implementations differ Β· FAQ

What ISO 8583 actually is

It is an international standard for financial transaction card-originated messages. It does not describe a network, an API or a product β€” it describes how to lay bytes out so two systems that have never met can agree on what a payment request says. That is why a 1987 standard still carries most of the world's card traffic: the format outlived every technology built on top of it.

Three editions exist β€” 1987, 1993 and 2003 β€” and 1987 is still the one you are most likely to meet. They differ in which fields exist and how wide some of them are, so the edition is not a footnote: the same bytes can decode differently under two editions. The first digit of the MTI tells you which one you are reading.

Almost nobody runs plain ISO 8583. Visa, Mastercard, and domestic switches each publish their own dialect: the same field numbers, their own meanings for the private fields, their own extra codes, sometimes their own character encoding. The standard gives you the envelope; the scheme specification tells you what is written inside. Treat any implementation guide you are handed as the authority over the base standard where the two disagree.

The shape of a message

Read a message left to right in three parts.

1. The MTI β€” four digits saying what this message is

Each digit does one job:

PositionMeaningExamples
1Version0 = 1987, 1 = 1993, 2 = 2003
2Message class1 authorization, 2 financial, 4 reversal, 8 network management
3Message function0 request, 1 response, 2 advice, 3 advice response
4Message origin0 acquirer, 2 issuer, 1/3 the same but a repeat

So 0100 is a 1987 authorization request from an acquirer, and 0110 is the response to it. 0400 is a reversal request, 0800 a network management message such as a sign-on or an echo test. Reading the four digits separately is faster than memorising a list of MTIs.

2. The bitmap β€” which fields are in this message

The bitmap is 64 bits, usually written as 16 hex characters. Bit n set means data element n is present, in ascending order, and absent fields simply are not there β€” there is no padding and no placeholder. That is the whole trick of the format: it stays compact without a schema, because the bitmap is the schema.

Bit 1 is special: it does not mean DE1, it means a second bitmap follows, extending the range to DE128. If bit 1 is not set, the message stops at DE64 and there are only 16 hex characters of bitmap.

Two mistakes account for most bitmap bugs: counting bits from 0 instead of 1, and forgetting that the bitmap can be sent as raw binary (8 bytes) rather than hex text (16 characters). Both produce fields that parse one position out.

3. The data elements β€” the values themselves

Each field is either fixed length, or prefixed by its own length:

TypePrefixReading it
FIXnoneTake exactly the declared number of characters. DE4 is always 12 digits.
LLVAR2 digitsRead two digits as the length, then that many characters. Those two digits are not part of the value.
LLLVAR3 digitsSame idea, three-digit length. Used where a field can exceed 99 characters, like DE55.

The declared length is counted in characters of the value, which is not always bytes: under Hex/BCD two digits pack into one byte, and a binary field's length may be given in bytes or in bits depending on the specification. When a parser drifts one field at a time, the length unit is the first thing to check.

A message, decoded

Here is a complete authorization request, assembled from a test card number and a placeholder terminal. Nothing here is real cardholder data.

010072200000008080001641111111111111110000000000000010000821143000123456TERM0001702

Taken apart, left to right:

BytesFieldReads as
0100MTI1987, authorization, request, from the acquirer
7220000000808000BitmapBits 2, 3, 4, 7, 11, 41 and 49 are set β€” those seven fields follow, in that order. Bit 1 is clear, so there is no second bitmap.
16 4111111111111111DE2 β€” PANLLVAR: the 16 is the length, the card number is the next 16 digits
000000DE3 β€” Processing codePurchase, both accounts unspecified
000000001000DE4 β€” Amount1000 minor units. With DE49 = 702 (SGD, two decimals) that is SGD 10.00
0821143000DE7 β€” Transmission21 August, 14:30:00 GMT. No year in the field.
123456DE11 β€” STANThe acquirer's trace number for the day
TERM0001DE41 β€” Terminal IDUnique within this merchant, not globally
702DE49 β€” CurrencyISO 4217 numeric for the Singapore dollar

Notice that DE4 means nothing until DE49 is read. That ordering β€” currency before amount β€” is the single most common source of amounts that are wrong by a factor of a hundred.

You can paste the message above into the parser on the home page and watch it come apart field by field.

The fields you will actually touch

There are 128 data elements. In practice a handful carry almost every question you will be asked:

FieldNameWhy it comes up
DE2PANThe card number. First 6–8 digits route the message; masked in every log.
DE3Processing codePurchase or cash decides pricing, limits and interest.
DE4AmountMinor units, no decimal point. Meaningless without DE49.
DE11STANUnique per day per acquirer only β€” it wraps and gets reused.
DE22POS entry modeHow the card was read; carries fraud liability.
DE37Retrieval reference numberStable for the whole life of the transaction β€” the practical join key.
DE39Response code00 is approved; everything else is the reason.
DE41/DE42Terminal / merchant IDWhere it happened, and what the cardholder disputes against.
DE49CurrencyFixes the decimals for DE4. Read it first.
DE55ICC dataChip data as TLV β€” where a chip decline explains itself.

The field dictionary has all 128 with lengths, formats and notes.

The code tables

Most ISO 8583 work is not parsing β€” it is looking up what a value means. The tables worth bookmarking:

Where implementations differ

Four places where the standard stops and someone else's document takes over. Every one of them has cost somebody a week.

Frequently asked questions

Is ISO 8583 still used?

Yes β€” it carries the large majority of card authorization traffic worldwide. ISO 20022 is growing in account-to-account and instant payments, and some schemes are migrating, but card rails run on 8583 and will for years. The two coexist rather than one having replaced the other.

What is the difference between ISO 8583 and ISO 20022?

8583 is compact positional bytes designed for 1980s links; 20022 is XML or JSON with a rich data model. 8583 says less in far fewer bytes, which is why it survives on latency-sensitive card networks. They are different formats for overlapping jobs, not versions of one thing.

Do I need the paid standard to work with ISO 8583?

For the base structure β€” MTI, bitmap, field numbers, lengths β€” no; that is well documented publicly, including on this site. For the private fields and the extra codes your traffic actually contains, you need the specification from your scheme or processor. That part is not public and cannot be inferred.

Why does my parser drift after a few fields?

Nearly always a length unit or an encoding: a binary field whose length is in bytes read as characters, a Hex/BCD field read as ASCII, or a bitmap sent as 8 raw bytes read as 16 hex characters. Find the last field that decoded correctly and check its length rule.

Read next