A couple of posts back, I talked about the importance of establishing an Internal Result Code ('irc') framework in a jPOS application. Here, I'll talk now about the equally important idea of establishing an Internal Transaction Code ('itc') framework. To me, the irc/itc concept are like two sides of the same coin. In fact, I think they get to the heart of the entire Buy vs. Build discussion.
In our jPOS application (we call it OLS.Switch), we've established an itc framework that has served us pretty well over time. While we established the list originally for an issuer-oriented implementation, what's been gratifying is how we've been able to re-purpose the core ideas of the framework for our acquirers. You can take a look at our itc list here. I've outlined in red the sections from our original issuer-oriented incarnation that we've been able to leverage from our acquirer-side work. The part on the upper-left that isn't in the red is the section most reflective of the original issuer orientation of the list. Those MTI/Processing Code combinations are from a specific issuer-side implementation in which we received Debit/EBT transactions from a Genpass transaction gateway. [NOTE: Genpass is now known as Elan Financial Services. Elan is owned by U.S. Bank.]
Thing is, our itc list has inspired a pretty good discussion between me and Alejandro about whether we've traded one set of esoteric codes (the ISO processing codes) for another. It's a good point. We've talked about how to improve them. One observation is that we treat the codes internally as alphanumeric (the column in our tranlog is defined as 'internalTranCode varchar(8)') and there's nothing to prevent us from going to a tran code set like PUR530, REV531 - these would be good eye-catchers as you peruse q2 logs or look at transactions in the jPOS UI.
Alejandro posits that we ought to evolve to something more ISO like (i.e., leverage the processing codes). My counterpoint to that has always been that the inherent variability of ISO means that your choices for your internal codes would only match up to one gateway/auth link. For example, if - in one of our recent projects - we had made the decision to implement the itc framework to match up with the FDR North processing code set, well...AMEX's processing codes are different than that. And, we're in the process of certifying and implementing four [U.S.] national Stored Value Card ('SVC') authorization links and - as you can guess - the MTIs and Processing Codes (for the exact same transaction sets!) are all over the map. In fairness, Alejandro's comments are more to the point that the itc list should follow some chosen implementation of the [relatively loosely applied] ISO processing code standard of xxyyzz (where xx = transaction type; yy = 'from' account; and 'zz' = 'to' account. [When you're in the midst of certifying a major SVC authorizer and they implement the purchase as '000000', you know what I mean about 'loose interpretations.']
Additionally, on the acquirer side, you find yourself accepting transactions from ISO8583 origination points, as well as XML, Visa Gen 2, APACS (the evolving European standard), X9.15 as well as totally off-the-map custom implementations. And, when you're switching out, in addition to the various ISO interpretations, you've got totally custom Field Separator Delimited-based endpoints (e.g., Verizon's Stored Value Card) and 'ISO-like but not quite ISO' bitmap implementations (e.g., JC Penney). Within this type of very realistic operating environment, our itc framework acts as a unifying standard.
One aspect of the itc framework that has worked out particularly well is the implementation of the xxxx1 transaction as a reversal. Those are really good eye-catchers on the jPOS UI transaction 'Show.'
Now, the great thing about jPOS is how easy the TransactionManager allows you to implement and extend the ultra-critical task of going from origination point transaction code to Internal transaction code to the ISO8583 MTI/Processing Code combination required by a particular authorizing endpoint. Here's one small example from one of our production implementations...
Here, the transactions are received from a Visa Gen 2 ('VG2') origination point, logged internally using our itc framework and (in the case of the Debit/EBT example I'm showing you here) routed out to FDR North for authorization.
To accept Debit/EBT transactions from the VG2 origination point, we have a switch participant that looks like this:
<participant class="org.jpos.ev.Switch" logger="Q2" realm="switch">
<property name="G.93" value="CreateDebit Decrypt DebitSale" />
<property name="G.96" value="CreateDebit Decrypt DebitSaleReversal LogAndReply" />
<property name="E.60" value="CreateDebit Decrypt EBT_FS_Sale" />
<property name="E.61" value="CreateDebit Decrypt EBT_FS_Void LogAndReply" />
<property name="E.62" value="CreateDebit Decrypt EBT_FS_Return" />
<property name="E.63" value="CreateDebit Decrypt EBT_FS_BalInq LogAndReply" />
<property name="E.68" value="CreateDebit Decrypt EBT_FS_Return_Rev LogAndReply" />
<property name="E.69" value="CreateDebit Decrypt EBT_FS_Sale_Rev LogAndReply" />
<property name="E.65" value="CreateDebit Decrypt EBT_Cash_Sale" />
<property name="E.66" value="CreateDebit Decrypt EBT_Cash_Void LogAndReply" />
<property name="E.67" value="CreateDebit Decrypt EBT_Cash_Sale_Rev LogAndReply" />
<!-- Unhandled transactions -->
<property name="Unhandled" value="Unhandled" />
</participant>
Let's focus on one transaction - the Debit Sale (G.93 where 'G' is the VG2 'Record Format' and '93' is the VG2 'Transaction Code'). Specifically, let's look at the 'DebitSale' participant - which is actually a 'group' which implements a series of participants - one of which is this one assigning the itc:
<participant class="org.jpos.ev.PopulateDebitTranLog"
logger="Q2" realm="populate-debit-tranlog">
<property name="itc" value="05300" />
<property name="cardType" value="DB" />
<property name="checkpoint" value="populate-debit-tranlog" />
</participant>
Then, subsequently, we want to route the transaction out to FDR with the appropriate MTI/Processing Code. So, we have this participant:
<participant class="org.jpos.ev.CreateFDRRequest"
logger="Q2" realm="create-fdr-request">
<property name="mti" value="0200" />
<property name="pcode" value="009000" />
<property name="template" value="cfg/fdr-template.xml" />
<property name="space" value="jdbm:fdr-stan" />
<property name="checkpoint" value="create-fdr-request" />
</participant>
Now, there's a lot of other stuff going in these transactions (PIN checking, Valid store and terminal checks, Duplicate checks, etc.), but these three participants give you the essence of the external-to-internal-to-external translation. Getting this concept right sits at the very heart of a successful jPOS implementation.
Comments