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.
Read a message left to right in three parts.
Each digit does one job:
| Position | Meaning | Examples |
|---|---|---|
1 | Version | 0 = 1987, 1 = 1993, 2 = 2003 |
2 | Message class | 1 authorization, 2 financial, 4 reversal, 8 network management |
3 | Message function | 0 request, 1 response, 2 advice, 3 advice response |
4 | Message origin | 0 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.
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.
Each field is either fixed length, or prefixed by its own length:
| Type | Prefix | Reading it |
|---|---|---|
FIX | none | Take exactly the declared number of characters. DE4 is always 12 digits. |
LLVAR | 2 digits | Read two digits as the length, then that many characters. Those two digits are not part of the value. |
LLLVAR | 3 digits | Same 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.
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:
| Bytes | Field | Reads as |
|---|---|---|
0100 | MTI | 1987, authorization, request, from the acquirer |
7220000000808000 | Bitmap | Bits 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 4111111111111111 | DE2 β PAN | LLVAR: the 16 is the length, the card number is the next 16 digits |
000000 | DE3 β Processing code | Purchase, both accounts unspecified |
000000001000 | DE4 β Amount | 1000 minor units. With DE49 = 702 (SGD, two decimals) that is SGD 10.00 |
0821143000 | DE7 β Transmission | 21 August, 14:30:00 GMT. No year in the field. |
123456 | DE11 β STAN | The acquirer's trace number for the day |
TERM0001 | DE41 β Terminal ID | Unique within this merchant, not globally |
702 | DE49 β Currency | ISO 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.
There are 128 data elements. In practice a handful carry almost every question you will be asked:
| Field | Name | Why it comes up |
|---|---|---|
DE2 | PAN | The card number. First 6β8 digits route the message; masked in every log. |
DE3 | Processing code | Purchase or cash decides pricing, limits and interest. |
DE4 | Amount | Minor units, no decimal point. Meaningless without DE49. |
DE11 | STAN | Unique per day per acquirer only β it wraps and gets reused. |
DE22 | POS entry mode | How the card was read; carries fraud liability. |
DE37 | Retrieval reference number | Stable for the whole life of the transaction β the practical join key. |
DE39 | Response code | 00 is approved; everything else is the reason. |
DE41/DE42 | Terminal / merchant ID | Where it happened, and what the cardholder disputes against. |
DE49 | Currency | Fixes the decimals for DE4. Read it first. |
DE55 | ICC data | Chip data as TLV β where a chip decline explains itself. |
The field dictionary has all 128 with lengths, formats and notes.
Most ISO 8583 work is not parsing β it is looking up what a value means. The tables worth bookmarking:
Four places where the standard stops and someone else's document takes over. Every one of them has cost somebody a week.
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.
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.
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.
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.