La idea de este protocolo es poder transmitir información para procesamiento de pagos a través de sockets de TCP/IP. Un mensaje de ISO8583 puede tener hasta 63 o 127 campos y se procesa de manera lineal (es decir, se va leyendo el mensaje en el orden en que fue recibido).
Un mensaje simple de ISO8583 viene de la siguiente forma:
El primer campo es un campo especial y corresponde a un bitmap secundario. Si el primer bit del bitmap primario (es decir el bitmap que siempre viene) está encendido, entonces después del bitmap primario viene un bitmap secundario, es decir, otros 64 bits que permiten incluir campos del 65 al 128.
A partir del segundo campo ya son solamente campos estándar, y pueden tener los siguientes tipos:
000000001500
.Los tipos de petición más comunes son:
0200 | Petición de abono, venta, recarga, cargo a tarjeta de crédito, etc. |
0210 | Respuesta de abono, venta, recarga, cargo a tarjeta de crédito, etc. |
0400 | Petición de reverso o anulación de abono, venta, recarga, etc |
0410 | Petición de reverso o anulación de abono, venta, recarga, etc |
0600 | Consulta de datos |
0610 | Respuesta a consulta de datos |
0800 | Mensaje de eco |
0810 | Respuesta a mensaje de eco |
Los mensajes ISO8583 se pueden codificar en ASCII o binario; el más común es ASCII, en el cual el tipo de mensaje mide 4 bytes porque se mandan los caracteres de texto como se indica anteriormente, por ejemplo para una recarga se envian los bytes 48, 50, 48, 48 que corresponden al texto "0200". En caso de mensaje binario se envían dos bytes, el byte 2 y un byte 0, ya que en hexadecimal el primer byte es 0x02 y el siguiente es 0x00, juntos son 0x0200.
En el caso de ASCII, el bitmap se envía como 16 caracteres que contienen el bitmap codificado en hexadecimal, es decir, cada 4 bits vienen como 1 dígito hexadecimal, por ejemplo si el mensaje incluye los campos 1 y 3 pero no los campos 2 ni 4, entonces los primeros 4 bits con 1010 y eso en hexadecimal se expresa como A. En caso de mensaje binario se envían 8 bytes sin codificar de ninguna manera.
Los campos numéricos y alfanuméricos en ASCII miden tantos bytes como posiciones contengan; es decir un campo numérico de 6 posiciones medirá 6 bytes y contendrá el número en texto; es decir, el numero 000012 por ejemplo vendrá en ASCII como los caracteres ASCII 48, 48, 48, 48, 49, 50.
Para los campos numéricos en codificación binaria se usa BCD (Binary Coded Digits), la cual consiste en tomar dos dígitos y pasarlos a hexadecimal, de manera que un byte puede contener dos dígitos. Por ejemplo el número 15 se transmite como el byte 0x15, el número 8 se transmite como 0x08, el número 128 se transmite como 0x0128 (dos bytes; 0x01 y 0x28). Por lo tanto la longitud en bytes es la mitad de la longitud en posiciones y siempre será par; si la longitud en posiciones es non, simplemente se ignora el primer dígito que siempre será un 0.
Los campos LLVAR y LLLVAR en ASCII tienen encabezados de dos y tres bytes respectivamente, indicando la longitud del resto del campo en texto. Un campo LLVAR o LLLVAR en ASCII que indique por ejemplo una longitud de 3 posiciones, tendrá un contenido de 3 bytes, más su encabezado. Por ejemplo un campo LLVAR con el texto "ABC" será codificado como la cadena "03ABC".
Los campos LLVAR y LLLVAR en binario son un poco más complicados. El campo LLVAR tiene un encabezado de un solo byte que contiene la longitud codificada en BCD y posteriormente viene su contenido. Pero un campo LLLVAR tendrá un encabezado de 2 bytes, con la longitud codificada en BCD pero se debe ignorar el primer dígito que siempre será 0.
Los campos de fecha y monto, al ser numéricos, se codifican como cualquier otro dato numérico, es decir en ASCII un monto mide 12 bytes pero en binario mide 6 bytes porque viene codificado en BCD.
En algunas ocasiones los mensajes deben incluir un encabezado que puede ir antes incluso del tipo de mensaje. La especificación para la implementación de la mensajería debe definir los encabezados, que pueden ser distintos por tipo de mensaje.
Adicionalmente, es muy común que para la transmisión de datos se defina un encabezado binario de 2 o 4 bytes, en el cual se indica la longitud del mensaje que se debe leer. De esta manera se simplifica la lectura en un socket TCP, ya que se leen dos bytes, y después se debe leer solamente tantos bytes como se indique en dicho encabezado. El orden de los bytes se debe incluir en la especificación, aunque por lo general va primero el byte más significativo.
En ocasiones se incluye también un terminador de mensaje, el cual puede estar incluido en la longitud del mensaje o no, dependiendo de la implementación.
A continuación se presentan algunos ejemplos de mensajes ISO8583, junto con la definición en XML para usarse en el framework j8583. En este caso se usa codificación en ASCII.
<?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>
Petición:
ISO0150000500200B23A800128A180180000000014000000650000000000002050042813271000057813271004280428042803456174591700012340000=000000230579A1B2C3D4E5 SOLABTEST TEST-3 DF MX010abcdefghij484012B456PRO1+000013 1234P0399904ABCD
Campo | Valor |
---|---|
Encabezado ISO | ISO015000050 |
Tipo de mensaje | 0200 |
Bitmap Primario | B23A800128A18018 |
Bitmap secundario | 0000000014000000 |
3 (proc code) | 650000 |
4 (monto) | 000000002050 ($20.50) |
7 (fecha) | 0428132710 (Abril 28 13:27:10) |
11 (trace) | 000578 |
12 (hora) | 132710 (13:27:10) |
13 (fecha expedicion) | 0428 (28 de abril) |
15 (fecha lim) | 0428 (28 de abril) |
17 (expiracion) | 0804 (Abril 2008) |
32 | 456 |
35 | 4591700012340000= |
37 (referencia) | 000000230579 |
41 (term id) | A1B2C3D4E5 |
43 | SOLABTEST TEST-3 DF MX |
48 | abcdefghij |
49 (currency) | 484 |
60 | B456PRO1+000 |
61 | 1234P |
100 | 999 |
102 | ABCD |
Respuesta:
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.
Campo | Valor |
---|---|
Encabezado ISO | ISO015000055 |
Tipo de mensaje | 0210 |
Bitmap Primario | B23A80012EA18018 |
Bitmap secundario | 0400004014000004 |
3 (proc code) | 650000 |
4 (monto) | 000000002050 ($20.50) |
7 (fecha) | 0428132710 (Abril 28 13:27:10) |
11 (trace) | 000578 |
12 (hora) | 132710 (13:27:10) |
13 (fecha expedicion) | 0428 (28 de abril) |
15 (fecha lim) | 0428 (28 de abril) |
17 (expiracion) | 0804 (Abril 2008) |
32 | 456 |
35 | 4591700012340000= |
37 (referencia) | 000000230579 |
38 (num. confirmacion) | 231043 |
39 (result code) | 00 |
41 (term id) | A1B2C3D4E5 |
43 | SOLABTEST TEST-3 DF MX |
48 | abcdefghij |
49 (currency) | 484 |
60 | B456PRO1+000 |
61 | Dynamic data generated at Mon Apr 28 13:27:11 CDT 2008 |
70 | ABC |
90 | Field of length 42 |
100 | 999 |
102 | ABCD |
126 | ...and yet another fixed field. |