ISO-8583 en Java

Para inaugurar mi blog, hablaré de un proyecto de software libre que tengo: j8583, también conocido como Java-ISO8583. Es una implementación semi-abstracta del protocolo transaccional de comunicación ISO-8583, que puede ser algo complicado y/o tedioso de implementar. UPDATE: Aquí he puesto una breve descripción en español.

ISO8583 es un protocolo transaccional de comunicación, muy utilizado en bancos, también se usa con puntos de venta (las terminales de tarjeta de crédito por ejemplo), y últimamente también se está usando para transaccionar con carriers de telefonía celular. No voy a entrar a detalle en el protocolo como tal. Se puede obtener (pagando) del sitio de ISO.

Para poder utilizar esta librería, se requiere conocer el protocolo en sí. Tiene licencia LGPL, de modo que se puede usar en aplicaciones comerciales cerradas; si hacen una aplicación que se redistribuye (software que venden, etc) solamente deben entregar los fuentes de la librería, junto con cualquier modificación que le hagan.

El paquete incluye ejemplos de una implementación de un cliente que envía y recibe mensajes de ISO8583, así como un server que recibe conexiones y atiende a varios clientes usando ISO8583. Se puede usar de modo binario o ASCII (lo más común).

La página del proyecto es http://github.com/chochos/j8583 y por supuesto http://j8583.sourceforge.net/

La documentación y la página las puse en inglés para no excluir a gente de otros países que puedan usar el proyecto. No he tenido tiempo de traducir nada (los javadoc de hecho no sabría cómo generarlos en español, fuera de tomar los HTML generados y traducirlos). La configuración de la fábrica de mensajes (la parte central de la librería) es bastante sencilla, a través de un archivo XML donde se definen plantillas para los tipos de mensaje que se van a crear, así como definiciones de los mensajes que se van a leer, indicando los campos esperados, con su longitud y tipo. De los campos indicados en las definiciones de respuestas, solamente se leen los que se indiquen en el bitmap de una respuesta. De esta manera, leer los mensajes ya es algo automático, todo el código para parseo de respuestas está en la fábrica de mensajes, no es necesario implementar algo adicional.

Los mensajes creados por la fábrica de mensajes son editables, pueden modificarse, agregarse o quitarse campos. La idea es que la fábrica genere nuevos mensajes ya con todos los valores fijos para el tipo de mensaje, y que solamente se tengan que asignar los valores que cambian. Incluso los dos valores que generalmente cambian, los campos 7 (fecha) y 11 (trace), se pueden asignar por la fábrica, poniendo la fecha actual a cada mensaje recién creado y usando un TraceNumberGenerator (una interfaz cuya implementación pueden proveer ustedes) para asignarle un trace en el campo 11 a cada mensaje generado.

Espero les sea de utilidad. Cualquier duda me pueden contactar directamente en SourceForge, registrando cualquier defecto que encuentren y poniendo ahí sus dudas.

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

respuestas

footballer: Eso que mencionas ya es una aplicación, j8583 es únicamente la biblioteca para manejo de ISO8583. No tengo algo así hecho porque hay demasiadas variables (la autenticación, los datos a recibir, manejo de peticiones repetidas, etc etc). Es un desarrollo a la medida.

Lucho: No entendí en dónde aparece esa petición de HTTP pero pues ese URL es del DTD que usa j8583 para parsear un archivo de configuración de XML. Probablemente alguien está usando j8583 y su parser de XML no guarda el DTD en cache local sino que siempre va y lo busca (cosa que es realmente innecesaria porque el DTD viene dentro del JAR de j8583).

Imagen de footballer

Post XML

Gracias por la respuesta.
Saludos.

Imagen de Lucho Com

Agradecido con tu apoyo, la

Agradecido con tu apoyo, la peticion HTTP la hace el dispositivo GPS por medio de una SIMCard de red celular y de ahi le manda el posicionamiento a un servidor del cliente donde se almacena esta info en una base de datos, podrias darme un poco mas de detalles para entender que es el archivo o fichero DTD y el termio parsear , si intento accesar a la direccion desde mi buscador explorer de internet me sale un error al hacer la busqueda, esto me indica que adicional de que intenta hacer la busqueda del DTD no lo encuentra por el error en al pagina.

Imagen de ezamudio

ufff

Esto no es algo específico de j8583. No lo inventé yo. Es cosa de XML.

Sí sabes lo que es parsear, lo hiciste con la petición HTTP. Búscalo en un diccionario de pochismos informáticos (parse en inglés).

El DTD es una guía para un parser de XML. Indica los tags y atributos que puede contener el documento, y en qué orden pueden venir. j8583 puede leer un archivo XML para configurar los tipos de mensajes que debe saber crear y leer. Los archivos XML en su encabezado tienen un texto indicando el DTD que se puede usar para parsear los datos.

Probablemente el dispositivo GPS usa j8583 y y lo configura con un archivo XML. El parser de XML que usan, va por el DTD al URL indicado (http://j8583.sourceforge.net/j8583.dtd), pero si lo pides por IP no funciona, porque j8583.sourceforge.net es un host virtual.

Espero te sirva esta info. Esto realmente no es una bronca de j8583 sino de la manera en que el parser de XML que usan está funcionando. La biblioteca incluye el DTD, por lo que realmente no sería necesario que vayan por él a internet (ni siquiera es necesario que realmente lo mencionen en el su archivo XML, podrían saltárselo).

Imagen de Lucho Com

Bueno ya comprendo mucho mas

Bueno ya comprendo mucho mas el problema, para evitar que al buscar el DTD apunte al ip entonces se deberia hacer cambios en alguna cabecera del protocolo, verificando la captura encontre el mensaje con la configuracion de valores te copio a ver si con esto por lo menos se decifra que esta enviando:

GET /j8583.dtd HTTP/1.1

User-Agent: Java/1.6.0_22

Host: j8583.sourceforge.net

Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2

Connection: keep-alive

HTTP/1.1 200 OK

Server: Apache/2.2.3 (CentOS)

Last-Modified: Tue, 07 Dec 2010 16:40:17 GMT

ETag: "213-496d4a8dafe40"

Accept-Ranges: bytes

Cache-Control: max-age=172800

Expires: Sat, 06 Aug 2011 17:45:15 GMT

Content-Type: text/plain

Content-Length: 531

Date: Thu, 04 Aug 2011 17:45:15 GMT

X-Varnish: 318240399

Age: 0

Via: 1.1 varnish

Connection: keep-alive

Esta es una captura que ya hice un par de semanas atras, buscando la causa de porque se comunicaba con ese Ip en especifico

Imagen de ezamudio

no esta enviando

no estás enviando nada, eso que me muestras es una petición HTTP para solicitar el j8583.dtd desde una aplicación Java.

Imagen de Lucho Com

Uff disculpame me hizo falta

Uff disculpame me hizo falta lo principa, esta es la continuacion del mensaje que te enviel:

Imagen de clon

Campos LLLVAR Encriptados

Hola Enrique,

He estado probando el j8583 y ha sido excelente, no me puedo quejar.
Quisiera saber si me puedes dar luz con respecto al campo 60, 61 y 62 ya que como es bien sabido estos son campos ASCII de hasta 999 caracteres. Ahora, sobre el desarrollo que debo implementar debo enviar estos campos encriptados en 3DES o DESede y enviarlos en binario (Hex) incluyendo la longitud. Es prácticamente el mismo formato del bitmap pero dentro de los campos 60 al 63
¿Que recomendación puedo recibir al respecto?

Agradezco tu ayuda

Imagen de ezamudio

customfield

Haz un CustomField que codifique tus datos como texto hex. Pero si usas LLLVAR entonces sólamente podrás mandar hasta 499 caracteres binarios porque al codificarlos como hex van a medir 998 caracteres.

O puedes usar Base64, eso solamente "infla" los datos en un 25 a 30% de modo que podrías enviar unos 700 bytes en cada campo, cuidando que ya codificados no pasen de 999.

La longitud no la puedes cifrar a menos que la repitas porque el parser necesita saber cuántos bytes leer, antes de descifrar ningún dato (ISO8583 no va a descifrar tus datos, eso es a nivel aplicación).

Imagen de clon

CustomField

Enrique, gracias por tu sugerencia.
Estoy revisando el ejemplo de customfield que viene en la versión 1.5.2, aunque aun no me queda muy claro como funciona. De nuevo gracias.

Imagen de Lucho Com

Que tal eZamudio de ante

Que tal eZamudio de ante mano las gracias por la explicacion breve de estos dias ya que efectivamente el cliente dentro de sus equipos GPS tenia una aplicacion java que hacia comunicacion con el ip que te indique y me ayudo para descartar de que fuera problema de la compañia telefonica ahora queda en manos de otra persona verificar las configuraciones.

Gracias,
Saludos desde ciudad de Panamá

Imagen de clon

Header

Hola de nuevo Enrique,
He hecho funcionar el customfield, aunque tengo un problema, en el header. El mensaje lo estoy enviando en codificación binaria, y el encabezado debe ir algo así:
0x81,0x85,0x8D,0x05,0x40

Ya que el setIsoHeader debe ser String, hago lo siguiente:

String s = new String(new char[] {0x81,0x85,0x8D,0x05,0x40});
req.setIsoHeader(s);

pero no funciona de forma correcta, al momento de enviarlo, lo reciben así: 3f 3f 3f 05 40 (codificado en ASCII : ???.@ )
¿Hay alguna forma para corregir esto? ya que solo pasa con char mayores a 0x79. Si el arreglo char lo cambio a byte [] pasa exactamente lo mismo

Gracias por tu ayuda.

Imagen de ezamudio

byte

Los bytes en Java son con signo. Si los quieren leer como sin signo, deben leer uno por uno, con el método InputStream.read() que devuelve un int, ese método es así para que devuelva un valor de 0 a 255 (en vez de un byte que es de -128 a 127). O puedes hacerle a cada byte un bitwise and contra 0xff:

byte b=(byte)0x81; //esto te da -127
int x= b&0xff; //esto te da 129
Imagen de macaruchi

Ejemplos

Hola!
Me baje esta libreria y estoy tratando de usarla para evitrar todo lo demas pero es imposible ni se como se empieza siquiera. No existe algun ejemplo sencillo donde podamos ver la construccion del mensaje?

Me he leido toda la documentacion del ISO8583 pero lo que no se es todo lo que tengo en la cabeza como poderlo aplicar usando esta paquete.
Alguna idea o ayuda vendria bien

Edwin

Imagen de ezamudio

ejemplos

Si bajas los fuentes, hay unos ejemplos. No es complicado usarla, pero necesitas saber acerca del protocolo para saber lo que estás haciendo. Todo es a través de la MessageFactory. Una vez que tienes una configurada, puedes crear un mensaje nuevo y ponerle datos:

IsoMessage m = messageFactory.newMessage(0x200);
m.setValue(4, new BigDecimal(155), IsoType.AMOUNT, 0);
m.setValue(7, new Date(), IsoType.DATE10, 0);
m.setValue(11, 1, IsoType.NUMERIC, 6);
m.setValue(43, "blabla", IsoType.ALPHA, 40);
m.setValue(48, "bleble", IsoType.LLVAR, 0);

Ese código al final te deja un mensaje tipo 0x200 con los campos 4, 7, 11, 43 y 48. Si le pides m.writeData() obtendrás la trama como un arreglo de bytes (ahí depende si le pediste que fuera binario o ASCII, el default es ASCII, y en ese momento es cuando genera el bitmap y codifica los campos segun su tipo,etc).

Para parsear un mensaje, tienes que leerlo tú de donde venga y cuando ya tengas un arreglo de bytes que quieras parsear como mensaje, se lo pasas a la MessageFactory, que debe tener configurada una plantilla para ese tipo de mensaje. Con eso obtendrás un IsoMessage y puedes pedirle los datos que necesites con los métodos getField, hasField, getObjectValue, o getAt y apply (estos dos últimos son para facilitar la sintaxis en Groovy Scala, respectivamente).

Imagen de macaruchi

Estoy viendo lo que me dices

Estoy viendo lo que me dices y ahora estoy tratando de entender el Cliente.java que esta en los fuentes para generar la trama. El config.xml veo que hay template declarados de varios tipos de mensajes supongo que esto se usa para definir cual es la configuracion del mensaje que se enviara. Estoy tratando de generar una trama para un sistema del cual me enviaron la trama pero no la entiendo mucho
--Esto es lo que supuestamente llega

0000 0049 0200 7024 4580 00C0 8004 1654
22** **** **62 9000 3000 0000 0001 2500
0000 8111 0954 1100 1200 0608 3132 3737
3638 3539 3334 3930 3030 3030 3030 3030
2020 2002 1400 0630 3030 3030 31
==
EL mensaje ISO en Ascii es este

*************** INCOMING MESSAGE ***************
ISO 8583 0200 S
F2 Primary Acc. Num 5422********6290
F3 Processing Code 003000
F4 Amount of Transaction 125.00
F11 System Trace 000081
F14 Expiration date 1109
F18 Merchant Category 5411
F22 POS Entry Mode 012
F24 Network International ID 006
F25 POS condition code 08
F41 Terminal ID 12776859
F42 Card acceptor or Merchant # 349000000000
F49 Transaction Currency code 214
F62 Invoice/ECR Ref # 000001

Esto es lo que necesito generar. Debo en el config hacer la declaracion de este mensaje?

Imagen de ezamudio

config

La configuracion para la MessageFactory tiene dos partes: una son los templates, que sirven para que cuando le pidas un mensaje a la fabrica, si tiene template para el tipo solicitado, te devuelve un mensaje que ya trae los campos definidos en el template.

Y la otra parte es la guia para el parser, donde tienes que definir el tipo de mensaje y los campos esperados. La fabrica solamente puede parsear los mensajes que tengan guia (la guia es por tipo) y esa guia debe contener TODOS los campos que esperas recibir. Si el mensaje no trae uno de los campos de la guia, no pasa nada, pero si la guia no tiene definido un campo que venga en el mensaje, no sabe como parsearlo y marcar error.

A j8583 no le importa el nombre del campo, es decir no le importa eso de que el campo 18 es "merchant category"; solamente defines que el campo 18 es ALPHA de 4 o NUMERIC de 4 o LLVAR o lo que sea.

Imagen de macaruchi

Guia

OK, enetendi la parte de MessageFactory y hasta cierto punto estoy trabajando con ella lo que no se donde definir es la guia para el parse.st
En el config.xml dices que en el mensaje de respuesta no pones todos los campos porque ya van del request y que solo usas eso pero como se sabe que ese mensaje es la respuesta al mensaje de request 200, por ejemplo, este es el mensaje 210 definido en el config.

Segun lo que dices puedo usar MessageFactory sin tener que crear un template en mensaje? supongo que es mas recomendable usar el template ?

Estoy usando el example.java ,Cliente.java y Server.java para probar las funcionalidades

Imagen de ezamudio

Parsear, crear

Parsear mensajes es una cosa, crearlos es otra. Crear mensajes es cuando tú haces un mensaje y le pones todos los datos, con la intención de enviarlo a otro sistema. Parsear mensajes es cuando recibiste una trama ISO8583 de otro sistema (o de donde sea) y la quieres convertir en un IsoMessage.

No puedes parsear una trama para obtener un IsoMessage si no tienes una guía para el tipo de mensaje que recibiste.

Puedes usar MessageFactory sin templates; los templates son para crear mensajes, pero si no tienes un template para un cierto tipo de mensaje no pasa nada, la MessageFactory te da un mensaje en blanco, sólo con dos campos ya fijados cuando mucho, según la hayas configurado: el campo 11 ya con un trace, si le configuraste un TraceGenerator, y el campo 7 con la fecha, si le indicaste que le ponga fecha a los mensajes nuevos.

De lo de la respuesta, lo que pasa es que MessageFactory tiene también un método createResponse, que crea un mensaje de manera similar a newMessage pero luego le copia los campos que vengan del mensaje que le pasas como parámetro, y además le cambia el tipo sumándole 16 para que si por ejemplo le das un 0200 te devuelva un 0210.

La documentación de toda la biblioteca está en línea, en inglés y en español, además del API doc (sólo en inglés) y por si fuera poco, tienes el código fuente a tu disposición.

Field 127

Hi Henry

thanks for this great site and great library. so far by following your comments when answering others people questions i have been able to configure it correctly i can receive msg like 0800 and respond 0810.

My problem other messages have private field 127, i want to decode and process this field but i dont have a clue , i have included it in parse guide a

<field num="127" type="LLLVAR" />

ct 14, 2011 6:37:33 PM isoExample.Server$Processor run
SEVERE: Parsing incoming message
java.text.ParseException: Insufficient data for LLLVAR field, pos 308
at com.solab.iso8583.parse.FieldParseInfo.parse(FieldParseInfo.java:108)
at com.solab.iso8583.MessageFactory.parseMessage(MessageFactory.java:364)
at isoExample.Server$Processor.run(Server.java:101)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

plz shade some light

Imagen de ezamudio

support

ppitta,

you can use the help forum in SourceForge for this kind of questions.

I have answered your question in a new topic in that forum.

Nuevo y necesito ayuda URGENTEMENTE!!!

Bueno primero que nada, felicidaes ezamudio por tus aportes... son EXCELENTES. Segundo y al grano, he descargado tu project de ejemplo para poder ver como funciona y poder entender mejor el manejo de mensajes con el j8583, me puedes ayudar a hechar a andar tu project...

Imagen de ezamudio

Guía

Ya viste la página oficial? Ahí viene la guía de uso y bastante información del proyecto.

Si

claro ya cheque la pagina oficial, pero no se ni por donde comenzar, soy nuevo en esto y pues honestamente ando perdido, me puedes ayudar???

Imagen de ezamudio

depende

Depende qué tan perdido andes, y a qué te refieres con "esto" cuando dices "soy nuevo en esto".

Ok

Ok, tienes razon mira, ya tengo tu project montado en mi Eclipse Indigo, primero no se si sea necesario un servidor de aplicaciones para poder realizar el test y segundo no se cual de las carpetas es la que trae el core del proyecto, es decir, cual de ellas tengo que ejecutar para poder ver el funcionamiento de un mensaje en formato ISO8583... Esto porque veo varias carpetas con las mismas clases, por ejemplo estoy tratando de entender si la carpeta "eclipse-project" es para jdk posteriores a 1.4 y la carpeta "eclipse-project-jdk14" sea especifica para puro jdk 1.4 o cual es la diferencia entre estas dos y la carpeta "j8583". Ahora si me explico??? XD

Imagen de ezamudio

no

No necesitas servidor de aplicaciones. Los ejemplos son simples programitas de JavaSE. No sé cuáles ejemplos bajaste o qué hayas bajado.

Si bajaste los fuentes del proyecto, en src/test hay pruebas unitarias, algunas de las cuales son para parsear mensajes a partir de archivos de texto.

Los ejemplos realmente son dos programas: Uno que abre un ServerSocket para recibir conexiones, esperando recibir tramas y contestarlas, y otro programa es un cliente, que se conecta al programa servidor para enviarle unas tramas y leer las respuestas.

Las eclipse-project son carpetas obsoletas, hace mucho que no toco ese código. El fuente del proyecto está en j8583, la carpeta que trae el archivo build.gradle. La de jdk14 era para Java 1.4 o inferior, pero ya hace tiempo que dejé de actualizarla, la única diferencia es que no trae generics, pero dado que Java 1.4 ya es completamente obsoleto y Java 5 ya no es nada nuevo, dejé ambas versiones y copié la de eclipse-project a la carpeta j8583 que es donde trabajo desde hace tiempo.

Sin embargo, los ejemplos de eclipse-project/src/j8583/example todavía pueden estar vigentes, aunque para compilarlos seguramente hay que mover varias cosas. Te recomiendo crear un nuevo proyecto que tenga como referencia el j8583 más actual (ya sea el proyecto o el puro jar de la versión 1.5.4) y copies a tu proyecto las clases de eclipse-project/src/j8583/example.

Algun dia que tenga tiempo haré un proyecto separado con los puros ejemplos, que se pueda compilar separado del principal. O tal vez meta los ejemplos es un sourceSet separado dentro del mismo j8583 y que se compilen y ejecuten con alguna tarea especial del script de Gradle (por estas indecisiones es que no he hecho nada con los ejemplos desde hace tiempo).

Perfecto

Perfecto y muchas gracias por todo, en serio GRACIAS!!! Dejame lidiar un rato con esto, XD Saludos y que tengas un Excelente Fin de Año

Ayuda!!!

Que tal ezamudio, tengo este error, me puedes orientar por donde esta mas o menos mi error: [Fatal Error] j8583.dtd:1:3: The markup declarations contained or pointed to by the document type declaration must be well-formed, la estructura del DTD la baje de tu repositorio

Imagen de ezamudio

NPI

El DTD no tiene broncas, no ha cambiado en años. Y de hecho la versión más reciente (no recurdo si ya lo subí como release o sólo está en fuentes) usa el DTD que viene en el jar, no va al server por él.

Tal vez hiciste copy-paste o algo que dañó el texto?

DTD

Mira esto es lo que contiene el DTD:

ya lo valide, varias ocasiones y pues ni asi furula... jejeje

Este es el error.

Mira este es el error, que me esta enviando:

18:54:37,890 INFO [main] Main - javax.xml.transform.TransformerFactory=null
18:54:37,906 INFO [main] Main - java.endorsed.dirs=C:\Program Files\Java\jre6\lib\endorsed
18:54:37,906 INFO [main] Main - launchFile: C:\MPEL_Workspace\.metadata\.plugins\org.eclipse.wst.xsl.jaxp.launching\launch\launch.xml
[Fatal Error] j8583.dtd:1:3: The markup declarations contained or pointed to by the document type declaration must be well-formed.
18:54:38,828 FATAL [main] Main - getAssociatedStylesheets failed
org.eclipse.wst.xsl.jaxp.debug.invoker.TransformationException: getAssociatedStylesheets failed
at org.eclipse.wst.xsl.jaxp.debug.invoker.internal.JAXPSAXProcessorInvoker.transform(JAXPSAXProcessorInvoker.java:225)
at org.eclipse.wst.xsl.jaxp.debug.invoker.internal.JAXPSAXProcessorInvoker.transform(JAXPSAXProcessorInvoker.java:186)
at org.eclipse.wst.xsl.jaxp.debug.invoker.internal.Main.main(Main.java:73)
Caused by: javax.xml.transform.TransformerConfigurationException: getAssociatedStylesheets failed
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.getAssociatedStylesheet(Unknown Source)
at org.eclipse.wst.xsl.jaxp.debug.invoker.internal.JAXPSAXProcessorInvoker.transform(JAXPSAXProcessorInvoker.java:207)
... 2 more
Caused by: org.xml.sax.SAXParseException: The markup declarations contained or pointed to by the document type declaration must be well-formed.
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
... 4 more

Imagen de ezamudio

no sé

nunca he visto ese error, no me ha pasado ni he recibido reportes de que a alguien más le ocurra

Cliente y servidor para probar el j8583

Que tal Ezamudio, es interesante tu proyecto, en la primer pagina de posts de este tema, note que haces referencia a las clases cliente y servidor entre otras, contenidas en los archivos de descarga, he descargado los fuentes de la ultima version "j8583-1.5.4-sources.jar", no veo las clases que mencionas, estan en alguna version en particular? Saludos.

Imagen de ezamudio

son ejemplos

Son ejemplos, el proyecto ha cambiado desde que publiqué este post y ya no vienen las clases de ejemplo dentro de los fuentes. Pero si buscas entre las versiones viejas por ahí está un zip con los ejemplos, que además siguen en el repositorio y puedes descargarlos directamente de ahí.

Cliente y Server son ejemplos que usan java.io y ChannelClient/ChannelServer usan java.nio.

Error

Que tal ezamudio, me puedes ayudar con este error:
Exception in thread "main" java.io.FileNotFoundException: \tmp\iso.bin (The system cannot find the path specified)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.(FileOutputStream.java:194)
at java.io.FileOutputStream.(FileOutputStream.java:84)
at j8583.Example.main(Example.java:77)
No entiendo si debo tener alguna carpeta "tmp" en la cual se va a depositar el iso.bin o que esta sucediendo, estuve revisando la estructura de carpetas del projecto j8583 y en ninguna lado veo alguna carpeta llamada "tmp". De antemano muchas Gracias y recibe un saludo.

Consulta

Hola ezamudio soy de Argentina, te quiero hacer una consulta en privado si puede ser. Tenes algún mail para consultarte via mensajería o skype.
Espero tu respuesta. Saludos

Imagen de ezamudio

tmp

furcio94: Supongo que sí, seguramente el ejemplo escribe en /tmp. Si lo corres en windows es probable que no funcione, modifica el código para que sea C:\temp o algo así.

mauryceli: No doy asesoría privada para j8583 a menos que sea trabajo pagado. Si quieres poner tu duda aquí o mejor aun en sf.net/projects/j8583 la contestaré cuando pueda.

Consulta

Es la idea para trabajo pago, pero quiero consultarte en privado

Consulta

Podremos hablar en privado asi te cuento lo que necesito.

Imagen de ezamudio

dónde

Dime a dónde te contacto

Consulta

Duda

Hola ezamudio, dentro del src del projecto no existe algun ejemplo en el cual el socket se conecte al server, reciba de esté un mensaje con el standar iso8583, transforme el mensaje en la definicion que esta en el XML y posteriormente lo convierta en un objeto request para un webService Pago, por decir... Lo que pasa es que estuve Revisando el Example.java que viene dentro del test del project y me queda claro que lee de un archivo txt. el mensaje string, posteriormente lo parsea en el Template definido en el XML, pero no lo deja en ningun lado, es decir simplemente lo pinta en pantalla. Lo que yo necesito es que lo deje en algun lado para poder generar un Request para un webService, todo esto en base a los campos definidos en el Template del XML, Lo que pasa es que estoy trabajando en un proyecto que utiliza este estandar y pues se me ha complicado mucho. Gracias pos tu ayuda

Imagen de ezamudio

ref

Error

Exception in thread "j8583-client" java.lang.NullPointerException
at j8583.Client.run(Client.java:73)
at java.lang.Thread.run(Thread.java:662)

me puedes ayudar con este error

Thanks

Gracias ya quedo resuelto y fue una tonteria XD

Hola

Una pregunta ezamudio, los tags Template deben ser iguales a los tags Parse, es decir, mi tag de peticion ( < template type="0200" > ) debe ser igual al tag ( < parse type="0200" > ), porque me esta marcando un NullPointerexception:

Exception in thread "j8583-client" java.lang.NullPointerException
at j8583.Client.run(Client.java:80)
at java.lang.Thread.run(Thread.java:662)

De antemano gracias por tu ayuda, de verdad me ha servido de mucho =D

Imagen de ezamudio

no son iguales

Los template son para ponerle campos predefinidos a los tipos de mensaje que quieres crear. Los parse son para indicarle a la MessageFactory qué campos esperar y de qué tipo, por cada tipo de mensaje.

Por lo tanto, en los template van valores, en los parse nada más definiciones. Eso está en la página oficial: http://j8583.sourceforge.net/es/xmlconf.html

Campo: 13, Numerico, Longitud: 4 vs Tipo 4

Hola de nuevo ezamudio,

Mi duda es la siguiente que sucede si en las especificaciones que me mando el cliente para los mensajes iso en el campo 13 que es la siguiente:

Campo 13. Local Transaction Date
Formato: Numerico, Fijo, Longitud 4
Descripción: Día Local de la Transacción
Comentarios / Posibles Valores: MMDD Fecha en que ED ejecuta la petición. En caso de time-out del lado de Entidad Destino, EGLOBAL enviará la fecha en que responde la transacción a BNMR.

y yo, defino en mi xml lo siguiente:

< parse type="0210" >
...
...
< field num="13" type="DATE4" />
...
...
< / parse >

Es decir, no pongo < field num="13" type="Numeric" length="4" />, porque se supone que el mensaje que me va a enviar el cliente viene definido como: Numerico, Fijo, Longitud 4.

La pregunta es, causa conflicto???
Esto es solo duda, porque veo que DATE4 esta diseñado para contener valores con formato: MMDD y longitud: 4

Imagen de ezamudio

DATE4

Hay dos tipos de fecha de 4 dígitos: DATE4 y DATE_EXP, pero DATE_EXP es mmaa o aamm algo así (como las fechas de expiración de las tarjetas de crédito).

Es correcto que cuando usas DATE4 ya no necesitas poner la longitud porque ese tipo de dato siempre es de 4 dígitos. La diferencia entre usar DATE4 y NUMERIC de 4 es que DATE4 te va a devolver un java.util.Date cuando pidas el valor del campo, mientras que NUMERIC de 4 te devolvería un int.