Skip to content

Latest commit

 

History

History
251 lines (198 loc) · 8.4 KB

File metadata and controls

251 lines (198 loc) · 8.4 KB

2. ISO-8583 Message Handling

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.

2.1 ISO Factory

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");
    }
}

2.2 Message Factory

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;
    }
}

2.3 Generic Packager

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>

2.4 Putting It All Together

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:

  1. Initializing the GenericPackager with an XML configuration file.
  2. Setting up a MsgFactory with predefined templates for different transaction types.
  3. Creating purchase and balance inquiry messages using the templates.
  4. Packaging and unpackaging messages.
  5. 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.