Creating ISO8583 Server using jPOS Q2
Creating ISO8583 Server using jPOS Q2 is as simple as Creating ISO8583 Client using jPOS Q2, all we need is to create xml configuration for the QServer and create IsoRequestListener. There are a bunch of properties available to configure a jPOS QServer, you can take a look at the class directly. This post will only cover the basic configuration to create a Server.
Below diagram describes the flow for ISO Server to receive and send the response message.
- ISO Server will listen to the configured port and accept incoming connections.
- ISO Channel will get the message from the stream based on the specification. Here we are using ASCIIChannel.
- ISORequestListener.process() method will be invoked after the message successfully unpacked.
- This is where our logic to process the message starts.
- Sending response messages back to the clients by invoking ISOSource.send() method.
Here it is configuration xml for QServer.
<?xml version="1.0" ?>
<server name="test-server" class="org.jpos.q2.iso.QServer" logger="Q2">
<attr name="port" type="java.lang.Integer">7080</attr>
<channel class="org.jpos.iso.channel.ASCIIChannel" logger="Q2"
packager="org.jpos.iso.packager.ISO87APackager">
</channel>
<request-listener
class="com.codeinvocation.middleware.jpos.MiddlewareRequestListener" logger="Q2">
</request-listener>
</server>
Configuration above is basic QServer configuration, to Create ISO8583 Server using jPOS Q2.
- Server Name: Unique Server Name used to get ISOServer or QServer instances programmatically when needed.
- Server Class: QServer Class reference
- Server Logger: Logger name configuration (see 00_logger.xml)
- Port Attribute: Listened port number
- Channel Class: ISOChannel implementation class.
- Channel Logger: Logger name configuration (see 00_logger.xml), set this if you want to print received and sent messages.
- Channel Packager: ISO Message Specifications.
- Request Listener: ISORequestListener implementations. We can set multiple request listeners on a single ISO Server.
- Request Listener Logger: Logger name configuration (see 00_logger.xml), set this configuration to set the logger on the ISORequestListener implementations.
Here is the implementation of ISORequestListener:
public class MiddlewareRequestListener implements ISORequestListener, LogSource {
private Logger logger;
private String realm;
@Override
public boolean process(ISOSource source, ISOMsg requestMsg) {
LogEvent evt = new LogEvent(this, realm);
try {
IMessageHandler messageHandler = getMessageHandler(requestMsg);
ISOMsg responseMsg = messageHandler.handle(requestMsg, evt);
if (responseMsg != null) {
source.send(responseMsg);
}
} catch (Exception e) {
evt.addMessage(e);
} finally {
Logger.log(evt);
}
return false;
}
private IMessageHandler getMessageHandler(ISOMsg requestMsg) throws Exception {
IMessageHandler messageHandler = null;
String type = requestMsg.getMTI();
String processingCode = requestMsg.getString(3);
String networkManagementCode = requestMsg.getString(70);
if (MTI.NETWORK_MANAGEMENT.getString().equals(type)) {
if (NetworkManagementCode.ECHO.val.equals(networkManagementCode)) {
messageHandler = EchoMessageHandler.getInstance();
}
else if (NetworkManagementCode.SIGN_ON.val.equals(networkManagementCode)) {
// TODO Sign On
}
else if (NetworkManagementCode.SIGN_OFF.val.equals(networkManagementCode)) {
// TODO Sign Off
}
}
else if (MTI.TRANSACTIONAL.getString().equals(type)) {
if (ProcessingCode.INQUIRY.val.equals(processingCode)) {
// TODO Inquiry
}
if (ProcessingCode.PAYMENT.val.equals(processingCode)) {
// TODO Payment
}
}
else if (MTI.ADVICE.getString().equals(type)) {
// TODO Payment Advice
}
else if (MTI.ADVICE_REPEAT.getString().equals(type)) {
// TODO Payment Advice Repeat
}
else if (MTI.REVERSE.getString().equals(type)) {
// TODO Payment Reversal
}
return messageHandler;
}
@Override
public void setLogger(Logger logger, String realm) {
this.logger = logger;
this.realm = realm;
}
@Override
public String getRealm() {
return this.realm;
}
@Override
public Logger getLogger() {
return this.logger;
}
}
Like my previous ISO Server tutorials using Netty and Spring Integrations, we are going to handle echo messages and send the responses with response code success.
Testing results:
Q2 ISO Server Log:
<log realm="test-server.server.session/127.0.0.1:37274" at="2025-04-13T18:48:29.573763858">
<session-start/>
</log>
<log realm="channel/127.0.0.1:37274" at="2025-04-13T18:48:30.031928959" lifespan="457ms">
<receive>
<isomsg direction="incoming">
<!-- org.jpos.iso.packager.ISO87APackager -->
<field id="0" value="0800"/>
<field id="7" value="0413184829"/>
<field id="11" value="000001"/>
<field id="41" value="12345678"/>
<field id="70" value="301"/>
</isomsg>
</receive>
</log>
<log realm="channel/127.0.0.1:37274" at="2025-04-13T18:48:30.034387698">
<send>
<isomsg direction="outgoing">
<!-- org.jpos.iso.packager.ISO87APackager -->
<field id="0" value="0810"/>
<field id="7" value="0413184829"/>
<field id="11" value="000001"/>
<field id="39" value="00"/>
<field id="41" value="12345678"/>
<field id="70" value="301"/>
</isomsg>
</send>
</log>
<log realm="request-listener" at="2025-04-13T18:48:30.034753386" lifespan="2ms">
<request-listener>
Echo Handler Start
Echo Handler Done
</request-listener>
</log>
<log realm="channel/127.0.0.1:37274" at="2025-04-13T18:48:30.063068817" lifespan="28ms">
<receive>
<peer-disconnect/>
</receive>
</log>
<log realm="test-server.server.session/127.0.0.1:37274" at="2025-04-13T18:48:30.063797126">
<session-end/>
</log>
And here is Netty ISOClient Log:
=====OUTGOING ISOMSG=====
CONNECTION ID 105107fffeae5c63-0001f2ea-00000000-d687451555e7c8aa-c0b54fc5
REMOTE ADDRESS localhost/127.0.0.1:7080
TIMESTAMP Sun Apr 13 18:48:29 WIB 2025
MTI [0800]
DE-7 [0413184829]
DE-11 [000001]
DE-41 [12345678]
DE-70 [301]
=====OUTGOING ISOMSG=====
=====INCOMING ISOMSG=====
CONNECTION ID 105107fffeae5c63-0001f2ea-00000000-d687451555e7c8aa-c0b54fc5
REMOTE ADDRESS localhost/127.0.0.1:7080
TIMESTAMP Sun Apr 13 18:48:30 WIB 2025
MTI [0810]
DE-7 [0413184829]
DE-11 [000001]
DE-39 [00]
DE-41 [12345678]
DE-70 [301]
=====INCOMING ISOMSG=====
That's all about Creating ISO8583 Server using jPOS Q2. you can get the complete source code in my Github Repository.
Comments
Post a Comment