Using Visual Studio 2015, we will create a C# sample project that will interface with the Vendi and will perform the following activities:
Create a new Windows Form Application in Visual Studio. In our example, we use project name Vendi_Simple_Demo.
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:
SetOutputText("Callback:ToConnect\n");
break;
case DeviceState.DefaultDeviceTypeChange:
SetOutputText("Callback:DefaultDeviceTypeChange\n");
break;
case DeviceState.Connected:
SetOutputText("Callback:Connected\n");
break;
case DeviceState.Disconnected:
SetOutputText("Callback:Disconnected\n");
break;
case DeviceState.ConnectionFailed:
SetOutputText("Callback:ConnectionFailed\n");
break;
case DeviceState.TransactionData:
SetOutputText("Callback:TransactionData\n");
displayCardData(cardData);
break;
case DeviceState.DataReceived:
SetOutputTextLog(" IN: " + Common.getHexStringFromBytes(data));
break;
case DeviceState.DataSent:
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:
SetOutputText("Callback:MSRDecodeError\n");
break;
case DeviceState.SwipeTimeout:
SetOutputText("Callback:SwipeTimeout\n");
break;
case DeviceState.TransactionCancelled:
SetOutputText("Callback:TransactionCancelled\n");
break;
case DeviceState.TransactionFailed:
SetOutputText("Callback:TransactionFailed\n");
break;
case DeviceState.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)
{
text += ("EMV RESULT: " + "EMV_RESULT_CODE_APPROVED" + "\r\n");
break;
text += ("EMV RESULT: " + "EMV_RESULT_CODE_APPROVED_OFFLINE" + "\r\n");
break;
text += ("EMV RESULT: " + "EMV_RESULT_CODE_DECLINED_OFFLINE" + "\r\n");
break;
text += ("EMV RESULT: " + "EMV_RESULT_CODE_DECLINED" + "\r\n");
break;
text += ("EMV RESULT: " + "EMV_RESULT_CODE_GO_ONLINE" + "\r\n");
break;
text += ("EMV RESULT: " + "EMV_RESULT_CODE_CALL_YOUR_BANK" + "\r\n");
break;
text += ("EMV RESULT: " + "EMV_RESULT_CODE_NOT_ACCEPTED" + "\r\n");
break;
text += ("EMV RESULT: " + "EMV_RESULT_CODE_FALLBACK_TO_MSR" + "\r\n");
break;
text += ("EMV RESULT: " + "EMV_RESULT_CODE_TIMEOUT" + "\r\n");
break;
text += ("EMV RESULT: " + "EMV_RESULT_CODE_AUTHENTICATE_TRANSACTION" + "\r\n");
break;
text += ("EMV RESULT: " + "EMV_RESULT_CODE_SWIPE_NON_ICC" + "\r\n");
break;
text += ("EMV RESULT: " + "EMV_RESULT_CODE_CTLS_TWO_CARDS" + "\r\n");
break;
text += ("EMV RESULT: " + "EMV_RESULT_CODE_CTLS_TERMINATE" + "\r\n");
break;
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)
{
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)
{
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);
}
}
}