Giving the TransactionManager a Workout
The jPOS TransactionManager and Its Participants
I was doing some more work today with jPOS TransactionManager (‘TM’) instances. We’re bringing a second FSA-enabled endpoint on-board at one of our Acquirer payment switch implementations. My favorite part of the on-boarding is always the juncture when I sit down to figure out how to best implement the required transaction participants in the TM. When our clients and prospects ask to see “our authorization rules” or wonder “how do we implement new features and concepts,” we go directly to showing them some of our production TM implementations. That’s always the “a-ha!” moment.
The FSA implementation really brings a lot of best practices into play…especially in the part where I was diving in today: Reversals. Here’s a list of the things I had to consider while doing this:
[NOTE: The list below refers to the flow exhibited in this example.]
- Identify the transaction type in play (in the example that I’ve attached here, I’ve isolated the FSA Reversal logic for reader review).
- Create the tranlog entry
- Figure out what endpoint to route to (see our ‘SelectEndPoint’ participant – and its variations). We do this by examining a table we construct from card types and bin ranges (lookup the BIN range to determine the card type which – in turn – is related to an endpoint).
- For some of the endpoints (see ENDP2, ENDP3 and ENDP4 in my example – I did some masking here), simply handle the Reversal locally. [What’s going on there is that we’re not supposed to get FSA transactions related to these card types…but my experience dictates: you never know. So, we play prevent defense. Moreover, you can never flat-out reject a reversal of any kind because originators SAF them…see why here.]
- Try to find the original. [We’ve got two routines in our toolkit: what I call “find original soft” and “find original hard.” Early in the TM processing for reversals we need the ‘soft’ option because we need to get the PAN from the original if it exists (reversals typically don’t have PAN or track info); but even if we can’t find an original, we don’t want to abort the flow just yet, because we have other stuff to do). Later in the flow, we want to abort if no original was found (where not found = never got an original – OR – the original was declined – OR – the original was already reversed – OR – the original was already settled or extracted), so we do the ‘hard’ option.
- For Endpoints 1 (ENDP1) and 5 (ENDP5), prepare to go remote…but first we need to check if the original was handled locally or remotely. [In this implementation, there are circumstances in which an original request could have been handled at the point-of-sale as a ‘manager override’ which we handle locally (it’s not an auth – the sale happened, and the customer is long gone)…in those cases the endpoint doesn’t know about the original, so it makes zero sense to send them the reversal.]
- If the original was handled locally for cards associated with either ENDP1 or ENDP5, handle the reversal locally.
- If the original was handled remotely for cards associated with either ENDP1 or ENDP5, handle the reversal remotely.
- Create either an ENDP1 or ENDP5 outbound reversal request. [As a point of interest, the ENDP1 here is pure ISO8583, while ENDP5 uses APR’s very useful FSDISO approach (this is our 6th usage!)]
- Drop the reversal into the SAF queue (we always SAF outbound reversals!)
- Do our FlagReversal thing (tags the original’s revInd = ‘T’ and cross-links the reversal and original with cross-referencing transaction IDs in their respective refId columns).
- Do a force approval to make sure we get a controlled result code if the process aborts. [We use our internal result code = 4000, which is what we call a Force Approval. You never send a non-approval back on a reversal. This is a critically important concept. You learn this the hard way.]
- Create a response back to the originator.
Comments