jCard Internals - JPOSjpos.org/private/jCard_Internals.pdfiso2003_server_port is defined in...

27
jCard Internals

Transcript of jCard Internals - JPOSjpos.org/private/jCard_Internals.pdfiso2003_server_port is defined in...

  • jCard Internals

  • ii

    Table of ContentsCopyright notice ......................................................................................................................... v1. jCard Server ........................................................................................................................... 1

    1.1. jCard Server Lifecycle ............................................................................................... 11.2. jPOS CMF Server ...................................................................................................... 11.3. jPOS XML Server ...................................................................................................... 21.4. jCard Request Dispatcher ........................................................................................... 21.5. Incoming Handlers ..................................................................................................... 3

    2. jCard Transaction Manager ................................................................................................... 53. jCard Transaction Manager Participants ............................................................................... 8

    3.1. PrepareContext ............................................................................................................ 83.2. Open ............................................................................................................................ 93.3. Switch ....................................................................................................................... 103.4. Balance Inquiry Group ............................................................................................. 12

    3.4.1. CheckFields participant ................................................................................. 133.4.2. CreateTranLog participant ............................................................................. 163.4.3. CheckCard participant ................................................................................... 183.4.4. CheckTerminal participant ............................................................................ 193.4.5. CheckAcquirer participant ............................................................................. 203.4.6. SelectAccount participant .............................................................................. 203.4.7. ComputeBalances participant ........................................................................ 21

  • iii

    List of Figures2.1. Transaction Manager .......................................................................................................... 52.2. Transaction Participants ..................................................................................................... 63.1. Card / CardHolder / Account Relatioship ........................................................................ 183.2. Terminal / Merchant related relationships ........................................................................ 193.3. Card / CardHolder / Account Relatioship ........................................................................ 21

  • iv

    List of Tables3.1. jCard supported transactions ............................................................................................ 113.2. CheckFields special constant names ................................................................................ 13

  • v

    Copyright noticeCopyright © 1998-2015 by Alejandro Revilla d/b/a jPOS Consulting, Company# 212 752 380 016 - Uruguay. All rightsreserved. No part of this book may be reproduced in any form or by any electronic or mechanical means, includinginformation storage and retrieval systems, without permission in writing from Alejandro Revilla, except by a reviewer whomay quote brief passages in a review.

  • 1

    Chapter 1. jCard Server

    1.1. jCard Server LifecycleThe lifecycle of a transaction managed by jCard starts at a server.

    jCard can have multiple servers that in turn can operate using different ISO-8583 version/variants.

    There are two classes of servers:

    • jCard Native servers that operate using the jPOS CMF [http://jpos.org/doc/jPOS-CMF.pdf]• Customer specific servers that use other ISO-8583 versions/variants, or even non ISO-8583

    based protocols and convert all incoming and outgoing messages to and from the jPOSCMF

    The non jCard servers can operate on the same JVM as jCard (if deployed on the same deploydirectory), or they can run at external JVMs or even external systems and in turn connect to anative jCard server after the conversion to and from jPOS CMF took place.

    We call those customer specific servers (either running on the same JVM or on external JVMs)Source Stations.

    1.2. jPOS CMF ServerThe jPOS CMF server (ISO-8583 v2003) is defined in the file modules/jcard/deploy/50_server.xml and its configuration looks like this:

    @iso2003_server_port@

    The previous configuration instantiates a standard jPOS ISOServer that listens on a portdefined in the target file (i.e. devel.properties)

    The jPOS-EE build process uses Jakarta Ant’s filters to preprocess propertiesdefined in the build files (i.e. build.xml, build.properties, devel.properties)providing property expansion. In the default jCard configuration, the propertyiso2003_server_port is defined in devel.properties with a value of 8001.

    http://jpos.org/doc/jPOS-CMF.pdfhttp://jpos.org/doc/jPOS-CMF.pdf

  • jCard Server

    2

    The server uses the jPOS CSChannel and GenericPackager configured for ISO-8583v2003. It uses a 5 minutes timeout (300000ms) and defines a request listenerorg.jpos.jcard.Dispatcher and passes some configuration parameters to it, such as a space,a transaction manager queue (JCARD.TXN) and a class prefix (org.jpos.jcard.Incoming_).The Dispatcher completes the class name using the incoming message’s MTI and forwards thetransaction to the appropriate class, i.e:

    • Incoming_100• Incoming_200• Incoming_220• …• …

    1.3. jPOS XML ServerThe jPOS CMF uses ISO-8583 v2003, but for testing/debugging purposes, jCard also usesan ISO-8583 v2003 based XML server configured in the file modules/jcard/src/dist/deploy/50_xml_server.xml.

    The configuration looks like this:

    @xml_server_port@

    The previous configuration instantiates a standard jPOS ISOServer that listens on a portdefined in the target file (i.e. devel.properties).

    See jPOS CMF Server for an explanation of how filters work as well as how therequest listener is configured.

    This XML server uses jPOS XML representation of ISO-8583 messages (same as shown in thejPOS logs).

    1.4. jCard Request DispatcherThe jCard Request Dispatcher is an ISORequestListener [http://jpos.org/doc/javadoc/org/jpos/iso/ISORequestListener.html] that receives all traffic coming on the jCard main servers(both ISO-8583 v2003 and XML ones) and forwards them to the appropriate handler for thegiven MTI.

    http://jpos.org/doc/javadoc/org/jpos/iso/ISORequestListener.htmlhttp://jpos.org/doc/javadoc/org/jpos/iso/ISORequestListener.htmlhttp://jpos.org/doc/javadoc/org/jpos/iso/ISORequestListener.html

  • jCard Server

    3

    The code is located in modules/jcard/src/main/java/org/jpos/jcard/Dispatcher.javaand its process method looks like this:

    public boolean process (ISOSource source, ISOMsg m) { try { String mti = m.getMTI(); String className = cfg.get("prefix", "") + mti.substring(1); Class c = Class.forName(className); if (c != null) { ISORequestListener rl = (ISORequestListener) c.newInstance(); if (rl instanceof LogSource) ((LogSource)rl).setLogger (getLogger(), getRealm()+"-"+mti); if (rl instanceof Configurable) ((Configurable)rl).setConfiguration (cfg); return rl.process (source, m); } } catch (ClassNotFoundException e) { warn (e.getClass().getName() + " " + e.getMessage()); } catch (InstantiationException e) { warn (e); } catch (IllegalAccessException e) { warn (e); } catch (ISOException e) { warn (e); } return false; }

    Please note that we append the MTI to the configured prefix(org.jpos.jcard.Incoming_ in order to locate the appropriate handler class. TheMTI in jPOS includes the ISO-8583 version number (in this case the number 2representing ISO-8583 version 2003), so we use the code mti.substring(1) topick just the three-letter MTI.

    1.5. Incoming HandlersOnce a message reaches one of the jCard’s ISOServers, it gets forwarded to the RequestDispatcher, which in turn would instantiate an appropriate handler based on the Message’sMTI.

    As a small example, an 800 message (Network Management) would get forwarded toIncoming_800 which is implemented like this:

    public class Incoming_800 extends Log implements ISORequestListener { public boolean process (ISOSource source, ISOMsg m) { try { m.setResponseMTI (); m.set (39, "0000"); source.send (m); } catch (Exception e) { warn (e); } return true; } }

    This is a very simple handler that would just echo back a 810 response.

    On the other hand, other messages, such as 100, 200, 220, 304 and 420s are more complexand handled by the Transaction Manager. The implementation classes inherit fromIncomingSupport and are implemented like this:

  • jCard Server

    4

    public class Incoming_100 extends IncomingSupport { } public class Incoming_200 extends IncomingSupport { } ... ... public class Incoming_420 extends IncomingSupport { }

    IncomingSupport uses code like this in its process method.

    public boolean process (ISOSource source, ISOMsg m) { Context ctx = new Context ();

    ctx.put (REQUEST, m); String txnname = m.getString(0).substring(1); if (m.hasField(3)) { // processing code String pcode = m.getString(3); if (pcode.length() > 2) txnname = txnname + "." + pcode.substring(0,2); } if (m.hasField(24)) { txnname = txnname + "." + m.getString(24); // function code if (m.hasField (101)) txnname = txnname + "." + m.getString(101); // file name } if (m.hasField(25)) { txnname = txnname + "." + m.getString(25); // reason code } ctx.put (TXNNAME, txnname); ctx.put (SOURCE, source); // source is Transient sp.out (queue, ctx, timeout); // hands off to the TransactionManager return true; }

    This basically:

    • Creates a TransactionManager Context [http://jpos.org/doc/javadoc/org/jpos/transaction/Context.html] (ctx).

    • Creates a transaction name variable (TXNNAME) based on the MTI, the first two digits ofprocessing code (data element 3), and optionally the content of data element 24 (functioncode) and data element 25 (reason code). In situations where data element 24 is present, anoptional data element 101 (file name) may be appeneded to the transaction name.

    • Puts a reference to the ISOSource [http://jpos.org/doc/javadoc/org/iso/ISOSource.html]provided by the process method of the ISORequestListener [http://jpos.org/doc/javadoc/org/jpos/iso/ISORequestListener.html] in the Context under the constant name SOURCE.

    • Places the Context in a space under the queue defined in the XML configuration for theserver. This queue has to be the same used by the TransactionManager (in our case,"JCARD.TXN").

    In adition to the queue name, we define a timeout (in millis). The Context is placed in theSpace for a given time; ideally, it should be picked immediately by the TransactionManager.If the timeout expires, the entry will be lost. Interesting enough, due to the way theISO-8583 operates, this is a good thing. If for some reason a transaction doesn’t reach theTransactionManager in a reasonable short period of time, it would indicate that the system isexperiencing problems (such as a database being down, extremely high load, network issue,etc.). The best thing is to ignore the aging transactions so that the system recovers faster whenthe situation gets resolved. The remote endpoint will retry the transactions and the system willbe back up and running faster than if we try to process transactions that wouldn’t reach theremote endpoint anyway, because they have been timed out already.

    http://jpos.org/doc/javadoc/org/jpos/transaction/Context.htmlhttp://jpos.org/doc/javadoc/org/jpos/transaction/Context.htmlhttp://jpos.org/doc/javadoc/org/jpos/transaction/Context.htmlhttp://jpos.org/doc/javadoc/org/iso/ISOSource.htmlhttp://jpos.org/doc/javadoc/org/iso/ISOSource.htmlhttp://jpos.org/doc/javadoc/org/jpos/iso/ISORequestListener.htmlhttp://jpos.org/doc/javadoc/org/jpos/iso/ISORequestListener.htmlhttp://jpos.org/doc/javadoc/org/jpos/iso/ISORequestListener.html

  • 5

    Chapter 2. jCard Transaction ManagerjCard uses the jPOS TransactionManager [http://jpos.org/doc/javadoc/org/jpos/transaction/TransactionManager.html] 1 to implement its business logic usingreusable TransactionParticipant’s [http://jpos.org/doc/javadoc/org/jpos/transaction/TransactionParticipant.html].

    The TransactionManager implements a two-phase commit protocol, where participants getcalled usually twice; the first time at prepare time, and then — if all participants agree toproceed with the transaction — at commit time. If, for some reason, one of the participantsaborts the transaction, then those participants that were previously called (using their preparecallback method) will get a call to their abort method. There are special type of participants,the AbortParticipants that get called even if the transaction is going to abort, and theGroupSelectors that can provide some handy grouping of related participants.

    Figure 2.1. Transaction Manager

    jCard splits the business logic implementation into small little reusable chunks that we callparticipants. A typical transaction would:

    • Prepare the context with useful information such as a transaction timestamp• Perform some initial sanity checks on the message• Create an Hibernate session and begin a JDBC transaction• Create a TranLog record in the database with information taken from the request• Then perform multiple validations on the CardHolder, the Card, the Accounts…• …and similarly with Balance, Velocity checks, etc.• At some point the transaction is ready, so it’s logged and the JDBC transaction is committed• A suitable response gets created and transmitted back to the client

    Here is an overly simplified example of the aforementioned steps:

    1Documented in the jPOS Programmer’s Guide on chapter 10, and in the new Programmer’s Guide Draft http://jpos.org/doc/proguide-draft.pdf on chapter 9 (work in progress, so the numbering may change).

    http://jpos.org/doc/javadoc/org/jpos/transaction/TransactionManager.htmlhttp://jpos.org/doc/javadoc/org/jpos/transaction/TransactionManager.htmlhttp://jpos.org/doc/javadoc/org/jpos/transaction/TransactionManager.htmlhttp://jpos.org/doc/javadoc/org/jpos/transaction/TransactionParticipant.htmlhttp://jpos.org/doc/javadoc/org/jpos/transaction/TransactionParticipant.htmlhttp://jpos.org/doc/javadoc/org/jpos/transaction/TransactionParticipant.htmlhttp://jpos.org/doc/proguide-draft.pdfhttp://jpos.org/doc/proguide-draft.pdf

  • jCard Transaction Manager

    6

    Figure 2.2. Transaction Participants

    The transaction manager configuration is located in modules/jcard/src/dist/deploy/10_txnmgr.xml.

    The configuration starts like this:

    ...

    ... ... ...

    This creates a TransactionManager named txnmgr (it doesn’t explicitly define a nameattribute, so the element name is used as the service name) and define the following properties:

    • queue: This is the name of the Space [http://jpos.org/doc/javadoc/org/jpos/space/Space.html] queue used to send transactions to the TransactionManager. We use thearbitrary name JCARD.TXN but it could have been any other name, as long as the namematches the queue name defined in the request listeners (see modules/jcard/src/dist/deploy/50_*_server.xml)

    • sessions: The TransactionManager can process multiple simultaneous sessions. We usea low default value (2) in our tests servers in order to reduce the log size and simplify itsreading. Larger values can be used in production. The optimum value will depend on thenumber of processors available.

    • debug: if true, the TransactionManager will produce a log ticket after every transactionwith useful information about the transaction and the participants involved, with their timingand results.

    http://jpos.org/doc/javadoc/org/jpos/space/Space.htmlhttp://jpos.org/doc/javadoc/org/jpos/space/Space.htmlhttp://jpos.org/doc/javadoc/org/jpos/space/Space.html

  • jCard Transaction Manager

    7

    • participants: Then it follows a list, or chain, of TransactionParticipant's (or namedgroups that will process the transaction step by step. In the following chapter we’ll take alook at some of them.

    As we said above, if the TransactionManager definition has its debug property enabled, itwill produce log ticket. Here is a sample of what they look like:

    T 2010.589" lifespan="56ms"> txnmgr-0:151 prepare: org.jpos.jcard.PrepareContext NO_JOIN prepare: org.jpos.transaction.Open READONLY NO_JOIN prepare: org.jpos.jcard.Switch READONLY NO_JOIN groupSelector: reversal prepareresponse logit close sendresponse prepare: org.jpos.jcard.CheckFields NO_JOIN prepare: org.jpos.jcard.CreateTranLog NO_JOIN prepare: org.jpos.jcard.CheckCard NO_JOIN prepare: org.jpos.jcard.CheckTerminal NO_JOIN prepare: org.jpos.jcard.CheckAcquirer NO_JOIN prepare: org.jpos.jcard.FindOriginal READONLY NO_JOIN prepare: org.jpos.jcard.Reverse READONLY NO_JOIN prepare: org.jpos.jcard.PrepareResponse NO_JOIN prepare: org.jpos.jcard.LogIt READONLY NO_JOIN prepare: org.jpos.transaction.Close READONLY prepare: org.jpos.jcard.SendResponse READONLY prepare: org.jpos.jcard.ProtectDebugInfo READONLY prepare: org.jpos.transaction.Debug READONLY commit: org.jpos.transaction.Close commit: org.jpos.jcard.SendResponse commit: org.jpos.jcard.ProtectDebugInfo commit: org.jpos.transaction.Debug head=152, tail=152, outstanding=0, tps=12, peak=13, avg=9.38, elapsed=56ms prepare: org.jpos.jcard.PrepareContext [0.0/0.0] prepare: org.jpos.transaction.Open [0.6/0.6] prepare: org.jpos.jcard.Switch [0.0/0.6] prepare: org.jpos.jcard.CheckFields [0.2/0.9] prepare: org.jpos.jcard.CreateTranLog [1.2/2.1] prepare: org.jpos.jcard.CheckCard [4.2/6.4] prepare: org.jpos.jcard.CheckTerminal [0.8/7.2] prepare: org.jpos.jcard.CheckAcquirer [0.6/7.9] prepare: org.jpos.jcard.FindOriginal [2.3/10.2] prepare: org.jpos.jcard.Reverse [29.5/39.7] prepare: org.jpos.jcard.PrepareResponse [1.7/41.5] prepare: org.jpos.jcard.LogIt [0.1/41.7] prepare: org.jpos.transaction.Close [0.0/41.7] prepare: org.jpos.jcard.SendResponse [0.0/41.7] prepare: org.jpos.jcard.ProtectDebugInfo [0.0/41.7] prepare: org.jpos.transaction.Debug [0.0/41.7] commit: org.jpos.transaction.Close [4.5/46.3] commit: org.jpos.jcard.SendResponse [0.8/47.1] commit: org.jpos.jcard.ProtectDebugInfo [0.1/47.3] commit: org.jpos.transaction.Debug [9.0/56.3] end [56.9/56.9]

    We sometimes call this debug tickets

  • 8

    Chapter 3. jCard Transaction ManagerParticipants

    Once the transaction reaches the top of the Transaction Manager’s queue, it gets processed bythe participants defined in the file modules/jcard/src/dist/deploy/10_txnmgr.xml.

    In this chapter we’ll take a look at some of the most significant ones, to have an idea of whatthey do and how they work together to accomplish a full transaction. :numbered:

    3.1. PrepareContextThe PrepareContext participant is the very first participant in the execution chain. It isconfigured in ../deploy/10_txnmgr.xml like this:

    ... ...

    PrepareContext (available at modules/jcard/src/main/java/org/jpos/jcard/PrepareContext.java) prepares the Context (actually an org.jpos.transaction.Context)with helpful objects required by other participants down the execution chain, such as:

    • TIMESTAMP: It is desirable that all participants in a given transaction use exactly the sametimestamp, in order to avoid edge conditions where a transaction starts at a given date (i.e.23:59:59.99) and finish the next day (i.e.: at 00:00:00.00). These conditions not only happenat day boundary, they could happen at cutover times, etc.

    • TXNMGR: In situations where a transaction is forwarded from one transaction managerto another one (using the Forward participant), this context variable keeps a list of thetransaction managers involved in a given transaction.

    Implementing PrepareContext is trivial, the code looks like this:

    public class PrepareContext extends TxnSupport { TransactionManager txnmgr;

    public int prepare (long id, Serializable o) { Context ctx = (Context) o; ctx.getProfiler(); if (ctx.get (TIMESTAMP) == null) ctx.put (TIMESTAMP, new Date());

    String name = ctx.getString (TXNMGR); name = name == null ? txnmgr.getName() : ", " + txnmgr.getName(); ctx.put (TXNMGR, name);

    return PREPARED | NO_JOIN; }

    public void setTransactionManager (TransactionManager txnmgr) { this.txnmgr = txnmgr; }

    public void commit (long id, Serializable o) { } public void abort (long id, Serializable o) { } }

  • jCard TransactionManager Participants

    9

    The code is straight forward, but it deserves a few comments and clarifications:

    • The constants TIMESTAMP and TXNMGR are defined in file modules/jcard/src/main/java/org/jpos/ee/Constants.java, and taken at runtime from the org.jpos.ee.Constantsinterface.

    • The method void setTransactionManager (TransactionManager txnmgr) isnot part of the TransactionParticipant [http://jpos.org/doc/javadoc/org/jpos/transaction/TransactionParticipant.html] interface, but if available, it gets called bythe TransactionManager — providing a reference to itself — at initialization time.PrepareContext uses this technique 1 in order to grab a reference to the transaction managerso it can properly set the TXNMGR context variable.

    3.2. OpenThe Open participant creates a new org.jpos.ee.DB object, which in turns holds a liveHibernate and JDBC session. It stores a reference to the DB object in the context, under thename DB (defined in the org.jpos.ee.Constants interface). In addition, it begins a Hibernate/JDBC transaction, and stores it under the name TX.

    The configuration looks like this:

    ... ...

    The configuration defines the following properties:

    • checkpoint: This participant uses the general purpose jPOS Profiler [http://jpos.org/doc/javadoc/org/jpos/util/Profiler.html] in order to have realtime, fine grained, informationabout the system’s performance. We store a checkpoint called open that will appear at theend of every transaction (courtesy of the participant Debug that dumps the Context variablesto the jPOS log).

    • timeout: This is a timeout passed to Hibernate, which in turn passes it to the underlyingJDBC session. It is expressed in tenths of a second (in this case, 30.0 seconds).

    org.jpos.transaction.Open is located in jPOS-EE’s txn module and its implementation usesthe support class org.jpos.transaction.TxnSupport.

    TxnSupport provides a standard implementation of the prepare method, which inturn calls a protected doPrepare method. TxnSupport's prepare method createsa safety net around doPrepare, taking care of catching and logging possibleexceptions.

    1Duck typing

    http://jpos.org/doc/javadoc/org/jpos/transaction/TransactionParticipant.htmlhttp://jpos.org/doc/javadoc/org/jpos/transaction/TransactionParticipant.htmlhttp://jpos.org/doc/javadoc/org/jpos/transaction/TransactionParticipant.htmlhttp://jpos.org/doc/javadoc/org/jpos/util/Profiler.htmlhttp://jpos.org/doc/javadoc/org/jpos/util/Profiler.htmlhttp://jpos.org/doc/javadoc/org/jpos/util/Profiler.html

  • jCard TransactionManager Participants

    10

    3.3. SwitchOnce the Context is prepared, and a Hibernate/JDBC session has been opened, we areready to analize the transaction and decide how to route it, using a TransactionManager'sGroupSelector [http://jpos.org/doc/javadoc/org/jpos/transaction/GroupSelector.html].

    The participant org.jpos.jcard.Switch implements said GroupSelector. Theimplementation is quite straight forward:

    public class Switch extends TxnSupport implements GroupSelector { public int prepare (long id, Serializable context) { return PREPARED | READONLY | NO_JOIN; } public void commit (long id, Serializable ser) { } public void abort (long id, Serializable ser) { }

    public String select (long id, Serializable ser) { Context ctx = (Context) ser; String type = (String) ctx.get(TXNNAME); String groups = null; if (type != null) groups = cfg.get(type, null); if (groups == null) groups = cfg.get("unknown", "");

    // Debug info in context ctx.put("SWITCH", type + " (" + groups + ")"); return groups; } }

    Switch extends TxnSupport just to enjoy a couple of helper methods, such as the fact thatit already implements org.jpos.util.Configurable. It does nothing at prepare time, andreturns a PREPARE | READONLY | NO_JOIN value that tells the TransactionManager that:

    • The participant is prepared.

    • It did not modify the Context, so no need to take a persistent snapshot of it.

    • It doesn’t need to be called at prepare or abort time (NO_JOIN modifier)

    Then the select method uses the TXNNAME provided by the incoming handlers in order tofigure out which set of groups are going to process this transaction. It keys off the TXNNAMEusing configuration properties provided in the transaction manager configuration file(.../deploy/10_txnmgr.xml) that looks like this:

    ... ... ... ...

    http://jpos.org/doc/javadoc/org/jpos/transaction/GroupSelector.htmlhttp://jpos.org/doc/javadoc/org/jpos/transaction/GroupSelector.html

  • jCard TransactionManager Participants

    11

    The identifiers that appear in the value attributes of each property are the namesof groups defined in the transaction manager configuration file. For a deeperexplanation, please refer to the previous chapter, and to the Programmer’s Guidesgiven on that chapter’s footnote.

    The configuration is self-explanatory, a balance inquiry transaction (MTI=100, processingcode starts with 30) would run the following groups:

    • balanceinquiry: gets the balance for a given card/cardholder/account type• prepareresponse: prepares a response• logit: logs the transaction to the database• close: commits the JDBC transaction, so we can be sure the transaction is logged to

    persistent storage

    • sendresponse: sends a response back to the originating point

    The interesting point about jPOS TransactionManager in general, and jCard’s useof it in particular, is the fact that the system reuses most of the transaction participantimplementations, and even the groups of participants placed together under a given name (i.e.:logit, or sendresponse, etc.).

    jCard currently supports the following transactions:

    Table 3.1. jCard supported transactions

    ITC Name Description

    100.30 Balance Inquiry Computes the balance available and ledger balance for a givenaccount identified by the processing code’s account type (third andforth digits of data element 003)

    100.00 Authorization Authorization transaction, targets the cardholder’s account associatedwith the account type specified in the processing code.

    100.02 Authorizationvoid

    Voids a previously authorized transaction

    100.20 Refund Initiates a refund transaction

    100.22 Refund void Voids a previously authorized refund transaction

    200.00 POS Purchase Similar to 100.00 (Authorization), operates on the accounting layer.

    200.01 Cash Withdrawal Business logic is similar to POS Purchase, but withdrawals geta special ITC (internal transaction code) for reporting and riskmanagement purposes.

    200.02 Void Voids a POS Purchase or Cash Withdrawal

    200.20 Financial refund ditto

    200.21 Deposit Payment/Deposit to account

    Returns and deposits use a special account which is notimmediately accessible to cardholders, until an EOD process moves itto an appropriate and usable account.

    200.22 Voids apreviouslyprocessed refund/deposit

  • jCard TransactionManager Participants

    12

    ITC Name Description

    200.40 Account transfer Used to transfer funds from different accounts of the same cardholder(i.e.: checking to savings)

    220.00.0000 Purchase advice.A previouslyauthorizedtransaction(pending layer)gets confirmedby a purchaseadvice.

    220.20.0000 Refund advice Same for refunds

    220.00.1000 Force post Records a refund that was not previously authorized by the system.The value 1000 here represents: "Stand-In processing at the cardissuer’s option".

    See jPOS-CMF document, Appendix D, Reason Codes.

    220.00.2000 Force post Representment

    220.20.1000 Refund/Returnforce post

    220.20.4500 Chargebacknotification

    420.00.0000 Purchase/Authorizationreversal

    420.01.0000 Cash withdrawalreversal

    420.02.0000 Void reversal

    420.20.0000 Refund reversal

    420.21.0000 Deposit reversal

    420.40.0000 Transfer reversal

    304.301.CUSTOMER File update Adds a new customer

    304.301.MERCHANT File update Adds a new merchant

    For a complete list of Message Type Indicators and Processing Codes, refer to thejPOS-CMF [http://jpos.org/doc/jPOS-CMF.pdf] document.

    3.4. Balance Inquiry GroupThe Balance Inquiry transaction (itc "100.30") executes the groups:

    • balanceinquiry• prepareresponse• logit• close• sendresponse

    and then continues to the participants ProtectDebugInfo and Debug defined after the mainSwitch.

    http://jpos.org/doc/jPOS-CMF.pdfhttp://jpos.org/doc/jPOS-CMF.pdf

  • jCard TransactionManager Participants

    13

    This section describes the participants used by the balanceinquiry group.

    3.4.1. CheckFields participant

    Sample configuration

    The class org.jpos.jcard.CheckFields, located in the jcard module, checks for mandatoryand optional fields in the incoming message (available in the Context under the constant nameREQUEST.

    In addition to checking field presence by their field number, CheckFields understands severalspecial names that, when found, are then placed in the Context for the benefit of the followingparticipants.

    Table 3.2. CheckFields special constant names

    Constant Name Description

    PAN Extracts the PAN from the original message, either from data element 35 ona swiped transaction, or from data elements 2 and 14. Places the entries PANand EXP (expiration) in the Context. Throws an INVALID_CARD business logicexception (BLException) if a primary account number could not be found inthe request.

    PCODE Puts four variables in the context:

    • PCODE: full content of data element 3 (6 digits)• PCODE_TXN_TYPE: transaction type (first two digits of the processing code)• PCODE_ACCOUNT_TYPE: [source] account type (second group of two digits of

    the processing code)• PCODE_ACCOUNT2_TYPE: destination account type (third group of two digits of

    the processing code)

    Throws an INVALID_REQUEST BLException on errors.

    ORIGINAL_DATA_ELEMENTS Parses field 56 and places the following variables in the Context:

    • ORIGINAL_MTI: with the MTI of the original transaction• ORIGINAL_STAN: with the STAN (field 11) of the original transaction• ORIGINAL_TIMESTAMP: Timestamp (field 7) of the original transsaction

    AMOUNT Picks the transaction amount off field 4 and places the following variables inthe context:

    • AMOUNT: a BigDecimal containing the transaction amount. Decimals areadjusted according to the currency in use

    • CURRENCY: ISO-4217 currency code.

    Throws INVALID_AMOUNT BLException on errors.

    NETWORK_CAPTURE_DATE Parses the capture date and places it in the Context as a java.util.DateObject under the name NETWORK_CAPTURE_DATE. Throws INVALID_REQUEST onerrors.

    ADDITIONAL_AMOUNT Picks additional amount off field 54.

  • jCard TransactionManager Participants

    14

    Constant Name Description

    Field 7 If Field 7 (transmission date) is present in the list of mandatory or optionalfields, a TRANSMISSION_TIMESTAMP Date object is placed in the Context.

    Field 12 If Field 12 (local transaction date) is present in the list of mandatory or optionalfields, a LOCAL_TRANSACTION_TIMESTAMP Date object is placed in the Context.

    Field 41 If field 41 (Terminal ID) is present in the list of mandatory or optional fields,its string representation gets placed in the Context under the name TID.

    Field 42 If field 42 (Merchant ID) is present in the list of mandatory or optional fields,its string representation gets placed in the Context under the name MID.

    Sample transaction

    The Debug participant dumps the context after the transaction has been processed. A typicalContext would look like this:

    148 100.00 org.jpos.iso.channel.CSChannel@59d6e3d2 open [0.7/0.7] create-tranlog [1.5/2.3] check-card [5.0/7.3] check-terminal [0.8/8.1] check-acquirer [0.7/8.8] select-account [0.0/8.9] check-previous-reverse [3.7/12.6] check-velocity [9.9/22.5] authorization-start [0.0/22.6] authorization-pre-lock-journal [1.9/24.5] authorization-post-lock-journal [2.6/27.1] authorization-compute-balance [3.6/30.8] authorization-post-transaction [16.2/47.1] authorization [0.0/47.1] create-cache-ledger [26.1/73.2] create-cache-pending-and-credit [6.8/80.0] create-cache-pending [7.8/87.9]

  • jCard TransactionManager Participants

    15

    compute-balances [0.0/87.9] prepare-response [2.8/90.7] log-response [0.2/91.0] close [4.7/95.7] end [98.1/98.1] Fri Oct 15 18:22:54 UYST 2010 txnmgr org.jpos.ee.DB@7f4f84d5 100.00 (authorization prepareresponse logit close sendresponse) 000000 00 00 00 Fri Oct 15 18:22:54 UYST 2010 Fri Oct 15 18:22:54 UYST 2010 6.00 840 29110001 Fri Oct 15 12:00:00 UYST 2010 001001 org.jpos.ee.TranLog@635e6e9f[id=147] Fri Oct 15 00:00:00 UYST 2010 org.jpos.ee.Card@67360e7[id=4,pan=000000...0001] org.jpos.ee.CardHolder@3fea9527[id=2] org.jpos.ee.Issuer@64fa32bb[id=1,name=1] org.jpos.ee.Acquirer@6f3fd5c[id=1,name=1] org.jpos.gl.FinalAccount@1cb4ccc5[id=1042,code=21.0000000001.00] ---- reverse check ---- CriteriaImpl(org.jpos.ee.TranLog:this[][date>=Fri Oct 15 17:22:54 UYST 2010, irc=1816, stan=000000000144, originalItc=100.00, acquirer=000001, mid=001001, card=org.jpos.ee.Card@67360e7[id=4,pan=000000...0001], tid=29110001 ])

    org.jpos.gl.GLSession@3d99fd3f 0000 464166 8.05 4.00 0

  • jCard TransactionManager Participants

    16

    Some of the variables there, such as MID, TID, NETWORK_CAPTURE_DATE, PCODE,PCODE_TXN_TYPE, PCODE_ACCOUNT_TYPE, PCODE_ACCOUNT2_TYPE, etc. are placed by thisCheckFields participant.

    3.4.2. CreateTranLog participant

    Sample configuration

    Once the CheckFields participant has performed reasonable sanity checks against theincoming message, we are ready to create a TranLog record.

    The TranLog record is defined in the org.jpos.ee.TranLog entity (see modules/jcard/src/main/java/org/jpos/ee/TranLog.java and its modules/jcard/src/main/resources/org/jpos/ee/TranLog.hbm.xml mapping file).

    The CreateTranLog participant understands the following configuration parameters:

    • capture-date: This is the name of the CaptureDate service (org.jpos.ee.CaptureDate)defined in the …/deploy/01_capture_date.xml service. It provides a system-wide currentcapture date.

    • node: In a multi-node jCard deployment, users can configure the transaction managersto use different node names. This info-only node name gets stored in the tranlog.nodecolumn of the database record (see more about the database record below).

    • checkpoint: This property is actually managed by CreateTranLog's super class TxnSupportwhich calls checkpoint on the profiler available in the Context. When the Context getsdumped by the last participant (the Debug participant), the profiler is displayed with usefulinformation about the time spent by each participant.

    Here is a sample output:

    open [0.5/0.5] create-tranlog [3.7/4.3] compute-balances [62.0/66.3] close [25.8/92.2] end [98.2/98.2]

    The time is expressed in millis, in this case, the open participant took half a millisecond, andthe create-tranlog participant 3.7ms. The second figure is the running total (in this case, 3.7ms+0.5ms=4.3ms).

    Participants that extend TxnSupport can be configured to create a checkpoint in theprofiler. This is very useful during application tunning.

  • jCard TransactionManager Participants

    17

    CreateTranLog creates a TranLog record in the database, and populates a set of initial fieldsthat include:

    • Date: it uses the TIMESTAMP Date object available in the Context, courtesy of thePrepareContext participant.

    • LocalTransactionDate: LOCAL_TRANSACTION_TIMESTAMP taken by CheckFields from fields12 and 13 when available.

    • TransmissionDate: TRANSMISSION_TIMESTAMP taken by CheckFields from field 7, usuallyavailable.

    • Node: this is the Node name taken from the participant’s configuration property node.• Itc: the Internal Transaction Code, this is the TXNNAME context variable, placed by the

    request listener (IncomingSupport).

    • originalItc: On reversals and voids, CheckFields takes the original data elements off thecomposite field 56. In particular, originalItc is taken off ORIGINAL_MTI.

    • localId: This is the per-instance TransactionManager's id for this transaction. Can be usedto track the transaction in the jPOS logs for debugging purposes.

    • Outstanding: This is the number of pending Contexts available in theTransactionManager's input queue. Usually provides an estimate of the system load. Thisvalue should be really low, ideally 0, at all times.

    A higher value here means the system is under heavy load or experiencing a problem andrequires further review.

    • Acquirer: taken directly from field 32, if present, otherwise defaults to 000000.• Mid: Merchant ID, taken directly from field 42, if present.• Tid: Terminal ID, taken directly from field 41 (usually present).• Stan: Serial Transaction Audit Number, taken directly from field 11 (usually present).• ApprovalNumber: taken from field 38, if available.• ResponseCode: on force-post transactions, field 39 (response code) may be present.• Currency: The CURRENCY object optionally placed in the Context by CheckFields, taken

    from the composite amount field 4.

    • Amount: Transaction amount, placed in the Context by CheckFields under the nameAMOUNT.

    • AdditionalAmount: If available, placed in the Context by CheckFields under the nameADDITIONAL_AMOUNT.

    • CaptureDate: The system’s capture date, taken from the CaptureDate service.• FunctionCode: Taken directly from field 24, if present.• ReasonCode: Taken directly from field 25, if present.• FileName: on File Update transactions (MTI=304), taken from field 101 (file name), if

    present.

    After populating the TranLog object with the aforementioned fields, and saving it to theunderlying Hibernate/JDBC session (created by the Open participant), CreateTranLog sets thefollowing objects in the Context:

    • TRANLOG: a reference to the newly created TranLog object• CAPTURE_DATE: the capture date provided by the CaptureDate service and used by this

    transaction

  • jCard TransactionManager Participants

    18

    3.4.3. CheckCard participant

    Sample configuration

    In the jCard system, a Card (org.jpos.ee.Card entity) is just a reference to aCardHolder (org.jpos.ee.CardHolder) which in turn can hold general ledger accounts(org.jpos.gl.Account, actually org.jpos.gl.FinalAccount). 2

    Figure 3.1. Card / CardHolder / Account Relatioship

    CheckCard locates the Card from the card table, but there’s a caveat: the Primary AccountNumber (PAN) available in the Context (placed by the CheckFields participant) can’t be usedto find the card in the table because, due to PCI compliance, cards are encrypted.

    In addition, the encryption scheme we use (DUKPT 3 can not be used either, because the samecard encrypted two different times will create two different cryptograms. So jCard uses a hash(hash column in the card table).

    CheckCard then picks the PAN off the Context, computes its hash, and searches using thathash in the Card database. Once found, a live reference to the org.jpos.ee.Card entity isplaced in the Context under the name CARD.

    Once we have the Card reference in memory, we can pull the CardHolder using thecard.getCardHolder() method. CheckCard verifies that we have a valid and activecardholder (its active property has to be true). It also performs some verifications and sanitychecks on the card (it must be active, not suspended/stolen/lost and its start and end dates arewithin operational range).

    CheckCard can raise some exceptions that would, in turn, abort the transaction, raising errorssuch as:

    • CARD_NOT_ACTIVE• CARD_SUSPENDED• CARD_STOLEN• CARD_LOST• CARD_NOT_CONFIGURED, if the card is not associated with a CardProduct entity.• CARD_EXPIRED• CARD_SUSPICIOUS, if the received expiration date doesn’t match our records.

    2The classes in the org.jpos.gl package are part of jPOS-EE’s miniGL [https://github.com/jpos/jPOS-EE/tree/master/modules/minigl/src] module3Derived Unique Key Per Transaction

    https://github.com/jpos/jPOS-EE/tree/master/modules/minigl/srchttps://github.com/jpos/jPOS-EE/tree/master/modules/minigl/srchttps://github.com/jpos/jPOS-EE/tree/master/modules/minigl/src

  • jCard TransactionManager Participants

    19

    • CARDHOLDER_NOT_CONFIGURED• CARDHOLDER_NOT_ACTIVE• CARDHOLDER_EXPIRED

    CheckCard places the following new entries in the Context:

    • CARD• CARDHOLDER, pulled off the Card using card.getCardHolder()• ISSUER, taken from the CardProduct associated with this Card

    (card.getCardProduct().getIssuer())

    3.4.4. CheckTerminal participant

    Sample configuration

    CheckTerminal instantiates an org.jpos.ee.TerminalManager and uses the MID and TIDcontext variables placed by the previous CheckFields participant (taken from fields 42 and 41respectively) to locate a Terminal object from the database.

    Figure 3.2. Terminal / Merchant related relationships

    CheckTerminal reads a configuration property called force-check and decides if the terminaland merchant has to be actually validated as the jCard system can be installed in situationswhere the terminals and merchants are handled by the acquirer and are provided just as generalpurpose information.

    If check is required (force-check is true), the system validates that the Terminal exists and isactive, and that belongs to a Merchant that also exists and is active.

  • jCard TransactionManager Participants

    20

    There’s another optional flag, lock-terminal that can be used to lock the terminal, so thattransactions performed from a single terminal are serialized.

    CheckTerminal can raise some exceptions that would in turn abort the transaction, raisingerrors such as:

    • INVALID_TERMINAL• INVALID_MERCHANT• INACTIVE_TERMINAL• INACTIVE_MERCHANT• ACQUIRER_MISMATCH

    CheckTerminal places the following new entries in the Context:

    • TERMINAL• MERCHANT pulled off the Card using card.getCardHolder()

    3.4.5. CheckAcquirer participant

    Sample configuration

    The Card, located by the previous CheckCard participant is associated with a CardProduct,which in turn belongs to an Issuer, which is placed in the context (courtesy of CheckCard).

    Issuer has a one-to-many relationship with Acquirer's. This participant is a placeholderthat would allow to easily configure restrictions for different card products/issuer/acquirer(s)restrictions.

    The current code will just pick the first active acquirer and place it in the Context.

    In a multi-acquirer scenerio, this participant can be modified to validate that thereceived acquirer ID from the original request (field 32) matches the selectedacquirer associated with this CardProduct/Issuer.

    CheckAcquirer can raise the following exceptions:

    • SYSCONFIG_ERROR : Acquirer not found.

    and places the following new entry in the Context:

    • ACQUIRER

    3.4.6. SelectAccount participant

    Sample configuration

  • jCard TransactionManager Participants

    21

    Figure 3.3. Card / CardHolder / Account Relatioship

    A Card belongs to a CardHolder which has many Account's.

    As told in Section 3.4.3, “CheckCard participant”, org.jpos.gl.Account's aregeneral ledger accounts represented by miniGL's org.jpos.gl.FinalAccountentities. miniGL is part of jPOS-EE, and you can read more about its concepts here:http://jpos.org/private/miniGL.pdf

    This participant uses the CardHolder reference provided by the CheckCard participant, andthe PCODE_ACCOUNT_TYPE and CURRENCY information provided by the CheckFields participantin order to locate a cardholder’s account suitable for this account type (i.e. checking/savings/credit/prepaid, etc.) and currency combination.

    Once located, it places in the Context a reference to the FinalAccount object using the nameACCOUNT.

    If the transaction type (PCODE_TXN_TYPE) equals "40" (a transfer transaction according to jPOSCMF), SelectAccount uses the destination account type (last two digits of field 3, stored inPCODE_ACCOUNT2_TYPE) and currency to select the destination account, which is placed in thecontext as ACCOUNT2.

    SelectAccount can raise the following exceptions:

    • ACCOUNT_NOT_FOUND

    and places the following new entry or entries in the Context:

    • ACCOUNT• ACCOUNT2 (on transfer transactions)

    In addition to setting variables in the Context, SelectAccount takes the opportunity to pickthe TranLog object created by the CreateTranLog participant from the Context (it’s storedunder the name TRANLOG) and populates the account and optionally account2 properties.

    3.4.7. ComputeBalances participant

    Sample configuration

    ComputeBalances creates a miniGL session and picks the ACCOUNT subject to this balancecalculation from the Context. It uses the ISSUER in order to locate the miniGL Journal usedby this issuer (a Journal is the accounting book where all transactions specific to this issuerget recorded), as well as the current TIMESTAMP provided by the PrepareContext participant.

    http://jpos.org/private/miniGL.pdf

  • jCard TransactionManager Participants

    22

    jCard uses miniGL' multi-layer feature to store its transactions. Its layer plan involves usingthe href="http://www.iso.org/iso/en/prods-services/popstds/currencycodeslist.html[ISO-4217currency code] as the accounting layer (confirmed transactions that impacts the accountingbalance), and specific offset numbers for pending (unconfirmed authorizations that affectthe available balance but don’t touch the accounting balance) as well as credit overdrafttransactions.

    The layer plan looks like this:

    Currency Code Accounting Layer Pending Layer Credit Layer

    US Dollars 840 1840 2840

    Euros 978 1978 2978

    Argentine Peso 032 1032 2032

    Nigerian Naira 566 1566 2566

    Relying on miniGL’s multi-layer support, it is easy to compute different kind of balancesat differents point in time. ComputeBalances uses the transaction’s currency code in orderto select the appropriate accounting layer, and then adds PENDING_OFFSET to know the layernumber used to record pending transactions (i.e. authorizations that are are not confirmed byan advice transaction yet).

    For an US dollar transaction (currency code 840), ComputeBalances would calculate:

    • Accounting balance: taken from layer 840.• Available balance: taken by combining transactions in layer 840 and layer 1840

    This participant is used in the balance inquiry transaction, but also on othertransactions that have financial impact, such as POS purchases and ATMwithdrawals, and still return a balance (usually printed on receipts). For credittransactions (account type equals 30), the accounting balance field returns the creditallowance, in this case, taken from layer 2840.

    ComputeBalances can raise the following exceptions:

    • SYSERR_DB if the Issuer doesn’t have a Journal.

    and places the following new entries in the Context:

    • LEDGER_BALANCE• AVAILABLE_BALANCE

    In addition to setting variables in the Context, SelectAccount takes the opportunity topick the TranLog object, created by the CreateTranLog partitcipant, from the Context (it’sstored under the name TRANLOG) and populates TranLog's account, and optionally account2,properties.

    jCard InternalsTable of ContentsCopyright noticeChapter 1. jCard Server1.1. jCard Server Lifecycle1.2. jPOS CMF Server1.3. jPOS XML Server1.4. jCard Request Dispatcher1.5. Incoming Handlers

    Chapter 2. jCard Transaction ManagerChapter 3. jCard Transaction Manager Participants3.1. PrepareContext3.2. Open3.3. Switch3.4. Balance Inquiry Group3.4.1. CheckFields participantSample configurationSample transaction

    3.4.2. CreateTranLog participantSample configuration

    3.4.3. CheckCard participantSample configuration

    3.4.4. CheckTerminal participantSample configuration

    3.4.5. CheckAcquirer participantSample configuration

    3.4.6. SelectAccount participantSample configuration

    3.4.7. ComputeBalances participantSample configuration