Home | Project Page | Download | Protocol description (Spanish) | Configuration | API documentation

A brief explanation of the ISO-8583 protocol

The objective of this protocol is to transmit information for payment processing through a network, usually using TCP/IP sockets. An ISO8583 message can have up to 63 or 127 fields and is processed in a linear way, that is, the message can be processed as it is being read.

Message format

A simple ISO8583 is comprised of the following:

The first field is a special field and contains a secondary bitmap. If the first bit of the primary bitmap is on, then the first field after the bitmap is another bitmap, also 64 bits long, indicating additional fields from 65 to 128.

Field types

From the second field to the last one, the message contains only "normal" fields, which can have the following datatypes:

Alpha:
Can contain a fixed number of characters and digits. The length is previouly established in the spec for the particular implementation. If the contents are shorter than the field length, it must be filled with spaces to the right.
Numeric
Can contain only digits with a fixed length. The length is previously established in the spec for the particular implementation. If the number is shorter than the field length, it must be zero-filled to the left.
LLVAR
This is an alphanumeric field of variable length. It has a 2-digit field header at the beginning, indicating the length of the rest of the field, which can be 0 to 99.
LLLVAR
Also an alphanumeric field of variable length, but the field header is 3 digits long, so the rest of the field can be 0 to 999 characters long.
Date/Time
There are three different date formats: A 10-digit format MMDDHHmmss, a 4-digit format YYMM (useful for expiration dates on credit cards), another 4-digit format MMDD. The time is specified as 6 digits in format HHmmss.
Amount
This is a 12-digit numeric field expressing a currency amount in cents. For example $15.00 is expressed as 000000001500.

Message types

The most common message types are:

0200 Request for payment, credit card charge, etc.
0210 Response to payment, credit card charge, etc.
0400 Request for reversal of payment, credit card charge, etc.
0410 Response to reversal of payment, credit card charge, etc.
0600 Query
0610 Response to query
0800 Echo request
0810 Echo response

Encoding

ISO8583 messages can be encoded as ASCII or binary; ASCII is more common. In this format, the message type is 4 bytes long, because the characters for it are sent as text, ie. "0200". In binary encoding, the message type is 2 bytes long, for example message type 0200 is encoded as byte 0x02 and byte 0x00.

In ASCII encoding, the bitmap is sent using hex encoding, so it's 16 characters long; that is, every 4 bits are a hex digit. For example, if the message includes fields 1 and 3 but not 2 or 4, then the first 4 bits are 1010 which is 0xA. In binary encoding, the bitmap is sent as 8 bytes, without encoding them in any way.

Numeric and alpha fields in ASCII have the same length in bytes as they do in characters or digits; numeric fields are sent as text, for example "000012".

In binary encoding, numeric fields are encoded using BCD (Binary Coded Digits), which means taking 2 digits and encoding them as hex, that is, the number 12 is encoded as 0x12; this way, a byte can always contain 2 digits. Numbers with an odd number of digits (such as the length header for a LLLVAR field) will have a zero to the left, for example 128 is encoded as two bytes: 0x1 and 0x28.

ASCII-encoded LLVAR and LLLVAR fields will have 2 or 3 character headers.

Binary encoded LLVAR and LLLVAR fields will have 1 or 2 byte headers; LLVAR fields have their header as a 1-byte BCD number, for example if the header is 0x57 it means that the field is 57 bytes long. LLLVAR fields have 2-byte BCD headers but the first digit is always 0; for example if the header is 0x128 it means the field contents are 128 bytes long.

Date and amount fields, being numeric, are encoded as any other numeric field. For example a full date field will be 10 characters long in ASCII encoding but only 5 bytes long in binary encoding.

ISO header

In some implementations, messages must include a header before the message type. This is implementation-specific and the headers usually vary only by message type.

Additionally, it is very common to include a header with the length of the message when sending ISO8583 over a network. The header is usually 2 bytes long and is a binary unsigned integer with the length of the full message, thus making the reading on the other side easier, since the process consists of reading 2 bytes, interpreting them as a length, and then reading that many bytes. The byte order is usually most significant byte first, but it can vary in certain implementations.

Sometimes there is also a message terminator, which can be included in the length or not, depending on implementation. Message terminators are usually just 1 byte long.

Examples

Here are some examples of ISO8583 messages, along with the XML definition to parse them with the j8583 framework. ASCII encoding is being used for these.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE j8583-config PUBLIC "-//J8583//DTD CONFIG 1.0//EN"
	"http://j8583.sourceforge.net/j8583.dtd">
<j8583-config>

<!-- These are the ISO headers to be prepended to the message types specified -->
<header type="0200">ISO015000050</header>
<header type="0210">ISO015000055</header>
<header type="0400">ISO015000050</header>
<header type="0410">ISO015000055</header>
<header type="0800">ISO015000015</header>
<header type="0810">ISO015000015</header>

<!-- The client example uses this to create requests -->
<template type="0200">
	<field num="3" type="NUMERIC" length="6">650000</field>
	<field num="32" type="LLVAR">456</field>
	<field num="35" type="LLVAR">4591700012340000=</field>
	<field num="43" type="ALPHA" length="40">SOLABTEST             TEST-3       DF MX
	<field num="49" type="ALPHA" length="3">484</field>
	<field num="60" type="LLLVAR">B456PRO1+000</field>
	<field num="61" type="LLLVAR">        1234P</field>
	<field num="100" type="LLVAR">999</field>
	<field num="102" type="LLVAR">ABCD</field>
</template>

<!-- The server example uses this to create the responses
	we only need a few fields because the rest are copied from the request -->
<template type="0210">
	<field num="60" type="LLLVAR">Fixed data from template</field>
	<field num="70" type="ALPHA" length="3">ABC</field>
	<field num="90" type="ALPHA" length="42">Field of length 42</field>
	<field num="100" type="LLVAR">Fixed field</field>
	<field num="102" type="LLVAR">Another fixed field</field>
	<field num="126" type="LLLVAR">...and yet another fixed field.</field>
</template>

<!-- The server example uses this to read the requests -->
<parse type="0200">
	<field num="3" type="NUMERIC" length="6" />
	<field num="4" type="AMOUNT" />
	<field num="7" type="DATE10" />
	<field num="11" type="NUMERIC" length="6" />
	<field num="12" type="TIME" />
	<field num="13" type="DATE4" />
	<field num="15" type="DATE4" />
	<field num="17" type="DATE_EXP" />
	<field num="32" type="LLVAR" />
	<field num="35" type="LLVAR" />
	<field num="37" type="NUMERIC" length="12" />
	<field num="41" type="ALPHA" length="16" />
	<field num="43" type="ALPHA" length="40" />
	<field num="48" type="LLLVAR" />
	<field num="49" type="ALPHA" length="3" />
	<field num="60" type="LLLVAR" />
	<field num="61" type="LLLVAR" />
	<field num="100" type="LLVAR" />
	<field num="102" type="LLVAR" />
</parse>

<!-- The client example uses this to read the responses -->
<parse type="0210">
	<field num="3" type="NUMERIC" length="6" />
	<field num="4" type="AMOUNT" />
	<field num="7" type="DATE10" />
	<field num="11" type="NUMERIC" length="6" />
	<field num="12" type="TIME" />
	<field num="13" type="DATE4" />
	<field num="15" type="DATE4" />
	<field num="17" type="DATE_EXP" />
	<field num="32" type="LLVAR" />
	<field num="35" type="LLVAR" />
	<field num="37" type="NUMERIC" length="12" />
	<field num="38" type="NUMERIC" length="6" />
	<field num="39" type="NUMERIC" length="2" />
	<field num="41" type="ALPHA" length="16" />
	<field num="43" type="ALPHA" length="40" />
	<field num="48" type="LLLVAR" />
	<field num="49" type="ALPHA" length="3" />
	<field num="60" type="LLLVAR" />
	<field num="61" type="LLLVAR" />
	<field num="70" type="ALPHA" length="3" />
	<field num="90" type="ALPHA" length="42" />
	<field num="100" type="LLVAR" />
	<field num="102" type="LLVAR" />
	<field num="126" type="LLLVAR" />
</parse>

</j8583-config>

Example 1

Request:
ISO0150000500200B23A800128A180180000000014000000650000000000002050042813271000057813271004280428042803456174591700012340000=000000230579A1B2C3D4E5 SOLABTEST TEST-3 DF MX010abcdefghij484012B456PRO1+000013 1234P0399904ABCD
FieldValue
ISO headerISO015000050
Message type0200
Primary bitmapB23A800128A18018
Secondary bitmap0000000014000000
3 (proc code)650000
4 (amount)000000002050 ($20.50)
7 (date)0428132710 (Abril 28 13:27:10)
11 (trace)000578
12 (time)132710 (13:27:10)
13 (date issued)0428 (28 de abril)
15 (limit date)0428 (28 de abril)
17 (expiration date)0804 (Abril 2008)
32456
354591700012340000=
37 (reference)000000230579
41 (term id)A1B2C3D4E5
43SOLABTEST TEST-3 DF MX
48abcdefghij
49 (currency)484
60B456PRO1+000
61 1234P
100999
102ABCD

Response:
ISO0150000550210B23A80012EA180180400004014000004650000000000002050042813271000057813271004280428060403456174591700012340000=00000023057923104300A1B2C3D4E5 SOLABTEST TEST-3 DF MX010abcdefghij484012B456PRO1+000054Dynamic data generated at Mon Apr 28 13:27:11 CDT 2008ABCField of length 42 0399904ABCD031...and yet another fixed field.
FieldValue
ISO headerISO015000055
Message type0210
Primary bitmapB23A80012EA18018
Secondary bitmap0400004014000004
3 (proc code)650000
4 (amount)000000002050 ($20.50)
7 (transaction date)0428132710 (Abril 28 13:27:10)
11 (trace)000578
12 (time)132710 (13:27:10)
13 (date issued)0428 (28 de abril)
15 (limit date)0428 (28 de abril)
17 (expiration date)0804 (Abril 2008)
32456
354591700012340000=
37 (reference)000000230579
38 (confirmation number)231043
39 (result code)00
41 (term id)A1B2C3D4E5
43SOLABTEST TEST-3 DF MX
48abcdefghij
49 (currency)484
60B456PRO1+000
61Dynamic data generated at Mon Apr 28 13:27:11 CDT 2008
70ABC
90Field of length 42
100999
102ABCD
126...and yet another fixed field.