ISO-8583 message handling is at the core of jPOS functionality. It involves creating, parsing, and manipulating ISO-8583 messages. The key components in this process are the ISO Factory, Message Factory, and Generic Packager.
The ISOFactory is a utility class in jPOS that helps create ISO components such as channels, packagers, and fields. While it's not directly used for message handling, it's an important part of the jPOS ecosystem.
Example usage:
import org.jpos.iso.ISOFactory;
import org.jpos.iso.channel.NACChannel;
import org.jpos.iso.packager.ISO87APackager;
public class ISOFactoryExample {
public void demonstrateISOFactory() throws Exception {
// Create a channel
NACChannel channel = (NACChannel) ISOFactory.newChannel("org.jpos.iso.channel.NACChannel", "localhost:8000");
// Create a packager
ISO87APackager packager = (ISO87APackager) ISOFactory.newPackager("org.jpos.iso.packager.ISO87APackager", "");
// Create a field
ISOField field = (ISOField) ISOFactory.newField(2, "4111111111111111");
}
}The MsgFactory is used to create ISO messages based on predefined templates. This is particularly useful when you need to create similar messages repeatedly with slight variations.
Here's an example of how to use MsgFactory:
import org.jpos.iso.ISOException;
import org.jpos.iso.ISOMsg;
import org.jpos.iso.MsgFactory;
import org.jpos.iso.packager.ISO87APackager;
public class MessageFactoryExample {
private MsgFactory msgFactory;
public MessageFactoryExample() throws ISOException {
msgFactory = new MsgFactory();
msgFactory.setPackager(new ISO87APackager());
// Define a template for a purchase transaction
ISOMsg purchaseTemplate = new ISOMsg();
purchaseTemplate.setMTI("0200");
purchaseTemplate.set(3, "000000"); // Processing code for purchase
purchaseTemplate.set(25, "00"); // POS Condition Code
purchaseTemplate.set(41, "12345678"); // Terminal ID
msgFactory.add("purchase", purchaseTemplate);
}
public ISOMsg createPurchaseMessage(String pan, String amount) throws ISOException {
ISOMsg msg = msgFactory.newMsg("purchase");
msg.set(2, pan); // Primary Account Number
msg.set(4, amount); // Transaction Amount
msg.set(7, ISODate.getDateTime(new Date())); // Transmission Date & Time
msg.set(11, String.format("%06d", (int) (Math.random() * 1000000))); // Systems Trace Audit Number
return msg;
}
}The GenericPackager is a flexible packager that can be configured using an XML file. This allows you to define custom message formats without writing Java code.
Here's an example of how to use GenericPackager:
import org.jpos.iso.ISOException;
import org.jpos.iso.ISOMsg;
import org.jpos.iso.packager.GenericPackager;
public class GenericPackagerExample {
private GenericPackager packager;
public GenericPackagerExample() throws ISOException {
packager = new GenericPackager("config/iso87ascii.xml");
}
public byte[] packageMessage(ISOMsg msg) throws ISOException {
return packager.pack(msg);
}
public ISOMsg unpackMessage(byte[] msgData) throws ISOException {
ISOMsg msg = new ISOMsg();
packager.unpack(msg, msgData);
return msg;
}
}The XML configuration file (iso87ascii.xml) might look something like this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE isopackager SYSTEM "genericpackager.dtd">
<isopackager>
<isofield
id="0"
length="4"
name="Message Type Indicator"
class="org.jpos.iso.IFA_NUMERIC"/>
<isofield
id="1"
length="16"
name="Bitmap"
class="org.jpos.iso.IFB_BITMAP"/>
<isofield
id="2"
length="19"
name="Primary Account Number"
class="org.jpos.iso.IFA_LLNUM"/>
<!-- More field definitions... -->
</isopackager>Now, let's create a comprehensive example that uses all these components together:
import org.jpos.iso.ISOException;
import org.jpos.iso.ISOMsg;
import org.jpos.iso.ISOUtil;
import org.jpos.iso.MsgFactory;
import org.jpos.iso.packager.GenericPackager;
import org.jpos.util.LogEvent;
import org.jpos.util.Logger;
import org.jpos.util.SimpleLogListener;
import java.io.IOException;
import java.util.Date;
public class ISO8583MessageHandler {
private final MsgFactory msgFactory;
private final GenericPackager packager;
private final Logger logger;
public ISO8583MessageHandler() throws ISOException, IOException {
// Initialize packager
packager = new GenericPackager("config/iso87ascii.xml");
// Initialize message factory
msgFactory = new MsgFactory();
msgFactory.setPackager(packager);
// Define templates
defineMessageTemplates();
// Initialize logger
logger = new Logger();
logger.addListener(new SimpleLogListener(System.out));
}
private void defineMessageTemplates() throws ISOException {
// Purchase request template
ISOMsg purchaseTemplate = new ISOMsg();
purchaseTemplate.setMTI("0200");
purchaseTemplate.set(3, "000000");
purchaseTemplate.set(25, "00");
purchaseTemplate.set(41, "12345678");
msgFactory.add("purchase", purchaseTemplate);
// Balance inquiry template
ISOMsg balanceTemplate = new ISOMsg();
balanceTemplate.setMTI("0100");
balanceTemplate.set(3, "310000");
balanceTemplate.set(25, "00");
balanceTemplate.set(41, "12345678");
msgFactory.add("balance", balanceTemplate);
}
public ISOMsg createPurchaseMessage(String pan, String amount) throws ISOException {
ISOMsg msg = msgFactory.newMsg("purchase");
msg.set(2, pan);
msg.set(4, amount);
msg.set(7, ISODate.getDateTime(new Date()));
msg.set(11, String.format("%06d", (int) (Math.random() * 1000000)));
return msg;
}
public ISOMsg createBalanceInquiryMessage(String pan) throws ISOException {
ISOMsg msg = msgFactory.newMsg("balance");
msg.set(2, pan);
msg.set(7, ISODate.getDateTime(new Date()));
msg.set(11, String.format("%06d", (int) (Math.random() * 1000000)));
return msg;
}
public byte[] packageMessage(ISOMsg msg) throws ISOException {
return packager.pack(msg);
}
public ISOMsg unpackMessage(byte[] msgData) throws ISOException {
ISOMsg msg = new ISOMsg();
packager.unpack(msg, msgData);
return msg;
}
public void logMessage(ISOMsg msg, String direction) {
LogEvent ev = new LogEvent(this, "iso-message");
ev.addMessage(direction);
ev.addMessage(msg);
logger.log(ev);
}
public static void main(String[] args) {
try {
ISO8583MessageHandler handler = new ISO8583MessageHandler();
// Create and log a purchase message
ISOMsg purchaseMsg = handler.createPurchaseMessage("4111111111111111", "000000010000");
handler.logMessage(purchaseMsg, "OUTGOING");
// Package the message
byte[] packedMsg = handler.packageMessage(purchaseMsg);
System.out.println("Packed message: " + ISOUtil.hexdump(packedMsg));
// Unpack the message
ISOMsg unpackedMsg = handler.unpackMessage(packedMsg);
handler.logMessage(unpackedMsg, "INCOMING (unpacked)");
// Create and log a balance inquiry message
ISOMsg balanceMsg = handler.createBalanceInquiryMessage("4111111111111111");
handler.logMessage(balanceMsg, "OUTGOING");
} catch (Exception e) {
e.printStackTrace();
}
}
}This comprehensive example demonstrates:
- Initializing the
GenericPackagerwith an XML configuration file. - Setting up a
MsgFactorywith predefined templates for different transaction types. - Creating purchase and balance inquiry messages using the templates.
- Packaging and unpackaging messages.
- Logging messages for debugging purposes.
This implementation provides a solid foundation for handling ISO-8583 messages in a jPOS-based application. It can be easily extended to handle more message types and integrated into a larger transaction processing system.