You are on page 1of 6

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: Message type: Indicates if the message is a request or a response, and what type of transaction it is. Bitmap: The bitmap indicates the fields contained in the message. It is a binary string of 64 bits, in which every bit corresponds to a field, indicating which fields are included in the message. Fields: Fields are included after the bitmap. There are different field types and the message does not indicate the type of field; this has to be defined previously on a specification (there is a certain standard for some common fields but some implementations do not follow it, so it is very important to always review the specification for the specific implementation you will work on). 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 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>

TEST-3

<!-- 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 <field <field <field <field <field <field <field <field <field <field <field <field </parse>

num="15" type="DATE4" /> num="17" type="DATE_EXP" /> num="32" type="LLVAR" /> num="35" type="LLVAR" /> num="37" type="NUMERIC" length="12" /> num="41" type="ALPHA" length="16" /> num="43" type="ALPHA" length="40" /> num="48" type="LLLVAR" /> num="49" type="ALPHA" length="3" /> num="60" type="LLLVAR" /> num="61" type="LLLVAR" /> num="100" type="LLVAR" /> num="102" type="LLVAR" />

<!-- 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:

ISO0150000500200B23A800128A18018000000001400000065000000000000205004281327100 0057813271004280428042803456174591700012340000=000000230579A1B2C3D4E5 SOLABTEST TEST-3 DF MX010abcdefghij484012B456PRO1+000013 1234P0399904ABCD

Field Value ISO015000050 ISO header 0200 Message type B23A800128A18018 Primary bitmap Secondary bitmap 0000000014000000 650000 3 (proc code) 4 (amount) 000000002050 ($20.50) 7 (date) 0428132710 (Abril 28 13:27:10) 000578 11 (trace) 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) 456 32 4591700012340000= 35 000000230579 37 (reference) A1B2C3D4E5 41 (term id) SOLABTEST TEST-3 DF MX 43 abcdefghij 48 484 49 (currency) B456PRO1+000 60 1234P 61 999 100 ABCD 102

Response:

ISO0150000550210B23A80012EA18018040000401400000465000000000000205004281327100 0057813271004280428060403456174591700012340000=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.

Field Value ISO015000055 ISO header 0210 Message type B23A80012EA18018 Primary bitmap 0400004014000004 Secondary bitmap 650000 3 (proc code) 4 (amount) 000000002050 ($20.50) 7 (transaction date) 0428132710 (Abril 28 13:27:10) 000578 11 (trace) 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) 456 32 4591700012340000= 35 000000230579 37 (reference) 38 (confirmation number) 231043 00 39 (result code) A1B2C3D4E5 41 (term id) SOLABTEST TEST-3 DF MX 43 abcdefghij 48 484 49 (currency) B456PRO1+000 60 Dynamic data generated at Mon Apr 28 13:27:11 CDT 2008 61 ABC 70 Field of length 42 90 999 100 ABCD 102 ...and yet another fixed field. 126