<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#aaaaaa"
android:orientation="vertical" >
<TextView
android:id="@+id/status_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#000000"
android:gravity="center_vertical|center_horizontal"
android:text="UNIPAY DISCONNECTED"
android:textColor="#FFFFFF" />
<LinearLayout
android:id="@+id/linearLayoutBottom2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/btn_Connect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.53"
android:gravity="center_vertical|center_horizontal"
android:text="Connect" />
<Button
android:id="@+id/btn_Disconnect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.53"
android:text="Disconnect" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayoutEditText"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#dddddd"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical" >
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:background="#ffffff" >
<TextView
android:id="@+id/textLog"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text=""
android:textColor="#000000"
android:textSize="12sp"
android:typeface="monospace" >
</TextView>
</ScrollView>
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayoutBottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/btn_getFirmware"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.53"
android:gravity="center_vertical|center_horizontal"
android:text="Get Firm" />
<Button
android:id="@+id/btn_startSwipe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.53"
android:text="Start Swipe" />
<Button
android:id="@+id/btn_cancelSwipe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.53"
android:text="Cancel Swipe" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayoutBottom2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/btn_startEMV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.53"
android:gravity="center_vertical|center_horizontal"
android:text="Start EMV" />
<Button
android:id="@+id/btn_cancelEMV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.53"
android:text="Cancel EMV" />
<Button
android:id="@+id/btn_completeEMV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.53"
android:text="Complete Online" />
</LinearLayout>
</LinearLayout>
public void emvTransactionMessage(MESSAGE_Types message){
switch (message) {
case MESSAGE_INSERT_OR_SWIPE_CARD:
appendMessageToResults("PLEASE INSERT OR SWIPE CARD");
break;
case MESSAGE_REMOVE_CARD:
appendMessageToResults("PLEASE REMOVE CARD");
break;
case MESSAGE_BAD_ICC:
appendMessageToResults("CHIP READ ERROR-USE MSR\nPLEASE REMOVE CARD");
break;
case MESSAGE_TRANSACTION_CANCELLED:
appendMessageToResults("TRANSACTION CANCELLED");
break;
case MESSAGE_FALLBACK_FAILED:
appendMessageToResults("FALLBACK FAILED");
break;
case MESSAGE_USE_CHIP_READER:
appendMessageToResults("MUST USE ICC READER");
break;
case MESSAGE_PROCESSING:
appendMessageToResults("PROCESSING");
break;
case MESSAGE_READY:
appendMessageToResults("UniPay Ready");
break;
case MESSAGE_USE_MSR:
appendMessageToResults("Please Swipe Card");
break;
case MESSAGE_SDK_ERROR:
appendMessageToResults("SDK Error: " + String.valueOf(myUniPayEMV.getLastSDKError()));
break;
case MESSAGE_NOT_ACCEPTED:
appendMessageToResults("Not Accepted");
break;
default:
break;
}
}
public void swipeMSRDataEMV(IDTMSRData card, Map<String, byte[]> tags) {
StringBuilder sb = new StringBuilder();
sb.append("Swipe Data Captured for EMV transaction\n");
sb.append("Track 1: ");
if (card.track1 != null) if (card.track1.length() > 0) sb.append(card.track1);
sb.append("\nTrack 2: ");
if (card.track2 != null) if (card.track2.length() > 0) sb.append(card.track2);
sb.append("\nTrack 3: ");
if (card.track3 != null) if (card.track3.length() > 0) sb.append(card.track3);
sb.append("\n");
if (card.encTrack1 != null) if (card.encTrack1.length > 0) sb.append("Enc. Track 1: " + getHexStringFromBytes(card.encTrack1) + "\n");
if (card.encTrack2 != null) if (card.encTrack2.length > 0) sb.append("Enc. Track 2: " + getHexStringFromBytes(card.encTrack2) + "\n");
if (card.encTrack3 != null) if (card.encTrack3.length > 0) sb.append("Enc. Track 3: " + getHexStringFromBytes(card.encTrack3) + "\n");
if (card.serialNumber != null) if (card.serialNumber.length() > 0) sb.append("Serial Nunber: " + card.serialNumber + "\n");
if (card.KSN != null) if (card.KSN.length > 0) sb.append("KSN: " + getHexStringFromBytes(card.KSN) + "\n");
sb.append("\n");
sb.append("Tags:\n");
for (Map.Entry<String, byte[]> entry : tags.entrySet())
{
sb.append(entry.getKey() + ": " + getHexStringFromBytes(entry.getValue()));
sb.append("\n");
}
}
public void emvTransactionData(IDTEMVData emvData, UniPayEMV.EMV_RESULT_CODE_Types errorCode, boolean performReversal) {
byte[] b = {0};
if (emvData != null){
if (emvData.unencryptedTags != null){
b = emvData.unencryptedTags.get("9F27");
if (b[0] == 0x01) {
appendMessageToResults("ERROR: SERVICE NOT ALLOWED");
return;
}
}
}
if (performReversal) {
appendMessageToResults("WARNING: TRANSACTIONS WAS APPROVED ONLINE, BUT TERMINAL DECLINED. PLEASE REVERSE/VOID ONLINE APPROVAL FOR THIS TRANSACTION");
}
boolean isError = errorCode.toString().startsWith("EMV_RESULT_CODE_ERROR");
if (!isError) {
appendMessageToResults("");
appendMessageToResults("GENERATE AC RESULTS");
}
else {
appendMessageToResults("ERROR: TRANSACTION TERMINATED");
if (errorCode == UniPayEMV.EMV_RESULT_CODE_Types.EMV_RESULT_CODE_ERROR_EMV_SERVICE_NOT_ALLOWED) {
appendMessageToResults("NOT ACCEPTED");
}
appendMessageToResults("Result = " + errorCode.toString());
return;
}
if ((errorCode == UniPayEMV.EMV_RESULT_CODE_Types.EMV_RESULT_CODE_GO_ONLINE) || (b[0] == 0x88) || (b[0] == 0x8B) || (b[0] == 0x8A)) {
appendMessageToResults("Financial Transaction Request:");
appendMessageToResults("GO ONLINE");
}
else{
byte cvm[] = null;
byte tvr[] = null;
byte tsi[] = null;
if (emvData != null){
if (emvData.unencryptedTags != null){
cvm = emvData.unencryptedTags.get("9F34");
tvr = emvData.unencryptedTags.get("95");
tsi = emvData.unencryptedTags.get("9B");
}
}
String cvmString = "";
String tvrString = "";
String tsiString = "";
if (cvm != null) cvmString = getHexStringFromBytes(cvm);
if (tvr != null) tvrString = getHexStringFromBytes(tvr);
if (tsi != null) tsiString = getHexStringFromBytes(tsi);
String results = "SUCCESS - TC";
if ((b[0] & 0xf0) == 0) {
results = "DECLINE - AAC";
appendMessageToResults("Financial Transaction Confirmation:");
}
}
if (emvData != null){
if (emvData.unencryptedTags != null){
Map<String, byte[]> treeMap = new TreeMap<String, byte[]>(emvData.unencryptedTags);
appendMessageToResults("Tags:\n" + mapDescription(treeMap));
}
if (emvData.encryptedTags != null){
Map<String, byte[]> treeMap = new TreeMap<String, byte[]>(emvData.encryptedTags);
appendMessageToResults("Encrypted Tags:\n" + mapDescription(treeMap));
}
if (emvData.maskedTags != null){
Map<String, byte[]> treeMap = new TreeMap<String, byte[]>(emvData.maskedTags);
appendMessageToResults("Masked Tags:\n" + mapDescription(treeMap));
}
}
}
package com.example.unipay_tutorial;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Map;
import java.util.TreeMap;
import java.util.Vector;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.idtechproducts.device.*;
import com.idtechproducts.device.ReaderInfo.CAPTURE_ENCODE_TYPE;
import com.idtechproducts.device.ReaderInfo.CAPTURE_ENCRYPT_TYPE;
import com.idtechproducts.device.ReaderInfo.DEVICE_INTERFACE_Types;
import com.idtechproducts.device.ReaderInfo.EVENT_MSR_Types;
import com.idtechproducts.emv.UniPayEMV;
import com.idtechproducts.emv.UniPayEMV.EMV_COMPLETION_RESULT;
import com.idtechproducts.emv.UniPayEMV.IDTEMVData;
import com.idtechproducts.emv.UniPayEMV.MESSAGE_Types;
public class MainActivity extends Activity implements OnReceiverListener, UniPayEMV.UniPayEMVDelegate {
private IDT_Device myUniPayReader = null;
private TextView connectStatusTextView;
private TextView textLog;
private Button btnConnect;
private Button btnDisconnect;
private Button btnGetFirmware;
private Button btnStartSwipe;
private Button btnCancelSwipe;
private Button btnStartEMV;
private Button btnCancelEMV;
private Button btnCompleteEMV;
private Handler handler = new Handler();
private boolean isReaderConnected = false;
private String strCard = "";
private UniPayEMV myUniPayEMV = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler();
btnStartEMV = (Button)findViewById(R.id.btn_startEMV);
btnCancelEMV = (Button)findViewById(R.id.btn_cancelEMV);
btnCompleteEMV = (Button)findViewById(R.id.btn_completeEMV);
btnConnect = (Button)findViewById(R.id.btn_Connect);
btnDisconnect = (Button)findViewById(R.id.btn_Disconnect);
btnGetFirmware = (Button)findViewById(R.id.btn_getFirmware);
btnStartSwipe = (Button)findViewById(R.id.btn_startSwipe);
btnCancelSwipe = (Button)findViewById(R.id.btn_cancelSwipe);
textLog = (TextView)findViewById(R.id.textLog);
connectStatusTextView = (TextView)findViewById(R.id.status_text);
if(myUniPayReader!=null){
myUniPayReader.unregisterListen();
myUniPayReader.release();
myUniPayReader = null;
}
myUniPayReader = new IDT_Device(this,this);
myUniPayReader.registerListen();
loadXMLfile();
if(myUniPayEMV!=null){
myUniPayEMV = null;
}
myUniPayEMV = new UniPayEMV(this,myUniPayReader,this);
btnConnect.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
myUniPayReader.device_connect();
}
});
btnDisconnect.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
myUniPayReader.device_disconnect();
}
});
btnStartEMV.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
String str = new String();
myUniPayEMV.startEMVTransaction(1.00, 30, 0, null);
str = "Start EMV Executing";
textLog.setText(str);
}
});
btnCancelEMV.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
String str = new String();
myUniPayEMV.cancelTransaction();
str = "Cancel EMV Sent";
textLog.setText(str);
}
});
btnCompleteEMV.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
String str = new String();
myUniPayEMV.completeOnlineEMVTransaction(EMV_COMPLETION_RESULT.EMV_COMPLETION_RESULT_ACCEPTED, "00", "11223344556677883030", "");
str = "Complete EMV Sent";
textLog.setText(str);
}
});
btnStartSwipe.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
String str = new String();
int res = myUniPayReader.msr_startMSRSwipe();
if(res == 0)
{
str = "Start to MSR Swipe successfully,please swipe card.";
}
else
str = myUniPayReader.device_getResponseCodeString(res);
textLog.setText(str);
}
});
btnCancelSwipe.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
String str = new String();
int res = myUniPayReader.msr_cancelMSRSwipe();
if(res == 0)
{
str = "End to MSR Swipe successfully.";
}
else
str = myUniPayReader.device_getResponseCodeString(res);
textLog.setText(str);
}
});
btnGetFirmware.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
StringBuilder version = new StringBuilder();
int res = myUniPayReader.device_getFirmwareVersion(version);
String str = new String();
if(res == 0)
{
str = "Firmware = " + version.toString();
}
else
str = myUniPayReader.device_getResponseCodeString(res);
textLog.setText(str);
}
});
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().setFlags(WindowManager.LayoutParams. FLAG_FULLSCREEN, WindowManager.LayoutParams. FLAG_FULLSCREEN);
myUniPayReader.log_setVerboseLoggingEnable(true);
}
private String getXMLFileFromRaw(String fileName ,int res){
String fileNameWithPath = null;
fileNameWithPath = fileName;
String newFilename = fileName;
try {
InputStream in = getResources().openRawResource(res);
int length = in.available();
byte [] buffer = new byte[length];
in.read(buffer);
in.close();
deleteFile(fileNameWithPath);
FileOutputStream fout = openFileOutput(fileNameWithPath, MODE_PRIVATE);
fout.write(buffer);
fout.close();
File fileDir = this.getFilesDir();
fileNameWithPath = fileDir.getParent() + java.io.File.separator + fileDir.getName();
fileNameWithPath += java.io.File.separator+newFilename;
} catch(Exception e){
e.printStackTrace();
fileNameWithPath = null;
}
return fileNameWithPath;
}
private String getConfigurationFileFromRaw( ){
return getXMLFileFromRaw("idt_unimagcfg_default.xml",R.raw.idt_unimagcfg_default);
}
private boolean isFileExist(String path) {
if(path==null)
return false;
File file = new File(path);
if (!file.exists()) {
return false ;
}
return true;
}
private void loadXMLfile(){
String fileNameWithPath = getConfigurationFileFromRaw();
if(!isFileExist(fileNameWithPath)) {
fileNameWithPath = null;
}
myUniPayReader.config_setXMLFileNameWithPath(fileNameWithPath);
Log.d("Demo Info >>>>>","loadingConfigurationXMLFile begin.");
myUniPayReader.config_loadingConfigurationXMLFile(true);
}
private Runnable doUpdateStatus = new Runnable()
{
public void run()
{
if(!isReaderConnected){
connectStatusTextView.setText("UNIPAY DISCONNECTED");
}
else{
connectStatusTextView.setText("UNIPAY CONNECTED");
}
}
};
@Override
public void deviceConnected() {
isReaderConnected = true;
handler.post(doUpdateStatus);
}
@Override
public void deviceDisconnected() {
isReaderConnected = false;
handler.post(doUpdateStatus);
}
@Override
public void AutoConfigCompleted(StructConfigParameters arg0) {
}
@Override
public void AutoConfigProgress(int arg0) {
}
@Override
public void ICCNotifyInfo(byte[] arg0, String arg1) {
}
@Override
public void LoadXMLConfigFileInfo(int arg0, String arg1) {
}
@Override
public boolean getUserGrant(USER_GRANT_TYPE arg0, String arg1) {
return false;
}
@Override
public void msgAudioVolumeAjustFailed(String arg0) {
}
@Override
public void msgToConnectDevice() {
}
@Override
public void plugStatusChange(DEVICE_INTERFACE_Types interfaceType, boolean deviceInserted) {
}
private Runnable m_CardRunnable = new Runnable()
{
public void run()
{
textLog.setText(strCard);
}
};
public void swipeMSRData(IDTMSRData card)
{
String str = new String();
if( card.event == EVENT_MSR_Types.EVENT_MSR_CARD_DATA ||card.event == EVENT_MSR_Types.EVENT_MSR_DATA_ERROR)
{
int len = card.cardData.length;
int i = 0;
str = "CardData:\r\n";
for(i = 0; i < len; i++)
{
str += String.format("%02x ", card.cardData[i]);
}
if(card.track1 != "")
{
str += "\r\nTrack1 data:\r\n";
str += card.track1;
}
if(card.track2 != "")
{
str += "\r\nTrack2 data:\r\n";
str += card.track2;
}
if(card.track3 != "")
{
str += "\r\nTrack3 data:\r\n";
str += card.track3;
}
len = card.encTrack1.length;
if(len > 0)
{
str += "\r\nTrack1 encrypted data:\r\n";
for(i = 0; i < len; i++)
{
str += String.format("%02X", card.encTrack1[i]);
}
}
len = card.encTrack2.length;
if(len > 0)
{
str += "\r\nTrack2 encrypted data:\r\n";
for(i = 0; i < len; i++)
{
str += String.format("%02X", card.encTrack2[i]);
}
}
len = card.encTrack3.length;
if(len > 0)
{
str += "\r\nTrack3 encrypted data:\r\n";
for(i = 0; i < len; i++)
{
str += String.format("%02X", card.encTrack3[i]);
}
}
len = card.KSN.length;
if(len > 0)
{
str += "\r\nKSN:";
for(i = 0; i < len; i++)
{
str += String.format("%02x ", card.KSN[i]);
}
}
str += "\r\nCard Type:";
if(card.cardType == CAPTURE_ENCODE_TYPE.CAPTURE_ENCODE_TYPE_ISOABA)
str += String.format("ISO 7813/ISO 4909/ABA format.");
else if(card.cardType == CAPTURE_ENCODE_TYPE.CAPTURE_ENCODE_TYPE_AAMVA)
str += String.format("AAMVA format.");
else if(card.cardType == CAPTURE_ENCODE_TYPE.CAPTURE_ENCODE_TYPE_Raw)
str += String.format("Raw; un-decoded format.");
else if(card.cardType == CAPTURE_ENCODE_TYPE.CAPTURE_ENCODE_TYPE_JisI_II)
str += String.format("JIS I or JIS II.");
else
str += String.format("Other format.");
str += "\r\nEncode Status:";
str += String.format("%02x ", card.captureEncodeStatus);
str += "\r\nEncrypt Type:";
if(card.captureEncryptType == CAPTURE_ENCRYPT_TYPE.CAPTURE_ENCRYPT_TYPE_TDES)
str += String.format("TDES");
if(card.captureEncryptType == CAPTURE_ENCRYPT_TYPE.CAPTURE_ENCRYPT_TYPE_AES)
str += String.format("AES");
if(card.captureEncryptType == CAPTURE_ENCRYPT_TYPE.CAPTURE_ENCRYPT_TYPE_NONE)
str += String.format("None");
if(card.serialNumber != "")
{
str += "\r\nReader Serial Number:";
str += card.serialNumber;
}
}
else if(card.event == EVENT_MSR_Types.EVENT_MSR_BACKSPACE_KEY)
str = "Press Backspace Key.";
else if(card.event == EVENT_MSR_Types.EVENT_MSR_CANCEL_KEY)
str = "Press Cancel Key.";
else if(card.event == EVENT_MSR_Types.EVENT_MSR_ENTER_KEY)
str = "Press Enter Key.";
else
{
str = "Swipe Card error, error code is ";
str += String.format("%02X %02X ", card.cardData[0],card.cardData[1]);
}
strCard = str;
handler.post(m_CardRunnable);
}
@Override
public void timeout(String arg0) {
}
@Override
public void confirmApplicationSelection(Vector<String> arg0, boolean arg1) {
}
@Override
public void languagePreference(byte[] arg0) {
}
private String getHexStringFromBytes(byte []data)
{
if(data==null) return null;
if(data.length<=0)
return null;
StringBuffer hexString = new StringBuffer();
String fix = null;
for (int i = 0; i < data.length; i++) {
fix = Integer.toHexString(0xFF & data[i]);
if(fix.length()==1)
fix = "0"+fix;
hexString.append(fix);
}
fix = null;
fix = hexString.toString();
return fix;
}
private void appendMessageToResults(String str){
final String result = str + "\n";
runOnUiThread(new Runnable() {
public void run() {
textLog.append(result);
}
});
}
public void emvTransactionMessage(MESSAGE_Types message){
switch (message) {
case MESSAGE_INSERT_OR_SWIPE_CARD:
appendMessageToResults("PLEASE INSERT OR SWIPE CARD");
break;
case MESSAGE_REMOVE_CARD:
appendMessageToResults("PLEASE REMOVE CARD");
break;
case MESSAGE_BAD_ICC:
appendMessageToResults("CHIP READ ERROR-USE MSR\nPLEASE REMOVE CARD");
break;
case MESSAGE_TRANSACTION_CANCELLED:
appendMessageToResults("TRANSACTION CANCELLED");
break;
case MESSAGE_FALLBACK_FAILED:
appendMessageToResults("FALLBACK FAILED");
break;
case MESSAGE_USE_CHIP_READER:
appendMessageToResults("MUST USE ICC READER");
break;
case MESSAGE_PROCESSING:
appendMessageToResults("PROCESSING");
break;
case MESSAGE_READY:
appendMessageToResults("UniPay Ready");
break;
case MESSAGE_USE_MSR:
appendMessageToResults("Please Swipe Card");
break;
case MESSAGE_SDK_ERROR:
appendMessageToResults("SDK Error: " + String.valueOf(myUniPayEMV.getLastSDKError()));
break;
case MESSAGE_NOT_ACCEPTED:
appendMessageToResults("Not Accepted");
break;
default:
break;
}
}
public void swipeMSRDataEMV(IDTMSRData card, Map<String, byte[]> tags) {
StringBuilder sb = new StringBuilder();
sb.append("Swipe Data Captured for EMV transaction\n");
sb.append("Track 1: ");
if (card.track1 != null) if (card.track1.length() > 0) sb.append(card.track1);
sb.append("\nTrack 2: ");
if (card.track2 != null) if (card.track2.length() > 0) sb.append(card.track2);
sb.append("\nTrack 3: ");
if (card.track3 != null) if (card.track3.length() > 0) sb.append(card.track3);
sb.append("\n");
if (card.encTrack1 != null) if (card.encTrack1.length > 0) sb.append("Enc. Track 1: " + getHexStringFromBytes(card.encTrack1) + "\n");
if (card.encTrack2 != null) if (card.encTrack2.length > 0) sb.append("Enc. Track 2: " + getHexStringFromBytes(card.encTrack2) + "\n");
if (card.encTrack3 != null) if (card.encTrack3.length > 0) sb.append("Enc. Track 3: " + getHexStringFromBytes(card.encTrack3) + "\n");
if (card.serialNumber != null) if (card.serialNumber.length() > 0) sb.append("Serial Nunber: " + card.serialNumber + "\n");
if (card.KSN != null) if (card.KSN.length > 0) sb.append("KSN: " + getHexStringFromBytes(card.KSN) + "\n");
sb.append("\n");
sb.append("Tags:\n");
for (Map.Entry<String, byte[]> entry : tags.entrySet())
{
sb.append(entry.getKey() + ": " + getHexStringFromBytes(entry.getValue()));
sb.append("\n");
}
}
public void emvTransactionData(IDTEMVData emvData, UniPayEMV.EMV_RESULT_CODE_Types errorCode, boolean performReversal) {
byte[] b = {0};
if (emvData != null){
if (emvData.unencryptedTags != null){
b = emvData.unencryptedTags.get("9F27");
if (b[0] == 0x01) {
appendMessageToResults("ERROR: SERVICE NOT ALLOWED");
return;
}
}
}
if (performReversal) {
appendMessageToResults("WARNING: TRANSACTIONS WAS APPROVED ONLINE, BUT TERMINAL DECLINED. PLEASE REVERSE/VOID ONLINE APPROVAL FOR THIS TRANSACTION");
}
boolean isError = errorCode.toString().startsWith("EMV_RESULT_CODE_ERROR");
if (!isError) {
appendMessageToResults("");
appendMessageToResults("GENERATE AC RESULTS");
}
else {
appendMessageToResults("ERROR: TRANSACTION TERMINATED");
if (errorCode == UniPayEMV.EMV_RESULT_CODE_Types.EMV_RESULT_CODE_ERROR_EMV_SERVICE_NOT_ALLOWED) {
appendMessageToResults("NOT ACCEPTED");
}
appendMessageToResults("Result = " + errorCode.toString());
return;
}
if ((errorCode == UniPayEMV.EMV_RESULT_CODE_Types.EMV_RESULT_CODE_GO_ONLINE) || (b[0] == 0x88) || (b[0] == 0x8B) || (b[0] == 0x8A)) {
appendMessageToResults("Financial Transaction Request:");
appendMessageToResults("GO ONLINE");
}
else{
byte cvm[] = null;
byte tvr[] = null;
byte tsi[] = null;
if (emvData != null){
if (emvData.unencryptedTags != null){
cvm = emvData.unencryptedTags.get("9F34");
tvr = emvData.unencryptedTags.get("95");
tsi = emvData.unencryptedTags.get("9B");
}
}
String cvmString = "";
String tvrString = "";
String tsiString = "";
if (cvm != null) cvmString = getHexStringFromBytes(cvm);
if (tvr != null) tvrString = getHexStringFromBytes(tvr);
if (tsi != null) tsiString = getHexStringFromBytes(tsi);
String results = "SUCCESS - TC";
if ((b[0] & 0xf0) == 0) {
results = "DECLINE - AAC";
appendMessageToResults("Financial Transaction Confirmation:");
}
}
if (emvData != null){
if (emvData.unencryptedTags != null){
Map<String, byte[]> treeMap = new TreeMap<String, byte[]>(emvData.unencryptedTags);
appendMessageToResults("Tags:\n" + mapDescription(treeMap));
}
if (emvData.encryptedTags != null){
Map<String, byte[]> treeMap = new TreeMap<String, byte[]>(emvData.encryptedTags);
appendMessageToResults("Encrypted Tags:\n" + mapDescription(treeMap));
}
if (emvData.maskedTags != null){
Map<String, byte[]> treeMap = new TreeMap<String, byte[]>(emvData.maskedTags);
appendMessageToResults("Masked Tags:\n" + mapDescription(treeMap));
}
}
}
private String mapDescription(Map <String,byte[]> tags){
if (tags == null) return "";
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, byte[]> entry : tags.entrySet())
{
sb.append(entry.getKey() + ": " + getHexStringFromBytes(entry.getValue()));
sb.append("\n");
}
return sb.toString();
}
}