« May 2008 | Main | July 2008 »

6 posts from June 2008

Monday, June 30, 2008

Defending Your SAF

We implemented a Verizon Stored Value interface in our OLS.Switch solution using jPOSFSDISOMsg.  Using this facility, our retail clients can offer their customer phone card activation and refresh (aka. ‘top-up’) at the point of sale.  Now comes some ‘prevent defense’ requirements on our part.  Because Verizon is a non-standard interface, we need to take some extra protection to ensure that we don't get blown up by a crazy incoming dollar amount.  We saw on Wednesday, May 28th where 10 position amounts are coming in from the POS.  Our client’s Store System has a bug (re-created in the lab) causing ID numbers to come in as the amount.  This situation doesn't blow up the other interfaces because ISO Field 4 is 12 positions in length. But on Verizon, we get an exception because the defined length in the outgoing request is only six (6) positions.  Our q2.log shows this exception:

org.jpos.iso.ISOException: invalid len 10/6

The problem is further exacerbated because we put the item into SAF queue.  The exception repeats until the item is removed.  Thank god Alejandro’s very nice SAF facility bails us out by removing the crap record from the top of the queue after it expires.  For the record, our 20_verizon_saf.xml participant looks like this:

<saf name='verizon-saf' logger='Q2' realm='verizon-saf' class='org.jpos.saf.SAF'>
<property name='space' value='jdbm:saf-verizon' />
<property name='mux' value='verizon-mux' />
<property name='flag-retransmissions' value='no'>
  if MTI is in list, messages would be retransmitted as xxx1
</property>
<property name='initial-delay' value='60000' />
<property name='inter-message-delay' value='1000' />
<property name='wait-for-response' value='60000' />
<property name='max-retransmissions' value='1000' />
<property name='expire-after' value='1200'>
  in seconds
</property>
<property name='valid-response-codes' value='*' />
<property name='retry-response-codes' value='ZZ' />

That red, bolded value is the failsafe here: the ‘expire-after’ feature trumps the fact that the record is malformed.  After 20 minutes of retransmission misfires (the exception gets re-raised with every re-try), ‘expire-after’ cleans up the mess.

Now, we do the prevent defense thing as we’ve done in the past.  We need to protect and defend the integrity of the SAF.  In this case, we ought to flat-out reject the Verizon transaction locally if the incoming amount if the incoming amount string is > 6 positions.

So, we made this change in our CreateVerizonrequest.java program, leveraging one of OLS.Switch’s internal result codes:

- fsd.set ("purchase-price", msg.get ("amount"));

+ // If the amount length is greater than six, an
+ // exception occurs. The field length in VZN is 6;
+ // the store can do larger amounts. The problem is
+ // further exacerbated because we put the item into
+ // the SAF queue.  The exception repeats until the
+ // item is removed.

+ String reqamt = msg.get ("amount");
+ assertTrue (reqamt.length() < 7, APPLERR_INVAMOUNT,
+     "Amount too big for Verizon outbound message format");
+ if (reqamt.length() < 7) {
+     fsd.set ("purchase-price", msg.get ("amount"));
+ }
+       

As further prevention, Dave has suggested a change not to place an entry in the SAF if an exception is raised when processing the original.  That’s something on deck.

Saturday, June 28, 2008

Real Systems Do Extracts, Part 6

We practice continuous improvement of our extract processes.  Too many payment systems teams get locked into the ‘coolness’ factor on the OLTP side and leave the entire extract side of the equation until very late in the project game.  That’s not the way our OLS.Switch clients see things.  The extract is of equal importance.  After all, it’s how they get paid.  You can do all the transactions you want in whiz-bang way, but if you can’t reliably produce and ship a related extract file one or more times a day, your sponsoring bank isn’t going to fork over a dime.  You’ll be hearing from your client’s accountant (hey, maybe even the CFO) very early in morning.  In fact, in this business, if you get a 3 AM phone call on the red phone like Hillary, I can guarantee you it’s not because your most excellent jPOS OLTP engine blew up.  It’s because your extract PoC flopped.  

At one client site, we just formulated and are prepared to rollout an improved process for troubleshooting exceptions in the OLS.Switch nightly extract.  The approach also aims to contain the operational fallout that occurs when an exception is encountered.  Our goal:  Provide our clients' on-call engineers with the tools required to attain self-sufficiency in troubleshooting and resolution.  While don’t mind the phone calls, the new approach greatly increases the odds that they can sort it out themselves.

Specifically, when the nightly extract encounters an exception condition, we face the following challenges:

  1. The exception is buried in the q2.log.  It can be difficult to find.
  2. The exception relates to one or more specific records on the tranlog, but the ID is not referenced.  It takes a fair degree of intuition and esoteric knowledge to figure out which row prompted the error.
  3. The exception leaves the files in a “half-baked” state, but to the automated scripts that follow they appear complete.  As a result, [our client] sends invalid files (they don’t have trailer records) to processors.
  4. The exception is especially dangerous with respect to [one specific] extract.  Because this file format does not contain a trailer record, the half-baked file is processed correctly by [that endpoint].  This outcome heightens the possibility of duplicate billing of [that provider’s] transactions when the extract is re-run.

To address these concerns, OLS has re-engineered the extract exception process as follows:

  1. The exception text in the q2 log now references the ID of the offending row.
  2. To prevent the VB script from executing at job’s end, when an exception is found all extract files are renamed with an “*.bad” suffix. 
  3. For each extract and report file, the OLS.Switch extract process writes a complementary “*.log” file when an exception occurs.  The exception message will appear inside the log related to the specific file in which we encountered an error while trying to create it.

Thursday, June 26, 2008

More on the mechanics of jPOS’ FSDMsg facility

A jPOS Users list member asks:

“Does FSDMsg only supports fixed-length fields?  Can FSDMsg supports variable-length fields? Let’s say 2 bytes of length.”

You can do variable-length fields.  ‘FSD’ means “field separator delimited.”  Delimiters define the end of fields that can be variable in length.  Take a look at this schema definition from one of our jPOS implementations:

<schema>
<field id="magnetic-strip-info"      type="AFS" length="80" />
<field id="expiration-date"          type="NFS" length="4" />
<field id="pin-data-fs"              type="A"   length="1" />
<field id="flex-info"                type="AFS" length="108" />
<field id="amount"                   type="AFS" length="14" />
<field id="additional-amount"        type="AFS" length="14" />
<field id="register-number"          type="A"   length="2" />
<field id="tran-id"                  type="A"   length="7" />
<field id="tender-attempt-indicator" type="A"   length="1" />
<field id="tender-number"            type="N"   length="4" />
<field id="tender-attempt"           type="A"   length="4" />
</schema>

That's something we use to parse a portion of an incoming message, where:

  • A = fixed-length alphanumeric field
  • N = fixed-length numeric field
  • AFS = variable-length alphanumeric field, terminated by a field separator ('1C)
  • NFS = variable-length numeric field, terminated by a field separator ('1C)

Here's another example:

<schema id='S'> <!-- Special Condition Record-->
<field id='quasi-cash-indicator'  type='K' length='1' >N</field>
<field id='special-condition-indicator' type='A' length='1'  />
<field id='clearing-sequence'           type='N' length='2'  />
<field id='clearing-count'              type='N' length='2'  />
<field id='cust-svc-phone-flag'   type='K' length='1' >N</field>
<field id='filler-1'                    type='A' length='34' />
<field id='seqno'                       type='N' length='6'  />
<field id='special-use-fields'          type='A' length='19' />
<field id='merchant-trans-indicator'    type='A' length='1'  />
<field id='cert-for-mc-advice-code'     type='A' length='1'  />
<field id='mc-trans-category-indicator' type='A' length='2'  />
<field id='filler-2'                    type='A' length='9'  />
</schema>

Where:

  • K = Constant (you can see how I've specified the constant values).

Some other FSD behaviors to note...

If you're building a message via FSD and you *don't* specify a value for a particular field in your code, then what you get as a default is:

  • For 'A': Filled with spaces
  • For 'N': Filled with zeroes
  • For 'AFS' and 'NFS': You'll get just the field separator

Also:

For 'A': If you populate a field with a value shorter than the length of the field, FSD will left-justify and space-fill to the right.  For example, if I were to populate this field...

<field id="tran-id"                  type="A"   length="7" />

...with "4433", I'd get:

"4433   "

For 'N': If you populate a field with a value shorter than the length of the field, FSD will right-justify and zero-fill to the left.  For example, if I were to populate this field...

<field id='seqno'                       type='N' length='6'  />

...with 4433, I'd get:

004433

If, however, 'seqno' had been defined like so...

<field id='seqno'                       type='NFS' length='6'  />

...and you placed '4433' in there, then FSD would build this in the construction of the message:

4433'1C

(where '1C indicates the presence of a hex field separator)

Additionally, when using or defining NFS or AFS you MUST use a length that is the maximum than any expected length you plan on receiving.  You see above:

<field id="magnetic-strip-info"      type="AFS" length="80" />

If I were to get, say, 85 characters in from the origination point prior to a field separator, then I'm screwed and my FSD parse breaks down because I've blown past where my field separator ought to be.  We worked with the store system team in this case to determine the absolute maximum we would see coming in...then we set that value a few characters bigger for safety.

Another behavior to note:

Suppose in your program you use the wrong FSD field name.  For example, when populating this field...

<field id='seqno'                       type='N' length='6'  />

...let's say that in your code, you did this:

        m.set ("seq-no", Integer.toString(seqno));

(note incorrect field name used in set).

What would happen would be:

  1. Your code would compile without error.
  2. Your program would execute without error.
  3. The records would be created with 'seqno' populated with 000000.

Double-check all your field references in your program to make sure you've got the names exactly right!

See my previous posts related to different FSDMsg usages here and here.

Monday, June 16, 2008

Conversion(s) Complete

For payment systems managers wondering if the jPOS project is a good choice for your enterprise, we’ve got an update from our flagship OLS.Switch client as a consideration in your decision-making process. 

At that client, we reached a gratifying dual milestone last week.  First, they’ve just finished on-boarding the last of about 1,800 acquired stores, bringing the total to around 5,020 locations across the four US continental time zones.  Second, we’ve just converted the last of the payment acceptance types off of the legacy platform.  That's a Check Authorization application.  As a result, as of Friday the legacy application is processing a big fat zero transactions per day, while the jPOS-fueled OLS.Switch clocked in a week in which the daily average was just a gnat's hair shy of 1 million (991,588 to be exact). 

I had said here recently that the 'New Normal' after we reached these milestones was going to be one where we reached a million customers interactions a day the 'natural' way, i.e., without the a holiday-fueled consumer buying bulge.  We're not quite there yet.  Thursday, Friday and Saturday all clocked in comfortably over the one million threshold but were no doubt fueled by a sizable Father's Day run-up.

We do all this on $28,000 of core server hardware - replicated application nodes + a two-server MS SQL Server virtual cluster.  Refer to my 'Can jPOS Handle It?' series for further details.

Thursday, June 12, 2008

Now Blogging With Windows Live Writer

I’m taking part in Six Apart’s new TypePad Blog Tune-Up Service.  One of the things they noticed in their review is my bad habit of occasionally copying things in from Word.  This is causing some problems because, as the tune-up report notes “Copying content from Word will cause formatting problems, error messages, and feed validation problems. The issue with Microsoft Word formatting code is not unique to TypePad's Rich Text Editor. Any editor that copies over formatting will cause issues such as this -because the code that Microsoft Word inserts is not web-compatible.”

So, I’m taking the Tune-up team’s suggestion by blogging with Windows Live Writer.  So far, I’m impressed.  The download was easy and the integration into IE is seamless.  I just started writing immediately without any feelings of disorientation.

Payment Systems Podcast, Episode 1

My OLS colleagues Dave Bergert and Chuck Wilke were in Big D earlier this week for a planning meeting.  While here, Dave had the idea of recording a first Podcast for his Payment Systems Blog.  He invested in a pretty impressive-looking microphone and recorded and edited the session with Garage Band on his MacBook. 

Dave sounds great here.  His background as a QSA makes him a really good questioner.  I need to get closer to the microphone.  Blame the echo on the "minimalist style" that my wife and I have throughout our house.

My Photo

Tools

  • Google

    The entire web
    www.andyorrock.com
AddThis Social Bookmark Button

Resources

  • About Me
  • Dave Bergert's blog
    Insightful payment systems thoughts by my OLS colleague, Dave Bergert, CISSP, CISA, CompTIA Security+, and former Visa-certified QSA.
  • Glenbrook Partners' Blog List
    Glenbrook Partners has compiled "a current summary of the latest content from some of our favorite payments and banking blogs based upon their RSS feeds." Alejandro, Dave and I are on the list, as are many other good info sources.
  • jPOS
    Faced with payment systems challenges? Start here to learn more about Alejandro Revilla's jPOS project.
  • Randy San Nicolas' blog
    My OLS colleague Randy San Nicolas writes about his wealth of experience in various Issuer- and Acquirer-side endeavors in his Prepaid Enterprise blog.
  • soliSYSTEMS
    My friend Roque Solis is our go-to guy for RFID, smart cards, chip cards, integrated circuit(s) cards (ICC), HSMs, cryptographic accelerators, DES and public-key cryptography.
  • Specs Online - AMEX
    American Express (Amex) puts all its acquirer specs online for public retrieval.
  • Specs Online - First Data
    First Data Merchant Services (FDMS, aka 'FDR') puts all its acquirer specs online for public retrieval. [NOTE: FDMS' spec repository is accessible only via Internet Explorer; this link will not work with Firefox or other browsers.]
Blog Widget by LinkWithin

Enter your email address:

Delivered by FeedBurner

Blog powered by TypePad

If you're looking here...

  • Your attention to detail is a great asset. Use it wisely.