Developing for EMV, Part III

In Part I of this series, we talked about how chip-card transactions differ from magstripe. We saw that there’s a considerable amount of back-and-forth communication between the reader and the card. But (good news!) we also saw that a lot of that communication is handled automatically — which is to say, out of the control of the payment-app developer — by the reader’s EMV kernel.

In Part II, we talked a bit about the various tags (or TLV data) that you can expect to get back during an EMV transaction, and what some of them mean. We also mentioned that an EMV transaction occurs in phases (with names like Start, Authenticate, and Complete). And we saw that different TLVs come back during the different phases.

VP8300
The ViVOpay VP8300 can handle chip cards, magstripe, or contactless.

We’ve also mentioned (many times, in fact) that while you can certainly carry out an EMV transaction by sending raw firmware commands directly to the card reader (via USB or RS-232), it’s generally easier to interact with the reader using ID TECH’s Universal SDK. (Go here for downloads. Be prepared to specify a platform: Windows, Linux, MacOS, iOS, or Android.)

Why is the SDK easier? Well, for one thing, it takes care of setting up serial communications (USB, RS-232, or Bluetooth) with the reader. It also insulates you from having to know about device-level firmware commands and associated low-level protocols. Also, you get ready-made code libraries that help with error-code interpretation, and data parsing.

Another great thing about the Universal SDK is that it comes with sample code showing how to use the various libraries that make these jobs easier. (Read on.)

How do you get started with the SDK? Let’s take a look at the major steps.

Step 1: Install the SDK

If you know which operating system you’ll be developing for, go to Development — Home on the Knowledge Base and navigate to the appropriate download. There are separate builds for Windows, Linux, MacOS, iOS, and Android.

Unpack the archive and try loading the sample project (look in the Source Code folder) in your IDE of choice. Compile and Run the sample app, with your ID TECH reader plugged in. Verify that the app can communicate with the reader.

Step 2: Configure Your Reader

Don’t expect to be able to run an EMV transaction straight out of the box! Your first transaction will fail if you haven’t taken time to configure your reader. At the very minimum, this means loading the reader with:

  • Terminal settings
  • AIDs
  • CAPKs (Certificate Authority Public Keys)

ID TECH supplies sample values for these (for testing purposes only), but you still need to run the commands that load the sample values. They aren’t loaded until you run the commands! (Fortunately, once your reader has these items loaded, you don’t need to re-load them on each startup. The values are persistent. Configuration is a one-time thing.) Take a look at the SDK’s sample code to see how this is done.

EMV configuration is a fairly big topic. We won’t try to do it justice in this post. For an introduction to the subject, be sure to see our earlier post on Terminal Settings, and also read the Configuration section of our EMV White Paper (PDF: free download).

Step 3: Run a Transaction

The sample app contains code for doing this. Step through the app to see how it works. Otherwise, you will at least need to set up a custom callback (a function that will be invoked automatically by the SDK at the right time), then call emv_startTransaction() yourself.

Communication with the card reader occurs asynchronously, which means that when you call a method like emv_startTransaction(), the SDK will contact the reader, seting off a chain of events, but your program will not block while the events take place. Instead, control is immediately returned to your app (along with a success/error code). SDK code will monitor the reader for any updates. When the reader finishes the Start phase of the EMV transaction, for example, it sends TLV data to the host computer (over USB, usually). The SDK will intercept that data, invoke your custom callback, and hand the data to the callback.

Bottom line, you need to set up a custom callback if you want to hear back from the reader!

What Does a Callback Look Like?

In the Windows version of the Universal SDK, your custom callback should have a C# signature that looks something like this:

    private void MessageCallBack(IDTechSDK.IDT_DEVICE_Types type, 
                             DeviceState state, 
                             byte[] data, 
                             IDTTransactionData cardData, 
                             EMV_Callback emvCallback, 
                             RETURN_CODE transactionResultCode)

To ensure your callback is actually used, you need to register it with the SDK at runtime, like this:

    IDT_VP3300.setCallback(MessageCallBack);

This example assumes you are using the ViVOpay VP3300 as your card reader, but obviously the SDK will support whatever ID TECH or ViVOpay reader you happen to be using. This is, after all, a Universal SDK.

What Does the Transaction Code Look Like?

When you want to start a transaction, you will need to execute code that looks something like this:

    RETURN_CODE rt = IDT_VP3300.SharedController.emv_startTransaction(1.00, 0,2, 0, 30, null, false);
    if (rt == RETURN_CODE.RETURN_CODE_DO_SUCCESS)
        {
            tbOutput.AppendText("Start EMV Successful\r\n");
        }
    else
       {
            tbOutput.AppendText("Start EMV failed Error Code: " + "0x" + String.Format("{0:X}", (ushort)rt) + ": " + IDTechSDK.errorCode.getErrorString(rt) + "\r\n");
       }

The call to emv_startTransaction() will result in a request being sent (over USB or serial) to the reader. The reader will do an ATR (that is, it will contact the chip on the card) and cause the EMV kernel to swing into action.

Assuming the Start Transaction succeeds (doesn’t time out, or error out), and assuming you’ve registered a callback (as described previously), your callback will, after one or two seconds, be executed. Your callback code should contain a fairly sizable “switch” statement with lots of cases to handle various types of outcomes. The outcome you’re hoping for, of course, is a successful EMV transaction with TLV data. So, you’re probably going to have code that looks something like the following, which will execute (in your callback) at the end of the Start phase:

[ switch statement ... ]
case DeviceState.TransactionData:
   //Transaction data is being returned in IDTTransactionData cardData
SetOutputText("Callback: TransactionData\n");
if (cardData.emv_resultCode == EMV_RESULT_CODE.EMV_RESULT_CODE_GO_ONLINE)
{
    // We will auto-complete. Normally, a host response is required here.
    SetOutputText("Online request. Auto Complete EMV Transaction.\n");
    byte[] responseCode = new byte[] { 0x30, 0x30 };
    byte[] iad = null;
    RETURN_CODE rt = IDT_VP3300.SharedController.emv_completeTransaction(false, responseCode, iad, null,null);
    return;
}

This code assumes you’ve set your prefs in such a way as to automatically execute the Authenticate Transaction phase, so you can go directly from Start to Complete. (It doesn’t have to be done that way, of course. It all depends what your requirements are.) In a real payment app, your app would pause during this ‘case’ to go online to the gateway or acquirer. Then you’d pass tag 8A (and maybe others) to emv_completeTransaction().

To see how to parse the transaction data (the TLVs) that come back after each phase of the transaction, search the sample code for “displayCardData(IDTTransactionData cardData)”. You’ll see various examples for parsing the data.

Questions?

You may have questions as you start to use the SDK. Bear in mind, the SDK comes with a great deal of documentation (in HTML as well as PDF formats). But if your questions need further answers, we’re here! Contact our experts:

Toll Free Number
1-800-984-1010

 

 

Related Posts

Leave a comment

You must be logged in to post a comment.