IDTech Windows SDK Guide  1.2.177.4
API reference for Vendi
Sample Project Tutorial

Using Visual Studio 2015, we will create a C# sample project that will interface with the Vendi and will perform the following activities:

  • Get firmware version
  • Perform MSR Transaction
  • Perform CTLS Transaction
  • Connect to either USB or Serial Versions of Vendi.
  • Show log of all data going to/from Vendi

Step 1: Create New Project

Create a new Windows Form Application in Visual Studio. In our example, we use project name Vendi_Simple_Demo.

new_project.png

Step 2: Import Libraries

Import the Necessary Libraries

Step 3: Design Interface

Use the Form Designer to layout buttons/fields
Open your form designer and add items so it contains the following buttons/fields:

  • Radio buttons for USB and COM selection. For COM selection, add a text box to specify COM port
  • Add buttons to execute the following functions:
    • Get Firmware
    • Start MSR
    • Cancel MSR
    • Start CTLS Transaction
    • Cancel CTLS Transaction
  • Add a text box to communicate data from the Vendi.
  • Add a text box for the log of Vendi.
Vendi_app.png

Step 4: Configure the Project File

In the start of the class file, perform the following:

  • Add Using Statements to Utilize Library
  • Set callback method and initialize Vendi singleton object in the class initializer. Reference: Initialize Vendi
  • Implement the radio button methods CheckChanged handlers to set the proper interface for SDK communications
    private void rbInterface_CheckedChanged(object sender, EventArgs e)
    {
    if (rbUSB.Checked)
    {
    IDT_Vendi.useUSB();
    }
    else
    {
    IDT_Vendi.useSerialPort(Convert.ToInt32(tbCOMPort.Text));
    }
    }

  • Implement the button methods Click handlers for button press code execution
    private void btnGetFirmwareVersion_Click(object sender, EventArgs e)
    {
    string firmwareVersion = "";
    byte[] reData = { };
    RETURN_CODE rt = IDT_Vendi.SharedController.device_getFirmwareVersion(ref firmwareVersion);
    if (rt == RETURN_CODE.RETURN_CODE_DO_SUCCESS)
    {
    tbOutput.AppendText("Firmware Ver: " + firmwareVersion + "\r\n");
    System.Diagnostics.Debug.WriteLine("Firmware Ver: " + firmwareVersion);
    }
    else
    {
    tbOutput.AppendText("Get Firmware Fail Error Code: " + "0x" + String.Format("{0:X}", (ushort)rt) + ": " + IDTechSDK.errorCode.getErrorString(rt) + "\r\n");
    System.Diagnostics.Debug.WriteLine("Get Firmware Fail Error Code: " + "0x" + String.Format("{0:X}", (ushort)rt));
    }
    }
    private void btnStartMSR_Click(object sender, EventArgs e)
    {
    RETURN_CODE rt = IDT_Vendi.SharedController.msr_startMSRSwipe(60);
    if (rt == RETURN_CODE.RETURN_CODE_DO_SUCCESS)
    {
    // continueMSR = true;
    //EY: MSR BLUE LED BLINK
    tbOutput.AppendText("MSR Turned On successfully; Ready to swipe\r\n");
    System.Diagnostics.Debug.WriteLine("MSR Turned On successfully; Ready to swipe");
    }
    else
    {
    tbOutput.AppendText("Start Swipe Failed Error Code: " + "0x" + String.Format("{0:X}", (ushort)rt) + ": " + IDTechSDK.errorCode.getErrorString(rt) + "\r\n");
    System.Diagnostics.Debug.WriteLine("Start Swipe Failed Error Code: " + "0x" + String.Format("{0:X}", (ushort)rt));
    }
    }
    private void btnCancelMSR_Click(object sender, EventArgs e)
    {
    RETURN_CODE rt = IDT_Vendi.SharedController.msr_cancelMSRSwipe();
    if (rt == RETURN_CODE.RETURN_CODE_DO_SUCCESS)
    {
    tbOutput.AppendText("MSR Turned Off successfully\r\n");
    System.Diagnostics.Debug.WriteLine("MSR Turned Off successfully");
    }
    else
    {
    tbOutput.AppendText("MSR Turned Off failed Error Code: " + "0x" + String.Format("{0:X}", (ushort)rt) + ": " + IDTechSDK.errorCode.getErrorString(rt) + "\r\n");
    System.Diagnostics.Debug.WriteLine("MSR Turned Off failed Error Code: " + "0x" + String.Format("{0:X}", (ushort)rt));
    }
    }
    private void btnStartCTLSTransaction_Click(object sender, EventArgs e)
    {
    byte[] additionalTags = new byte[] { 0x8E, 0x5A };
    RETURN_CODE rt = IDT_Vendi.SharedController.ctls_startTransaction(1.00, 0, 2, 0, 30, additionalTags);
    if (rt == RETURN_CODE.RETURN_CODE_DO_SUCCESS)
    {
    tbOutput.AppendText("Start CTLS Successful\r\n");
    System.Diagnostics.Debug.WriteLine("Start CTLS Successful");
    }
    else
    {
    tbOutput.AppendText("Start CTLS failed Error Code: " + "0x" + String.Format("{0:X}", (ushort)rt) + ": " + IDTechSDK.errorCode.getErrorString(rt) + "\r\n");
    System.Diagnostics.Debug.WriteLine("Start CTLS failed Error Code: " + "0x" + String.Format("{0:X}", (ushort)rt));
    }
    }
    private void btnCancelCTLSTransaction_Click(object sender, EventArgs e)
    {
    RETURN_CODE rt = IDT_Vendi.SharedController.ctls_cancelTransaction();
    if (rt == RETURN_CODE.RETURN_CODE_DO_SUCCESS)
    {
    tbOutput.AppendText("Cancel Transaction Successful\r\n");
    System.Diagnostics.Debug.WriteLine("Cancel Transaction Successful");
    }
    else
    {
    tbOutput.AppendText("Cancel Transaction failed Error Code: " + "0x" + String.Format("{0:X}", (ushort)rt) + ": " + IDTechSDK.errorCode.getErrorString(rt) + "\r\n");
    System.Diagnostics.Debug.WriteLine("Cancel Transaction failed Error Code: " + "0x" + String.Format("{0:X}", (ushort)rt));
    }
    }

Step 5: Configure Callback

The callback is used to receive important SDK data (messages, log info and transaction results). Reference: Implement the Callback Function

private void MessageCallBack(IDTechSDK.IDT_DEVICE_Types type, DeviceState state, byte[] data, IDTTransactionData cardData, EMV_Callback emvCallback, RETURN_CODE transactionResultCode)
{
switch (state)
{
case DeviceState.ToConnect:
//A connection attempt is starting for IDT_DEVICE_TYPES type
SetOutputText("Callback:ToConnect\n");
break;
case DeviceState.DefaultDeviceTypeChange:
//The SDK is changing the default device to IDT_DEVICE_TYPES type
SetOutputText("Callback:DefaultDeviceTypeChange\n");
break;
case DeviceState.Connected:
//A connection has been made to IDT_DEVICE_TYPES type
SetOutputText("Callback:Connected\n");
break;
case DeviceState.Disconnected:
//A disconnection has occured with IDT_DEVICE_TYPES type
SetOutputText("Callback:Disconnected\n");
break;
case DeviceState.ConnectionFailed:
//A connection attempt has failed for IDT_DEVICE_TYPES type
SetOutputText("Callback:ConnectionFailed\n");
break;
case DeviceState.TransactionData:
//Transaction data is beign returned in IDTTransactionData cardData
SetOutputText("Callback:TransactionData\n");
displayCardData(cardData);
break;
case DeviceState.DataReceived:
//Low-level data received for IDT_DEVICE_TYPES type
SetOutputTextLog(" IN: " + Common.getHexStringFromBytes(data));
break;
case DeviceState.DataSent:
//Low-level data sent for IDT_DEVICE_TYPES type
SetOutputTextLog(" OUT: " + Common.getHexStringFromBytes(data));
break;
case DeviceState.CommandTimeout:
SetOutputText("Command Timeout\n");
break;
case DeviceState.CardAction:
if (data != null & data.Length > 0)
{
CARD_ACTION action = (CARD_ACTION)data[0];
StringBuilder sb = new StringBuilder("Card Action Request: ");
if ((action & CARD_ACTION.CARD_ACTION_INSERT) == CARD_ACTION.CARD_ACTION_INSERT) sb.Append("INSERT ");
if ((action & CARD_ACTION.CARD_ACTION_REINSERT) == CARD_ACTION.CARD_ACTION_REINSERT) sb.Append("REINSERT ");
if ((action & CARD_ACTION.CARD_ACTION_REMOVE) == CARD_ACTION.CARD_ACTION_REMOVE) sb.Append("REMOVE ");
if ((action & CARD_ACTION.CARD_ACTION_SWIPE) == CARD_ACTION.CARD_ACTION_SWIPE) sb.Append("SWIPE ");
if ((action & CARD_ACTION.CARD_ACTION_SWIPE_AGAIN) == CARD_ACTION.CARD_ACTION_SWIPE_AGAIN) sb.Append("SWIPE_AGAIN ");
if ((action & CARD_ACTION.CARD_ACTION_TAP) == CARD_ACTION.CARD_ACTION_TAP) sb.Append("TAP ");
if ((action & CARD_ACTION.CARD_ACTION_TAP_AGAIN) == CARD_ACTION.CARD_ACTION_TAP_AGAIN) sb.Append("TAP_AGAIN ");
SetOutputText(sb.ToString() + "\n");
}
break;
case DeviceState.MSRDecodeError:
//Awaiting a swipe for IDT_DEVICE_TYPES type
SetOutputText("Callback:MSRDecodeError\n");
break;
case DeviceState.SwipeTimeout:
//Waiting for swipe timed out
SetOutputText("Callback:SwipeTimeout\n");
break;
case DeviceState.TransactionCancelled:
//Transaction has been cancelled
SetOutputText("Callback:TransactionCancelled\n");
break;
case DeviceState.TransactionFailed:
//Transaction failed to complete
SetOutputText("Callback:TransactionFailed\n");
break;
case DeviceState.EMVCallback:
//Callback during EMV transaction retrieved from EMV_Callback emvCallback
SetOutputText("Callback:EMVCallback\n");
break;
default:
break;
}
}
private void displayCardData(IDTTransactionData cardData)
{
string text = "";
if (cardData.Event == EVENT_TRANSACTION_DATA_Types.EVENT_TRANSACTION_DATA_CARD_DATA)
{
SetOutputText("Data received: (Length [" + cardData.msr_rawData.Length.ToString() + "])\n" + string.Concat(cardData.msr_rawData.ToArray().Select(b => b.ToString("X2")).ToArray()) + "\r\n");
System.Diagnostics.Debug.WriteLine("Data received: (Length [" + cardData.msr_rawData.Length.ToString() + "])\n" + string.Concat(cardData.msr_rawData.ToArray().Select(b => b.ToString("X2")).ToArray()));
}
if (cardData.device_RSN != null && cardData.device_RSN.Length > 0)
text += "Serial Number: " + cardData.device_RSN + "\r\n";
if (cardData.msr_track1Length > 0)
text += "Track 1: " + cardData.msr_track1 + "\r\n";
if (cardData.msr_encTrack1 != null)
text += "Track 1 Encrypted: " + Common.getHexStringFromBytes(cardData.msr_encTrack1) + "\r\n";
if (cardData.msr_hashTrack1 != null)
text += "Track 1 Hash: " + Common.getHexStringFromBytes(cardData.msr_hashTrack1) + "\r\n";
if (cardData.msr_track2Length > 0)
text += "Track 2: " + cardData.msr_track2 + "\r\n";
if (cardData.msr_encTrack2 != null)
text += "Track 2 Encrypted: " + Common.getHexStringFromBytes(cardData.msr_encTrack2) + "\r\n";
if (cardData.msr_hashTrack2 != null)
text += "Track 2 Hash: " + Common.getHexStringFromBytes(cardData.msr_hashTrack2) + "\r\n";
if (cardData.msr_track3Length > 0)
text += "Track 3: " + cardData.msr_track3 + "\r\n";
if (cardData.msr_encTrack3 != null)
text += "Track 3 Encrypted: " + Common.getHexStringFromBytes(cardData.msr_encTrack3) + "\r\n";
if (cardData.msr_hashTrack3 != null)
text += "Track 3 Hash: " + Common.getHexStringFromBytes(cardData.msr_hashTrack3) + "\r\n";
if (cardData.msr_KSN != null)
text += "KSN: " + Common.getHexStringFromBytes(cardData.msr_KSN) + "\r\n";
if (cardData.emv_clearingRecord != null)
{
if (cardData.emv_clearingRecord.Length > 0)
{
text += "\r\nCTLS Clearing Record: \r\n";
text += Common.getHexStringFromBytes(cardData.emv_clearingRecord) + "\r\n";
Dictionary<string, string> dict = Common.processTLVUnencrypted(cardData.emv_clearingRecord);
foreach (KeyValuePair<string, string> kvp in dict) text += kvp.Key + ": " + kvp.Value + "\r\n";
text += "\r\n\r\n";
}
}
if (cardData.emv_unencryptedTags != null)
{
if (cardData.emv_unencryptedTags.Length > 0)
{
text += "\r\n======================== \r\n";
text += "\r\nUnencrypted Tags: \r\n";
text += Common.getHexStringFromBytes(cardData.emv_unencryptedTags) + "\r\n\r\n";
text += tlvToValues(cardData.emv_unencryptedTags);
text += "\r\n======================== \r\n";
}
}
if (cardData.emv_encryptedTags != null)
{
if (cardData.emv_encryptedTags.Length > 0)
{
text += "\r\n======================== \r\n";
text += "\r\nEncrypted Tags: \r\n";
text += Common.getHexStringFromBytes(cardData.emv_encryptedTags) + "\r\n\r\n";
text += tlvToValues(cardData.emv_encryptedTags);
text += "\r\n======================== \r\n";
}
}
if (cardData.emv_maskedTags != null)
{
if (cardData.emv_maskedTags.Length > 0)
{
text += "\r\n======================== \r\n";
text += "\r\nMasked Tags: \r\n";
text += Common.getHexStringFromBytes(cardData.emv_maskedTags) + "\r\n\r\n";
text += tlvToValues(cardData.emv_maskedTags);
text += "\r\n======================== \r\n";
}
}
if (cardData.emv_hasAdvise) text += "CARD RESPONSE HAS ADVISE" + "\r\n";
if (cardData.emv_hasReversal) text += "CARD RESPONSE HAS REFERSAL" + "\r\n";
if (cardData.iccPresent == 1) text += "ICC Present: TRUE" + "\r\n";
if (cardData.iccPresent == 2) text += "ICC Present: FALSE" + "\r\n";
if (cardData.isCTLS == 1) text += "CTLS Capture: TRUE" + "\r\n";
if (cardData.isCTLS == 2) text += "CTLS Capture: FALSE" + "\r\n";
if (cardData.msr_extendedField != null && cardData.msr_extendedField.Length > 0)
text += "Extended Field Bytes: " + Common.getHexStringFromBytes(cardData.msr_extendedField) + "\r\n";
if (cardData.captureEncryptType == CAPTURE_ENCRYPT_TYPE.CAPTURE_ENCRYPT_TYPE_TDES)
text += "Encryption Type: TDES\r\n";
if (cardData.captureEncryptType == CAPTURE_ENCRYPT_TYPE.CAPTURE_ENCRYPT_TYPE_AES)
text += "Encryption Type: AES\r\n";
if (cardData.captureEncryptType == CAPTURE_ENCRYPT_TYPE.CAPTURE_ENCRYPT_TYPE_NONE)
text += "Encryption Type: NONE\r\n";
if (cardData.captureEncryptType != CAPTURE_ENCRYPT_TYPE.CAPTURE_ENCRYPT_TYPE_NONE)
{
if (cardData.msr_keyVariantType == KEY_VARIANT_TYPE.KEY_VARIANT_TYPE_DATA)
text += "Key Type: Data Variant\r\n";
else if (cardData.msr_keyVariantType == KEY_VARIANT_TYPE.KEY_VARIANT_TYPE_PIN)
text += "Key Type: PIN Variant\r\n";
}
if (cardData.mac != null)
text += "MAC: " + Common.getHexStringFromBytes(cardData.mac) + "\r\n";
if (cardData.macKSN != null)
text += "MAC KSN: " + Common.getHexStringFromBytes(cardData.macKSN) + "\r\n";
if (cardData.Event == EVENT_TRANSACTION_DATA_Types.EVENT_TRANSACTION_DATA_EMV_DATA)
{
if ((cardData.isCTLS != 1) && (cardData.captureEncryptType != CAPTURE_ENCRYPT_TYPE.CAPTURE_ENCRYPT_TYPE_NONE)) text += "Capture Encrypt Type: " + ((cardData.captureEncryptType == CAPTURE_ENCRYPT_TYPE.CAPTURE_ENCRYPT_TYPE_TDES) ? "TDES" : "AES") + "\r\n";
switch (cardData.emv_resultCode)
{
case EMV_RESULT_CODE.EMV_RESULT_CODE_APPROVED:
text += ("EMV RESULT: " + "EMV_RESULT_CODE_APPROVED" + "\r\n");
break;
case EMV_RESULT_CODE.EMV_RESULT_CODE_APPROVED_OFFLINE:
text += ("EMV RESULT: " + "EMV_RESULT_CODE_APPROVED_OFFLINE" + "\r\n");
break;
case EMV_RESULT_CODE.EMV_RESULT_CODE_DECLINED_OFFLINE:
text += ("EMV RESULT: " + "EMV_RESULT_CODE_DECLINED_OFFLINE" + "\r\n");
break;
case EMV_RESULT_CODE.EMV_RESULT_CODE_DECLINED:
text += ("EMV RESULT: " + "EMV_RESULT_CODE_DECLINED" + "\r\n");
break;
case EMV_RESULT_CODE.EMV_RESULT_CODE_GO_ONLINE:
text += ("EMV RESULT: " + "EMV_RESULT_CODE_GO_ONLINE" + "\r\n");
break;
case EMV_RESULT_CODE.EMV_RESULT_CODE_CALL_YOUR_BANK:
text += ("EMV RESULT: " + "EMV_RESULT_CODE_CALL_YOUR_BANK" + "\r\n");
break;
case EMV_RESULT_CODE.EMV_RESULT_CODE_NOT_ACCEPTED:
text += ("EMV RESULT: " + "EMV_RESULT_CODE_NOT_ACCEPTED" + "\r\n");
break;
case EMV_RESULT_CODE.EMV_RESULT_CODE_FALLBACK_TO_MSR:
text += ("EMV RESULT: " + "EMV_RESULT_CODE_FALLBACK_TO_MSR" + "\r\n");
break;
case EMV_RESULT_CODE.EMV_RESULT_CODE_TIMEOUT:
text += ("EMV RESULT: " + "EMV_RESULT_CODE_TIMEOUT" + "\r\n");
break;
case EMV_RESULT_CODE.EMV_RESULT_CODE_AUTHENTICATE_TRANSACTION:
text += ("EMV RESULT: " + "EMV_RESULT_CODE_AUTHENTICATE_TRANSACTION" + "\r\n");
break;
case EMV_RESULT_CODE.EMV_RESULT_CODE_SWIPE_NON_ICC:
text += ("EMV RESULT: " + "EMV_RESULT_CODE_SWIPE_NON_ICC" + "\r\n");
break;
case EMV_RESULT_CODE.EMV_RESULT_CODE_CTLS_TWO_CARDS:
text += ("EMV RESULT: " + "EMV_RESULT_CODE_CTLS_TWO_CARDS" + "\r\n");
break;
case EMV_RESULT_CODE.EMV_RESULT_CODE_CTLS_TERMINATE:
text += ("EMV RESULT: " + "EMV_RESULT_CODE_CTLS_TERMINATE" + "\r\n");
break;
case EMV_RESULT_CODE.EMV_RESULT_CODE_CTLS_TERMINATE_TRY_ANOTHER:
text += ("EMV RESULT: " + "EMV_RESULT_CODE_CTLS_TERMINATE_TRY_ANOTHER" + "\r\n");
break;
}
}
SetOutputText(text);
}
private string tlvToValues(byte[] tlv)
{
string text = "";
Dictionary<string, string> dict = Common.processTLVUnencrypted(tlv);
foreach (KeyValuePair<string, string> kvp in dict) text += kvp.Key + ": " + kvp.Value + "\r\n";
return text;
}
delegate void SetTextCallback(string text);
private void SetOutputText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (tbOutput.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetOutputText);
Invoke(d, new object[] { text });
}
else
{
try { tbOutput.AppendText(text + "\r\n"); } catch (Exception ex) { }
}
}
private void SetOutputTextLog(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (logOutput.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetOutputTextLog);
Invoke(d, new object[] { text });
}
else
{
try { logOutput.AppendText(text + "\r\n"); }
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Exception: " + ex);
}
}
}