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

Breve explicación del protocolo ISO8583

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).

Formato del mensaje

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.

Tipos de campo

A partir del segundo campo ya son solamente campos estándar, y pueden tener los siguientes tipos:

Alfanumérico
Consiste en letras y números y tiene una longitud fija, previamente establecida en la especificación del mensaje. Si el contenido es menor a la longitud del campo, se debe rellenar con espacios a la derecha.
Numérico
Consiste solamente en números y tiene una longitud fija, previamente establecida en la especificación del mensaje. Si el contenido es menor a la longitud del campo, se debe rellenar con ceros a la izquierda.
LLVAR
Es un campo alfanumérico de longitud variable. Contiene un pequeño encabezado de dos posiciones al principio, indicando la longitud del resto del campo. Se deben leer estas dos posiciones y después se deben leer tantas posiciones como se indique ahí. Puede tener una longitud de 0 a 99 caracteres.
LLLVAR
Es un campo alfanumérico de longitud variable. Contiene un pequeño encabezado de tres posiciones al principio, indicando la longitud del resto del campo; se deben leer estas tres posiciones y luego tantas posiciones como se indique ahí. Puede tener una longitud de 0 a 999 caracteres.
Fecha/Hora
Hay tres tipos de fecha distintos: Uno es de 10 posiciones en formato MMDDHHmmss, otro es de 4 posiciones en formato AAMM (útil para fechas de expiración de tarjetas de crédito por ejemplo), otro es de 4 posiciones en formato MMDD. Otro es de 6 posiciones y contiene solamente la hora en formato HHmmss
Monto
Es un campo numérico de 12 posiciones y expresa una cantidad monetaria en centavos. Por ejemplo $15.00 se expresa como 000000001500.

Tipos de mensaje

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

Codificación

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.

Encabezado ISO

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.

Ejemplos

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>

Ejemplo 1

Petición:
ISO0150000500200B23A800128A180180000000014000000650000000000002050042813271000057813271004280428042803456174591700012340000=000000230579A1B2C3D4E5 SOLABTEST TEST-3 DF MX010abcdefghij484012B456PRO1+000013 1234P0399904ABCD
CampoValor
Encabezado ISOISO015000050
Tipo de mensaje0200
Bitmap PrimarioB23A800128A18018
Bitmap secundario0000000014000000
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)
32456
354591700012340000=
37 (referencia)000000230579
41 (term id)A1B2C3D4E5
43SOLABTEST TEST-3 DF MX
48abcdefghij
49 (currency)484
60B456PRO1+000
61 1234P
100999
102ABCD

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.
CampoValor
Encabezado ISOISO015000055
Tipo de mensaje0210
Bitmap PrimarioB23A80012EA18018
Bitmap secundario0400004014000004
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)
32456
354591700012340000=
37 (referencia)000000230579
38 (num. confirmacion)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.