Compare commits

..

No commits in common. "cdb7bb73c5ee4fafe75a39c64d59d1c61982d0b3" and "3cb8fe218eceb05909d957c6e27709da491d9a1b" have entirely different histories.

34 changed files with 394 additions and 780 deletions

View File

@ -13,6 +13,7 @@
<option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/baselib" />
<option value="$PROJECT_DIR$/ecr" />
<option value="$PROJECT_DIR$/ecr-service" />
<option value="$PROJECT_DIR$/ecr-service-lib" />
<option value="$PROJECT_DIR$/link-service-lib" />
<option value="$PROJECT_DIR$/mpulib" />

View File

@ -204,7 +204,7 @@ dependencies {
// ECR Dependencies - Modern ECR Client Library
// implementation project(path: ':ecr-client-lib')
// implementation project(path: ':ecr-service-lib')
implementation project(path: ':ecr-service-lib')
// Core Libraries
implementation project(path: ':paylibs')

View File

@ -4,7 +4,6 @@ import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.NavDestination;
@ -473,86 +472,57 @@ public class MainActivity extends AppCompatActivity implements
private void handleAutoSettlementIntent(Intent intent) {
if (intent == null) return;
boolean hasPOS = intent.getBooleanExtra("AUTO_SETTLEMENT", false);
boolean hasQR = intent.getBooleanExtra("AUTO_QR_SETTLEMENT", false);
if (hasPOS) {
// Handle regular auto settlement
boolean auto = intent.getBooleanExtra("AUTO_SETTLEMENT", false);
if (auto) {
PayDetail payDetail = (PayDetail) intent.getSerializableExtra("EXTRA_PAY_DETAIL");
if (payDetail != null) {
sharedViewModel.payDetail.setValue(payDetail);
sharedViewModel.transactionsType.setValue(TransactionsType.SETTLEMENT);
sharedViewModel.setAmount(POSUtil.getInstance().getDecimalAmountSeparatorFormat(payDetail.getAmount()));
try {
navController.navigate(R.id.transactionResultFragment);
} catch (Exception e) {
LogUtil.e(TAG, "Navigation error: " + e.getMessage());
}
// If QR also exists, trigger it AFTER POS result is done
if (hasQR) {
navigateToQRSettlementAfterPOS(intent);
}
} else {
// POS had no data, go straight to QR if available
if (hasQR) {
handleQRSettlement(intent);
}
}
} else if (hasQR) {
// Only QR settlement, no POS
handleQRSettlement(intent);
return;
}
}
private void navigateToQRSettlementAfterPOS(Intent intent) {
// Observe transactionResultFragment's completion via ViewModel
// When POS result screen signals "done" (print complete / user dismissed),
// then navigate to QR result
sharedViewModel.onSettlementResultDone.observe(this, new Observer<Boolean>() {
@Override
public void onChanged(Boolean done) {
if (done != null && done) {
// Remove observer so it only fires once
sharedViewModel.onSettlementResultDone.removeObserver(this);
// Reset flag
sharedViewModel.onSettlementResultDone.postValue(false);
// Now navigate to QR
handleQRSettlement(intent);
}
// Handle QR auto settlement
boolean autoQR = intent.getBooleanExtra("AUTO_QR_SETTLEMENT", false);
if (autoQR) {
int qrSaleCount = intent.getIntExtra("QR_SALE_COUNT", 0);
long qrSaleAmount = intent.getLongExtra("QR_SALE_AMOUNT", 0L);
int qrRefundCount = intent.getIntExtra("QR_REFUND_COUNT", 0);
long qrRefundAmount = intent.getLongExtra("QR_REFUND_AMOUNT", 0L);
long totalAmount = intent.getLongExtra("QR_TOTAL_AMOUNT", 0L);
List<PayDetail> qrTransList = (List<PayDetail>) intent.getSerializableExtra("QR_TRANS_LIST");
// Create QR settlement PayDetail
SettleData settleData = new SettleData(
qrSaleCount, qrSaleAmount, 0, 0L, qrRefundCount, qrRefundAmount, 0, 0L);
TradeData tradeData = Params.newTrade(false);
PayDetail payDetail = tradeData.getPayDetail();
payDetail.setSettleDataObj(settleData);
payDetail.setTransactionType(TransactionsType.MMQR_SETTLEMENT.value);
payDetail.setTransType(TransactionsType.MMQR_SETTLEMENT.name);
payDetail.setAmount(totalAmount);
payDetail.setTradeAnswerCode("000");
sharedViewModel.setAmount(POSUtil.getInstance().getDecimalAmountSeparatorFormat(totalAmount));
sharedViewModel.payDetails.setValue(qrTransList);
sharedViewModel.payDetail.setValue(payDetail);
sharedViewModel.transactionsType.setValue(TransactionsType.MMQR_SETTLEMENT);
try {
navController.navigate(R.id.transactionResultFragment);
} catch (Exception e) {
LogUtil.e(TAG, "QR Auto Settlement navigation error: " + e.getMessage());
}
});
}
private void handleQRSettlement(Intent intent) {
int qrSaleCount = intent.getIntExtra("QR_SALE_COUNT", 0);
long qrSaleAmount = intent.getLongExtra("QR_SALE_AMOUNT", 0L);
int qrRefundCount = intent.getIntExtra("QR_REFUND_COUNT", 0);
long qrRefundAmount = intent.getLongExtra("QR_REFUND_AMOUNT", 0L);
long totalAmount = intent.getLongExtra("QR_TOTAL_AMOUNT", 0L);
List<PayDetail> qrTransList = (List<PayDetail>) intent.getSerializableExtra("QR_TRANS_LIST");
SettleData settleData = new SettleData(
qrSaleCount, qrSaleAmount, 0, 0L, qrRefundCount, qrRefundAmount, 0, 0L);
TradeData tradeData = Params.newTrade(false);
PayDetail payDetail = tradeData.getPayDetail();
payDetail.setSettleDataObj(settleData);
payDetail.setTransactionType(TransactionsType.MMQR_SETTLEMENT.value);
payDetail.setTransType(TransactionsType.MMQR_SETTLEMENT.name);
payDetail.setAmount(totalAmount);
payDetail.setTradeAnswerCode("000");
sharedViewModel.setAmount(POSUtil.getInstance().getDecimalAmountSeparatorFormat(totalAmount));
sharedViewModel.payDetails.setValue(qrTransList);
sharedViewModel.payDetail.setValue(payDetail);
sharedViewModel.transactionsType.setValue(TransactionsType.MMQR_SETTLEMENT);
try {
navController.navigate(R.id.transactionResultFragment);
} catch (Exception e) {
LogUtil.e(TAG, "QR Auto Settlement navigation error: " + e.getMessage());
}
}

View File

@ -29,11 +29,9 @@ import com.denzcoskun.imageslider.constants.ScaleTypes;
import com.denzcoskun.imageslider.models.SlideModel;
import com.nexgo.oaf.apiv3.emv.AidEntity;
import com.nexgo.oaf.apiv3.emv.CapkEntity;
//import com.pos.connection.bridge.binder.ECRConstant;
import com.pos.connection.bridge.binder.ECRConstant;
import com.utsmm.kbz.util.MockData;
//import com.utsmm.kbz.util.ecr.ModernECRFactory;
//import com.utsmm.kbz.util.ecr.ModernECRManager;
import com.utsmyanmar.baselib.BaseApplication;
import com.utsmyanmar.baselib.emv.EmvParamOperation;
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
@ -318,8 +316,8 @@ public class MainFragment extends DataBindingFragment {
if (checkECRServiceAppExistOrNot()) {
// Initialize Modern ECR Manager
// modernECRManager.init();
////
//// // Observe navigation requests
//
// // Observe navigation requests
// modernECRManager.getNavigationRequest().observe(getViewLifecycleOwner(), destinationId -> {
// if (destinationId != null) {
// delayFunctionCall(() -> isRouteValidAndNavigateToRoute(destinationId));

View File

@ -20,7 +20,6 @@ import com.google.gson.Gson;
import com.utsmm.kbz.MainActivity;
import com.utsmm.kbz.util.EReceiptUtil;
import com.utsmm.kbz.util.enums.TransactionStatus;
import com.utsmyanmar.baselib.network.model.e_receipt.EReceiptRequest;
import com.utsmyanmar.baselib.repo.Repository;
import com.utsmm.kbz.BuildConfig;
@ -35,8 +34,6 @@ import io.reactivex.rxjava3.schedulers.Schedulers;
import retrofit2.HttpException;
import com.utsmyanmar.paylibs.Constant;
import com.utsmyanmar.paylibs.batch_upload.BatchListener;
import com.utsmyanmar.paylibs.batch_upload.BatchUploadProcess;
import com.utsmyanmar.paylibs.isobuilder.ISOMode;
import com.utsmyanmar.paylibs.isobuilder.builderx.ISOMsgX;
import com.utsmyanmar.paylibs.isobuilder.builderx.ISOVersion;
@ -47,8 +44,6 @@ import com.utsmyanmar.paylibs.model.SettleData;
import com.utsmyanmar.paylibs.model.TradeData;
import com.utsmyanmar.paylibs.network.ISOCallback;
import com.utsmyanmar.paylibs.network.ISOSocket;
import com.utsmyanmar.paylibs.sign_on.EchoTestProcess;
import com.utsmyanmar.paylibs.sign_on.SignOnListener;
import com.utsmyanmar.paylibs.utils.LogUtil;
import com.utsmyanmar.paylibs.utils.MessageType;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
@ -79,25 +74,14 @@ public class AutoSettleService extends Service {
private boolean regularSettlementCompleted = false;
private boolean qrSettlementCompleted = false;
private boolean posHasData = false; // true = POS actually ran and has result
private boolean qrHasData = false; // true = QR actually ran and has result
// Observers to keep reference for cleanup
private Observer<List<PayDetail>> regularSettlementObserver;
private Observer<List<PayDetail>> qrSettlementObserver;
private Observer<java.util.List<com.utsmyanmar.paylibs.model.PayDetail>> regularSettlementObserver;
private Observer<java.util.List<com.utsmyanmar.paylibs.model.PayDetail>> qrSettlementObserver;
private int i = 0;
private boolean flag = false;
@Inject
Repository repository;
private PayDetail pendingPayDetail = null;
private Bundle pendingQrData = null;
private boolean posSettlementReady = false;
private boolean qrSettlementReady = false;
ArrayList<PayDetail> payDetails = new ArrayList<>();
public static final String NOTIFICATION_CHANNEL_ID = "10001";
private final static String default_notification_channel_id = "default";
@ -204,10 +188,6 @@ public class AutoSettleService extends Service {
if (regularSettlementCompleted) {
return;
}
payDetails.clear();
payDetails.addAll(list);
regularSettlementCompleted = true;
repository.getSettlementPOS().removeObserver(this);
@ -245,13 +225,7 @@ public class AutoSettleService extends Service {
String bitmap = BitmapConfig.BPC_SETTLEMENT;
payDetail.setTransType(TransactionsType.SETTLEMENT.name);
payDetail.setTransactionType(TransactionType.SETTLEMENT);
if(!flag) {
payDetail.setProcessCode(TransactionsType.SETTLEMENT.processCode);
} else {
bitmap = BitmapConfig.BPC_SETTLEMENT_TRAILER;
payDetail.setProcessCode("910000");
}
payDetail.setProcessCode(TransactionsType.SETTLEMENT.processCode);
payDetail.setBatchNo(SystemParamsOperation.getInstance().getCurrentBatchNum());
SettleData settleData = new SettleData(
@ -271,14 +245,6 @@ public class AutoSettleService extends Service {
} else {
settlementData = "C" + String.format(Locale.getDefault(), "%012d", totalAmount);
}
if(totalAmount == 0 && (saleCount == 0 || preCount == 0 || refundCount == 0 || caCount == 0)) {
posSettlementReady = true;
posHasData = false;
checkAndLaunch();
checkIfBothSettlementsComplete();
return;
}
payDetail.setSettleData(settlementData);
payDetail.setAmount(totalAmount);
@ -303,7 +269,7 @@ public class AutoSettleService extends Service {
if (TextUtils.equals(resultStr, Constant.ANSWER_CODE_ACCEPT) || TextUtils.equals(resultStr, Constant.ANSWER_CODE_APPROVED)) {
payDetail.setIsNeedReversal(false);
} else if (TextUtils.equals(resultStr, "95") || TextUtils.equals(resultStr, "095")) {
payDetail.setIsNeedReversal(!flag);
payDetail.setIsNeedReversal(true);
}
}
}
@ -318,25 +284,34 @@ public class AutoSettleService extends Service {
public void onComplete() {
LogUtil.d(TAG, "Auto settlement transaction completed successfully");
if(payDetail.getIsNeedReversal()) {
flag = true;
batchUploadProcess();
} else {
flag = false;
if (!list.isEmpty()) {
for (PayDetail p : list) {
repository.deletePayDetail(p);
}
if (list != null && !list.isEmpty()) {
for (PayDetail p : list) {
repository.deletePayDetail(p);
}
repository.insertPayDetail(payDetail);
networkCutOver(payDetail);
}
repository.insertPayDetail(payDetail);
try {
PayDetail cleanPayDetail = new PayDetail();
cleanPayDetail.setTransType(payDetail.getTransType());
cleanPayDetail.setTransactionType(payDetail.getTransactionType());
cleanPayDetail.setProcessCode(payDetail.getProcessCode());
cleanPayDetail.setBatchNo(payDetail.getBatchNo());
cleanPayDetail.setSettleData(payDetail.getSettleData());
cleanPayDetail.setAmount(payDetail.getAmount());
cleanPayDetail.setTradeAnswerCode(payDetail.getTradeAnswerCode());
cleanPayDetail.setIsNeedReversal(payDetail.getIsNeedReversal());
// Use notification-based approach to reliably launch the app
launchAppWithSettlementResult("AUTO_SETTLEMENT", cleanPayDetail, null);
} catch (Exception e) {
LogUtil.e(TAG, "Error launching app with settlement result: " + e.getMessage());
e.printStackTrace();
}
checkIfBothSettlementsComplete();
}
});
}
};
@ -344,41 +319,6 @@ public class AutoSettleService extends Service {
repository.getSettlementPOS().observeForever(regularSettlementObserver);
}
private void batchUploadProcess() {
if(payDetails == null || payDetails.isEmpty()){
regularSettlementCompleted = false;
performSettlement();
return;
}
PayDetail payDetail = payDetails.get(i);
TradeData tradeData = new TradeData();
tradeData.setPayDetail(payDetail);
BatchUploadProcess.getInstance().enqueue(tradeData).startBatchUpload(new BatchListener() {
@Override
public void onSuccessBatch() {
if (i < payDetails.size() - 1) {
LogUtil.d(TAG, "Pay detail Size:" + payDetails.size());
LogUtil.d(TAG, "Count value:" + i);
i++;
batchUploadProcess();
} else {
regularSettlementCompleted = false;
performSettlement();
}
LogUtil.e(TAG, "Batch Upload Success");
}
@Override
public void onFailBatch() {
LogUtil.e(TAG, "Batch Upload Fail");
}
});
}
private void performQRSettlement() {
if (qrSettlementCompleted) {
return;
@ -425,9 +365,6 @@ public class AutoSettleService extends Service {
}
} catch (IllegalStateException e) {
LogUtil.e(TAG, "QR Auto Settlement: Database cursor error - likely due to large data size: " + e);
qrSettlementReady = true;
qrHasData = false;
checkAndLaunch();
checkIfBothSettlementsComplete();
return;
}
@ -485,24 +422,19 @@ public class AutoSettleService extends Service {
qrData.putLong("QR_TOTAL_AMOUNT", totalAmount);
qrData.putSerializable("QR_TRANS_LIST", qrTransactionsList);
// Use notification-based approach to reliably launch the app
pendingQrData = qrData;
qrHasData = true;
// launchAppWithSettlementResult("AUTO_QR_SETTLEMENT", null, qrData,false);
launchAppWithSettlementResult("AUTO_QR_SETTLEMENT", null, qrData);
} catch (Exception e) {
LogUtil.e(TAG, "Error launching app for QR settlement: " + e.getMessage());
qrHasData = false;
e.printStackTrace();
}
LogUtil.d(TAG, "QR Auto Settlement completed successfully");
} else {
LogUtil.d(TAG, "No QR transactions found for auto settlement");
qrHasData = false;
}
}
qrSettlementReady = true;
checkAndLaunch();
checkIfBothSettlementsComplete();
}
};
@ -548,120 +480,69 @@ public class AutoSettleService extends Service {
}
private void networkCutOver(PayDetail payDetail) {
EchoTestProcess.getInstance().enqueueCutOver().startSignOn(new SignOnListener() {
@Override
public void onSuccessSignOn() {
pendingPayDetail = payDetail;
posHasData = true;
posSettlementReady = true;
checkAndLaunch();
checkIfBothSettlementsComplete();
}
@Override
public void onFailureSignOn(Integer resultCode) {
LogUtil.d(TAG,"Failure Cut Over message: "+resultCode);
// POS done but cutover failed still mark ready
posSettlementReady = true;
posHasData = false;
checkAndLaunch();
checkIfBothSettlementsComplete();
}
@Override
public void onNetworkFailSignOn(String message) {
LogUtil.d(TAG,"Network Fail Cut Over message: "+message);
posSettlementReady = true;
posHasData = false;
checkAndLaunch();
checkIfBothSettlementsComplete();
}
});
}
private void checkAndLaunch() {
// !!!! need to add flag, if don't want both at once
if (!posSettlementReady || !qrSettlementReady) {
LogUtil.d(TAG, "Waiting for both settlements... POS=" + posSettlementReady + " QR=" + qrSettlementReady);
return;
}
LogUtil.d(TAG, "Both settlements ready. POS has data=" + posHasData + ", QR has data=" + qrHasData);
if (!posHasData && !qrHasData) {
LogUtil.d(TAG, "No settlement data to display");
return;
}
launchMainActivity();
}
private void launchMainActivity() {
private void launchAppWithSettlementResult(String settlementType,
PayDetail payDetail,
Bundle qrData) {
try {
Intent launchIntent = new Intent(this, MainActivity.class);
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
launchIntent.putExtra(settlementType, true);
if (posHasData && pendingPayDetail != null) {
launchIntent.putExtra("AUTO_SETTLEMENT", true);
if ("AUTO_SETTLEMENT".equals(settlementType) && payDetail != null) {
launchIntent.putExtra("EXTRA_TRANSACTION_TYPE", TransactionsType.SETTLEMENT.value);
launchIntent.putExtra("EXTRA_PAY_DETAIL", pendingPayDetail);
}
if (qrHasData && pendingQrData != null) {
launchIntent.putExtra("AUTO_QR_SETTLEMENT", true);
launchIntent.putExtra("EXTRA_QR_TRANSACTION_TYPE", TransactionsType.MMQR_SETTLEMENT.value);
launchIntent.putExtras(pendingQrData);
launchIntent.putExtra("EXTRA_PAY_DETAIL", payDetail);
} else if ("AUTO_QR_SETTLEMENT".equals(settlementType) && qrData != null) {
launchIntent.putExtra("EXTRA_TRANSACTION_TYPE", TransactionsType.MMQR_SETTLEMENT.value);
launchIntent.putExtras(qrData);
}
PendingIntent pendingIntent = PendingIntent.getActivity(
this,
(int) System.currentTimeMillis(),
launchIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
this,
(int) System.currentTimeMillis(),
launchIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
"SETTLEMENT_COMPLETE", "Settlement Complete", NotificationManager.IMPORTANCE_HIGH);
"SETTLEMENT_COMPLETE",
"Settlement Complete",
NotificationManager.IMPORTANCE_HIGH
);
channel.setDescription("Auto settlement completion notifications");
notificationManager.createNotificationChannel(channel);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "SETTLEMENT_COMPLETE")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Auto Settlement Complete")
.setContentText("Tap to view settlement results and print receipt")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setFullScreenIntent(pendingIntent, true);
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Auto Settlement Complete")
.setContentText("Tap to view settlement results and print receipt")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setFullScreenIntent(pendingIntent, true);
notificationManager.notify(2001, builder.build());
// Reset state
pendingPayDetail = null;
pendingQrData = null;
posSettlementReady = false;
qrSettlementReady = false;
posHasData = false;
qrHasData = false;
LogUtil.d(TAG, " Settlement complete notification created - will launch app when tapped");
startActivity(launchIntent);
try {
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP |
Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
startActivity(launchIntent);
} catch (Exception directException) {
LogUtil.d(TAG, "Direct launch failed (expected on modern Android), notification approach will handle it");
}
} catch (Exception e) {
LogUtil.e(TAG, "Error launching MainActivity: " + e.getMessage());
LogUtil.e(TAG, "Error creating settlement notification: " + e.getMessage());
e.printStackTrace();
}
}
private void sendEReceipt(EReceiptRequest request) {
try {
LogUtil.d(TAG, "Sending e-receipt: " + new Gson().toJson(request));

View File

@ -328,17 +328,6 @@ public class SettingsFragment extends DataBindingFragment {
}
}
public void onClearReversalClick() {
try {
sharedViewModel.transactionsType.postValue(TransactionsType.CLEAR_REVERSAL);
sharedViewModel.setTransMenu(TransMenu.CLEAR_REVERSAL);
Navigation.findNavController(requireActivity(), R.id.nav_host_fragment)
.navigate(R.id.inputPasswordFragment);
} catch (Exception e) {
LogUtil.e(TAG, "Error in clear reversal click: " + e.getMessage());
}
}
public void onTmsConfigClick() {
try {
LogUtil.d(TAG, "TMS Config clicked");

View File

@ -262,7 +262,6 @@ public class CardWaitingFragment extends DataBindingFragment implements DataBind
} else {
allType.add(CardSlotTypeEnum.ICC1);
allType.add(CardSlotTypeEnum.RF);
allType.add(CardSlotTypeEnum.SWIPE);
}
// int allType = AidlConstants.CardType.IC.getValue() | AidlConstants.CardType.MAGNETIC.getValue();
@ -290,7 +289,7 @@ public class CardWaitingFragment extends DataBindingFragment implements DataBind
} else if (isFallback && cardType == CardTypeX.MAG) {
/* do fallback transactions */
sharedViewModel.isEmv.postValue(false);
sharedViewModel.isEmv.setValue(false);
cardReadViewModel.setCardTransactionType(CardTransactionType.FALLBACK);
} else if (cardType == CardTypeX.IC || cardType == CardTypeX.NFC) {

View File

@ -3,7 +3,6 @@ package com.utsmm.kbz.ui.core_ui;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -159,7 +158,6 @@ public class EmvTransactionFragment extends DataBindingFragment {
}
observeEmvResultStatus();
observePinWarning();
}
private boolean isNotManualTransaction() {
@ -246,7 +244,7 @@ public class EmvTransactionFragment extends DataBindingFragment {
isCardTaped("Please try again",new CardDetectCallback() {
@Override
public void onComplete() {
sharedViewModel.setIsSeePhone(false);
sharedViewModel.setIsSeePhone(true);
navigateToCheckCard();
}
});
@ -351,15 +349,6 @@ public class EmvTransactionFragment extends DataBindingFragment {
});
}
private void observePinWarning() {
emvTransactionViewModel.pinRemainingCount.observe(getViewLifecycleOwner(), msg -> {
if (!TextUtils.isEmpty(msg)) {
Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT).show();
emvTransactionViewModel.pinRemainingCount.setValue("");
}
});
}
private void observeEmvErrorCode() {
dismissLoadingDialog();
emvTransactionViewModel.errorCodeMsg.observe(getViewLifecycleOwner(), pair -> {

View File

@ -6,8 +6,6 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.navigation.NavController;
import androidx.navigation.NavDestination;
@ -19,9 +17,6 @@ import com.utsmyanmar.baselib.fragment.DataBindingFragment;
import com.utsmyanmar.baselib.network.model.e_receipt.EReceiptRequest;
import com.utsmyanmar.baselib.util.DataBindingConfig;
import com.utsmyanmar.baselib.util.TimeoutCallback;
import com.utsmyanmar.paylibs.model.TradeData;
import com.utsmyanmar.paylibs.reversal.ReversalAction;
import com.utsmyanmar.paylibs.reversal.ReversalListener;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
import com.utsmm.kbz.BR;
import com.utsmm.kbz.R;
@ -109,17 +104,6 @@ public class ProcessingFragment extends DataBindingFragment {
setToolBarTitleWithoutBackIcon(getResourceString(R.string.title_processing));
checkReversal();
// disableNavigationBar();
getNavController(Constants.NAV_HOST_ID).addOnDestinationChangedListener(listener);
}
private void startTransactionProcess() {
if(isEmvTrans()) {
startTransactionProcess(emvTransactionProcessViewModel);
} else {
@ -127,55 +111,13 @@ public class ProcessingFragment extends DataBindingFragment {
}
sharedViewModel.loadingMsg(getResourceString(R.string.txt_sending));
// disableNavigationBar();
getNavController(Constants.NAV_HOST_ID).addOnDestinationChangedListener(listener);
}
private void checkReversal() {
observeOnce(sharedViewModel.getLastReversalTransaction(), payDetail -> {
if (payDetail != null) {
TradeData tradeData = new TradeData();
tradeData.setPayDetail(payDetail);
LogUtil.d(TAG, "Sending Reversal!");
sharedViewModel.loadingMsg(getResourceString(R.string.txt_sending_reversal));
ReversalAction.getInstance().setData(tradeData).enqueue().startReversal(new ReversalListener() {
@Override
public void onSuccessReversal() {
LogUtil.d(TAG, "Reversal Success!");
payDetail.setIsNeedReversal(false);
sharedViewModel.updatePayDetail(payDetail);
delayFunctionCall(()->startTransactionProcess());
}
@Override
public void onNetworkFail(String msg) {
LogUtil.d(TAG, "Reversal Network Fail!" + msg);
startTransactionProcess();
}
@Override
public void onFailReversal(String msg) {
LogUtil.d(TAG, "Reversal Fail!" + msg);
startTransactionProcess();
}
});
} else {
LogUtil.d(TAG,"No reversal found!");
startTransactionProcess();
}
});
}
private <T> void observeOnce(LiveData<T> liveData, Observer<T> observer) {
liveData.observe(getViewLifecycleOwner(), new Observer<T>() {
@Override
public void onChanged(T t) {
liveData.removeObserver(this);
observer.onChanged(t);
}
});
}
private boolean isEmvTrans() {
return sharedViewModel.isEmv.getValue() != null && sharedViewModel.isEmv.getValue();
}

View File

@ -335,7 +335,6 @@ public class TransactionResultFragment extends DataBindingFragment implements Da
sharedViewModel.startPrintSettlement(new PrintXStatus() {
@Override
public void onSuccess() {
sharedViewModel.onSettlementResultDone.postValue(true);
isCardInside();
}

View File

@ -2,7 +2,6 @@ package com.utsmm.kbz.ui.core_viewmodel;
import android.graphics.Bitmap;
import android.util.Log;
import android.widget.ListView;
import dagger.hilt.android.lifecycle.HiltViewModel;
import androidx.lifecycle.LiveData;
@ -74,8 +73,7 @@ public class SharedViewModel extends ViewModel {
public SingleLiveEvent<String> transactionName = new SingleLiveEvent<>();
// In SharedViewModel
public MutableLiveData<Boolean> onSettlementResultDone = new MutableLiveData<>(false);
/*May 16 2022*/
public SingleLiveEvent<Boolean> isEcr = new SingleLiveEvent<>();
@ -448,14 +446,6 @@ public class SharedViewModel extends ViewModel {
return repository.getReversalTransaction(voucherNo);
}
public LiveData<PayDetail> getLastReversalTransaction() {
return repository.getLastReversalTransaction();
}
public LiveData<List<PayDetail>> getAllReversalTransaction() {
return repository.getAllReversalTransactions();
}
public void updatePayDetail(PayDetail payDetail){
repository.updatePayDetail(payDetail);
}

View File

@ -210,43 +210,21 @@ public class SelectHostFragment extends DataBindingFragment implements DataBindi
private void clearReversal() {
checkPointReversal = false;
// sharedViewModel.getReversalTransaction(SystemParamsOperation.getInstance().getCurrentSerialNum()).observe(getViewLifecycleOwner(), payDetail -> {
// if (payDetail != null) {
// if (!checkPointReversal) {
// payDetail.setIsNeedReversal(false);
// sharedViewModel.updatePayDetail(payDetail);
// checkPointReversal = true;
//
// showSuccessDialog("Clear reversal success!");
// }
// } else {
// if (!checkPointReversal) {
// showInfoDialog("Clear reversal", "No reversal found!");
// checkPointReversal = true;
// }
//
// }
// });
sharedViewModel.getReversalTransaction(SystemParamsOperation.getInstance().getCurrentSerialNum()).observe(getViewLifecycleOwner(), payDetail -> {
if (payDetail != null) {
if (!checkPointReversal) {
payDetail.setIsNeedReversal(false);
sharedViewModel.updatePayDetail(payDetail);
checkPointReversal = true;
sharedViewModel.getAllReversalTransaction().observe(getViewLifecycleOwner(), new Observer<List<PayDetail>>() {
@Override
public void onChanged(List<PayDetail> payDetails) {
if(payDetails != null && !payDetails.isEmpty()) {
if(!checkPointReversal) {
for (PayDetail payDetail : payDetails) {
payDetail.setIsNeedReversal(false);
sharedViewModel.updatePayDetail(payDetail);
}
checkPointReversal = true;
showSuccessDialog("Clear reversal success!");
}
} else {
if (!checkPointReversal) {
showInfoDialog("Clear reversal", "No reversal found!");
checkPointReversal = true;
}
showSuccessDialog("Clear reversal success!");
}
} else {
if (!checkPointReversal) {
showInfoDialog("Clear reversal", "No reversal found!");
checkPointReversal = true;
}
}
});
}

View File

@ -359,10 +359,7 @@ public class PinPadViewModel extends ViewModel {
handler.obtainMessage(ON_ERROR_PIN_PAD,retCode).sendToTarget();
}
LogUtil.d(TAG,"RetCode:"+retCode);
if(retCode != SdkResult.PinPad_No_Pin_Input) {
payDetail.setPINCipher(ByteUtil.bytes2HexStr(data));
}
payDetail.setPINCipher(ByteUtil.bytes2HexStr(data));
LogUtil.d(TAG,"data bytes:"+ByteUtil.bytes2HexStr(data));
}

View File

@ -37,7 +37,6 @@ public class InjectKeyFragment extends DataBindingFragment {
private DownloadFlow mDownloadFlow;
private int keyIndexTmp = 8; // Default key index
private final List<HostSelectionItem> hostSelectionItems = new ArrayList<>();
private HostSelectionItem selectedHostSelectionItem;
@Override
protected void initViewModel() {
@ -129,7 +128,6 @@ public class InjectKeyFragment extends DataBindingFragment {
}
private void applyHostSelection(@NonNull HostSelectionItem selectionItem) {
selectedHostSelectionItem = selectionItem;
binding.terminalIdValue.setText(getDisplayValue(selectionItem.terminalId));
binding.merchantIdValue.setText(getDisplayValue(selectionItem.merchantId));
}
@ -158,14 +156,14 @@ public class InjectKeyFragment extends DataBindingFragment {
mDownloadFlow = DownloadFlow.getInstance();
String terminalId = selectedHostSelectionItem != null ? selectedHostSelectionItem.terminalId : null;
String merchantId = selectedHostSelectionItem != null ? selectedHostSelectionItem.merchantId : null;
String terminalId = SystemParamsOperation.getInstance().getTerminalId();
String merchantId = SystemParamsOperation.getInstance().getMerchantId();
String serialNo = TMSUtil.getInstance().getSerialNumber();
// Validate configuration
if (TextUtils.isEmpty(terminalId) || TextUtils.isEmpty(merchantId) || TextUtils.isEmpty(serialNo)) {
dismissLoadingDialog();
showDeclineDialog("Please configure the selected Terminal ID and Merchant ID first in TMS Configuration");
showDeclineDialog("Please configure Terminal ID, Merchant ID first in TMS Configuration");
return;
}

View File

@ -462,7 +462,11 @@ public class SettlementViewModel extends ViewModel {
} else if (TextUtils.equals(resultStr, "95") || TextUtils.equals(resultStr, "095")) {
//reversal
// if (!flag && isNoData.getValue()) {
payDetail.setIsNeedReversal(!flag);
if (!flag ) {
payDetail.setIsNeedReversal(true);
} else {
payDetail.setIsNeedReversal(false);
}
}
} else {

View File

@ -6,7 +6,6 @@ import com.utsmyanmar.paylibs.model.CardInfo;
import com.utsmyanmar.paylibs.model.MAGCardInfo;
import com.utsmyanmar.paylibs.model.PayDetail;
import com.utsmyanmar.paylibs.model.TradeData;
import com.utsmyanmar.paylibs.model.enums.TransCVM;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
import com.utsmyanmar.paylibs.utils.params.Params;
@ -99,7 +98,6 @@ public class TransactionUtil {
PayDetail payDetail = tradeData.getPayDetail();
payDetail.setCardNo(cardDataX.getPan());
payDetail.setEXPDate(cardDataX.getExp());
payDetail.setTransCVM(TransCVM.SIGNATURE);
if(cardDataX.getPan().startsWith("4")) {
payDetail.setAccountType(VISA_CARD_SCHEME);

View File

@ -120,17 +120,16 @@
<TextView
android:id="@+id/txt_emv_remaining_count"
android:layout_width="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_button"
android:fontFamily="@font/rubik_regular"
android:gravity="center"
android:text="@{emv.pinRemainingCount}"
android:textColor="@color/white"
android:textSize="@dimen/pan_size"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txt_emv_pin_mode"
app:layout_constraintStart_toEndOf="@+id/textView3"
app:layout_constraintTop_toBottomOf="@+id/textView20"
app:layout_goneMarginTop="@dimen/margin_button"
tools:text="3 LEFT" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -969,81 +969,6 @@
</androidx.cardview.widget.CardView>
<!-- Clear Reversal Card -->
<androidx.cardview.widget.CardView
android:id="@+id/clearReversalCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
android:onClick="@{()->click.onClearReversalClick()}"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="16dp"
app:cardElevation="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="20dp">
<androidx.cardview.widget.CardView
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="16dp"
app:cardBackgroundColor="@color/colorPrimary"
app:cardCornerRadius="24dp"
app:cardElevation="0dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:src="@drawable/ic_clear_all"
app:tint="@color/white" />
</androidx.cardview.widget.CardView>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/rubik_medium"
android:text="@string/title_clear_reversal"
android:textColor="@color/colorTextTitle"
android:textSize="18sp"
android:textStyle="bold"
tools:fontFamily="sans-serif-medium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:fontFamily="@font/rubik_regular"
android:text="@string/clear_reversal_description"
android:textColor="@color/colorTextContent"
android:textSize="14sp"
tools:fontFamily="sans-serif" />
</LinearLayout>
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/ic_right_arrow"
app:tint="@color/colorPrimary" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- TMS Server URL Card -->
<!-- android:onClick="@{()->click.onTmsAddressClick()}"-->
<androidx.cardview.widget.CardView

View File

@ -23,7 +23,6 @@ public final class TerminalKeyUtil {
public static final String TAG = TerminalKeyUtil.class.getSimpleName();
private static final byte[] main_key_data = ByteUtil.hexStr2Bytes("875f63741753d18811a3449090d1777b".toUpperCase()); // KBZ UAT
// private static final byte[] main_key_data = ByteUtil.hexStr2Bytes("875f63741753d18811a3449090d1777b".toUpperCase());
// private static final byte[] main_key_data = ByteUtil.hexStr2Bytes("e121249099a677e8b7d4f6a9d49fe8d1".toUpperCase()); // MPU
private static final byte[] work_key_data = new byte[16];

View File

@ -97,12 +97,6 @@ public interface PayDetailDao {
@Query("SELECT * FROM paydetail WHERE transactionType = 10 AND isNeedReversal = 1 AND voucherNo IN(:voucherNo)")
LiveData<PayDetail> getReversalTransaction(String voucherNo);
@Query("SELECT * FROM PayDetail WHERE isNeedReversal = 1 ORDER BY PID DESC LIMIT 1")
LiveData<PayDetail> getLastReversalTransactionLive();
@Query("SELECT * FROM PayDetail WHERE isNeedReversal = 1 ORDER BY PID DESC")
LiveData<List<PayDetail>> getAllReversalTransactionsLive();
// @Query("SELECT * FROM paydetail WHERE transactionType != 10 ORDER BY PID DESC")
@Query("SELECT * FROM paydetail ORDER BY PID DESC")
LiveData<List<PayDetail>> getTransactionHistory();

View File

@ -349,7 +349,7 @@ public class EmvParamHelper {
private AidEntity convertContactlessAIDNex(ContactlessAid contactlessAid) {
AidEntity aidV2 = new AidEntity();
aidV2.setTransType("FF"); // FF
aidV2.setTransType("FF");
aidV2.setOnlinePinCap(1);
aidV2.setAsi(0);
aidV2.setThreshold(0);
@ -412,8 +412,7 @@ public class EmvParamHelper {
aidV2.setTransType("FF");
aidV2.setOnlinePinCap(1);
aidV2.setAsi(0); //1
// aidV2.setThreshold(99);
aidV2.setAsi(1);
if (!(contactAid.getCvmLimit() < 0)) {
aidV2.setContactlessCvmLimit(contactAid.getCvmLimit());
@ -465,10 +464,6 @@ public class EmvParamHelper {
aidV2.setAppVerNum(contactAid.getApplicationVersion());
}
if (contactAid.getThreshold() != null && !contactAid.getThreshold().isEmpty()) {
aidV2.setThreshold(Long.parseLong(contactAid.getThreshold()));
}
return aidV2;
}

View File

@ -146,8 +146,6 @@ public class Repository {
public void updatePayDetail(PayDetail payDetail){payDetailDao.update(payDetail);}
public LiveData<PayDetail> getReversalTransaction(String voucherNo) { return payDetailDao.getReversalTransaction(voucherNo);}
public LiveData<PayDetail> getLastReversalTransaction() { return payDetailDao.getLastReversalTransactionLive();}
public LiveData<List<PayDetail>> getAllReversalTransactions() { return payDetailDao.getAllReversalTransactionsLive();}
public LiveData<List<PayDetail>> getTransactionHistory(){ return payDetailDao.getTransactionHistory();}

View File

@ -1,15 +1,12 @@
package com.utsmyanmar.baselib.viewModel;
import android.app.AlertDialog;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.lifecycle.MutableLiveData;
@ -108,7 +105,6 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
public MutableLiveData<Integer> pinPadVisibility = new MutableLiveData<>(8);
protected int pinEnterCount;
private int offlinePinIncorrectPromptCount;
public CustomPinPadKeyboard customPinPadKeyboard;
private int mWidth = 239; // Single item width of password keyboard
@ -249,7 +245,6 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
transData.setTransTime(new SimpleDateFormat("hhmmss", Locale.getDefault()).format(new Date()));
transData.setTraceNo(mPayDetail.getVoucherNo());
transData.setEmvProcessFlowEnum(EmvProcessFlowEnum.EMV_PROCESS_FLOW_STANDARD);
if (mPayDetail.getCardType() == CardTypeX.NFC.value) {
transData.setEmvEntryModeEnum(EmvEntryModeEnum.EMV_ENTRY_MODE_CONTACTLESS);
@ -265,8 +260,7 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
unionPayTransDataEntity.setSupportCDCVM(true);
//if support QPS, please enable below lines
unionPayTransDataEntity.setSupportContactlessQps(true);
unionPayTransDataEntity.setContactlessQpsLimit("000000030000");
unionPayTransDataEntity.setContactlessQpsLimit("000090000000");
transData.setUnionPayTransDataEntity(unionPayTransDataEntity);
@ -275,8 +269,6 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
emvHandler.contactlessAppendAidIntoKernel(EmvCardBrandEnum.EMV_CARD_BRAND_MASTER, (byte) 0x08, ByteUtils.hexString2ByteArray("A000000732100123"));
LogUtil.d(TAG, "TransData :" + transData.getTransAmount());
LogUtil.d(TAG, "start emv ");
// emvHandler.emvDebugLog(true);
emvHandler.emvProcess(transData, emvProcessListener);
@ -284,7 +276,7 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
private void initData() {
try {
emvHandler = BaseApplication.getInstance().deviceEngine.getEmvHandler2("app2");
emvHandler = BaseApplication.getInstance().deviceEngine.getEmvHandler2("app2");
if (emvHandler == null) {
LogUtil.e(TAG, "Failed to initialize EMV handler - emvHandler is null");
// Post error status to inform UI
@ -316,8 +308,8 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
return;
}
try {
LogUtil.d(TAG, "Selected :" + position + 1);
emvHandler.onSetSelAppResponse(position + 1);
LogUtil.d(TAG, "Selected :" + position);
emvHandler.onSetSelAppResponse(position);
} catch (Exception e) {
LogUtil.e(TAG, "Exception during app selection: " + e.getMessage());
e.printStackTrace();
@ -433,142 +425,213 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
initKeyboard(isOnlinePin == 1);
}
private void initKeyboard(boolean isOnlinePin) {
LogUtil.d(TAG, "init keyboard!");
LogUtil.d(TAG,"init keyboard!");
pinPadVisibility.setValue(0);
LogUtil.d(TAG, "pin pad is visible now!");
LogUtil.d(TAG,"pin pad is visible now!");
customPinPadKeyboard.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
customPinPadKeyboard.getViewTreeObserver().removeOnGlobalLayoutListener(this);
// Check if the view is already laid out
if (customPinPadKeyboard.getWidth() > 0 && customPinPadKeyboard.getHeight() > 0) {
// View already laid out call setup directly
setupPinPadLayout(isOnlinePin);
} else {
// View not yet laid out wait for layout
customPinPadKeyboard.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (customPinPadKeyboard.getWidth() > 0 && customPinPadKeyboard.getHeight() > 0) {
customPinPadKeyboard.getViewTreeObserver().removeOnGlobalLayoutListener(this);
setupPinPadLayout(isOnlinePin);
LogUtil.d(TAG,"inside the global layout!");
PinpadLayoutEntity pinpadLayout = new PinpadLayoutEntity();
int[] location = new int[2];
Rect r;
customPinPadKeyboard.getKey_1().getLocationOnScreen(location);
r = new Rect();
r.left = location[0];
r.top = location[1];
r.right = customPinPadKeyboard.getKey_1().getWidth() + r.left;
r.bottom = customPinPadKeyboard.getKey_1().getHeight() + r.top;
pinpadLayout.setKey1(r);
customPinPadKeyboard.getKey_2().getLocationOnScreen(location);
r = new Rect();
r.left = location[0];
r.top = location[1];
r.right = customPinPadKeyboard.getKey_2().getWidth() + r.left;
r.bottom = customPinPadKeyboard.getKey_2().getHeight() + r.top;
pinpadLayout.setKey2(r);
customPinPadKeyboard.getKey_3().getLocationOnScreen(location);
r = new Rect();
r.left = location[0];
r.top = location[1];
r.right = customPinPadKeyboard.getKey_3().getWidth() + r.left;
r.bottom = customPinPadKeyboard.getKey_3().getHeight() + r.top;
pinpadLayout.setKey3(r);
customPinPadKeyboard.getKey_4().getLocationOnScreen(location);
r = new Rect();
r.left = location[0];
r.top = location[1];
r.right = customPinPadKeyboard.getKey_4().getWidth() + r.left;
r.bottom = customPinPadKeyboard.getKey_4().getHeight() + r.top;
pinpadLayout.setKey4(r);
customPinPadKeyboard.getKey_5().getLocationOnScreen(location);
r = new Rect();
r.left = location[0];
r.top = location[1];
r.right = customPinPadKeyboard.getKey_5().getWidth() + r.left;
r.bottom = customPinPadKeyboard.getKey_5().getHeight() + r.top;
pinpadLayout.setKey5(r);
customPinPadKeyboard.getKey_6().getLocationOnScreen(location);
r = new Rect();
r.left = location[0];
r.top = location[1];
r.right = customPinPadKeyboard.getKey_6().getWidth() + r.left;
r.bottom = customPinPadKeyboard.getKey_6().getHeight() + r.top;
pinpadLayout.setKey6(r);
customPinPadKeyboard.getKey_7().getLocationOnScreen(location);
r = new Rect();
r.left = location[0];
r.top = location[1];
r.right = customPinPadKeyboard.getKey_7().getWidth() + r.left;
r.bottom = customPinPadKeyboard.getKey_7().getHeight() + r.top;
pinpadLayout.setKey7(r);
customPinPadKeyboard.getKey_8().getLocationOnScreen(location);
r = new Rect();
r.left = location[0];
r.top = location[1];
r.right = customPinPadKeyboard.getKey_8().getWidth() + r.left;
r.bottom = customPinPadKeyboard.getKey_8().getHeight() + r.top;
pinpadLayout.setKey8(r);
customPinPadKeyboard.getKey_9().getLocationOnScreen(location);
r = new Rect();
r.left = location[0];
r.top = location[1];
r.right = customPinPadKeyboard.getKey_9().getWidth() + r.left;
r.bottom = customPinPadKeyboard.getKey_9().getHeight() + r.top;
pinpadLayout.setKey9(r);
customPinPadKeyboard.getKey_0().getLocationOnScreen(location);
r = new Rect();
r.left = location[0];
r.top = location[1];
r.right = customPinPadKeyboard.getKey_0().getWidth() + r.left;
r.bottom = customPinPadKeyboard.getKey_0().getHeight() + r.top;
pinpadLayout.setKey10(r);
customPinPadKeyboard.getKey_cancel().getLocationOnScreen(location);
r = new Rect();
r.left = location[0];
r.top = location[1];
r.right = customPinPadKeyboard.getKey_cancel().getWidth() + r.left;
r.bottom = customPinPadKeyboard.getKey_cancel().getHeight() + r.top;
pinpadLayout.setKeyCancel(r);
customPinPadKeyboard.getKey_clear().getLocationOnScreen(location);
r = new Rect();
r.left = location[0];
r.top = location[1];
r.right = customPinPadKeyboard.getKey_clear().getWidth() + r.left;
r.bottom = customPinPadKeyboard.getKey_clear().getHeight() + r.top;
pinpadLayout.setKeyClear(r);
customPinPadKeyboard.getKey_ok().getLocationOnScreen(location);
r = new Rect();
r.left = location[0];
r.top = location[1];
r.right = customPinPadKeyboard.getKey_ok().getWidth() + r.left;
r.bottom = customPinPadKeyboard.getKey_ok().getHeight() + r.top;
pinpadLayout.setKeyConfirm(r);
byte[] number = pinPad.setPinpadLayout(pinpadLayout);
OnPinPadInputListener pinPadInputListener = new OnPinPadInputListener() {
@Override
public void onInputResult(final int retCode, final byte[] data) {
if (retCode == SdkResult.Success) {
LogUtil.d(TAG, "Success");
if(isOnlinePin) {
mPayDetail.setPINCipher(ByteUtil.bytes2HexStr(data));
}
mHandler.obtainMessage(PIN_CLICK_CONFIRM).sendToTarget();
} else if (retCode == SdkResult.Fail) {
LogUtil.d(TAG, "Failure");
} else if (retCode == SdkResult.PinPad_Input_Cancel) {
LogUtil.d(TAG, "Cancel");
mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
} else if (retCode == SdkResult.PinPad_Input_Timeout) {
mHandler.obtainMessage(PIN_TIME_OUT,-7009).sendToTarget();
} else if (retCode == SdkResult.PinPad_No_Pin_Input) {
mHandler.obtainMessage(PIN_CLICK_CONFIRM).sendToTarget();
} else {
mHandler.obtainMessage(PIN_ERROR).sendToTarget();
}
LogUtil.d(TAG, "RetCode:" + retCode);
LogUtil.d(TAG, "data bytes:" + ByteUtil.bytes2HexStr(data));
}
}
}
);
}
}
private void setupPinPadLayout(boolean isOnlinePin) {
LogUtil.d(TAG, "inside the global layout!");
PinpadLayoutEntity pinpadLayout = new PinpadLayoutEntity();
@Override
public void onSendKey(byte keyCode) {
increaseCount();
if (keyCode == PinPadKeyCode.KEYCODE_CLEAR) {
LogUtil.d(TAG, "on clear");
mHandler.obtainMessage(PIN_CLICK_CLEAR).sendToTarget();
} else if (keyCode == PinPadKeyCode.KEYCODE_CANCEL) {
LogUtil.d(TAG, "on click cancel");
mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
} else if (keyCode == PinPadKeyCode.KEYCODE_CONFIRM) {
LogUtil.d(TAG, "on click confirm");
mHandler.obtainMessage(PIN_CLICK_CONFIRM).sendToTarget();
} else {
LogUtil.d(TAG, "on click number");
mHandler.obtainMessage(PIN_CLICK_NUMBER, pinEnterCount, 0).sendToTarget();
}
LogUtil.d(TAG, "SendKey: " + ByteUtil.byte2HexStr(keyCode));
}
};
// Helper to avoid repetition
pinpadLayout.setKey1(getRectForView(customPinPadKeyboard.getKey_1()));
pinpadLayout.setKey2(getRectForView(customPinPadKeyboard.getKey_2()));
pinpadLayout.setKey3(getRectForView(customPinPadKeyboard.getKey_3()));
pinpadLayout.setKey4(getRectForView(customPinPadKeyboard.getKey_4()));
pinpadLayout.setKey5(getRectForView(customPinPadKeyboard.getKey_5()));
pinpadLayout.setKey6(getRectForView(customPinPadKeyboard.getKey_6()));
pinpadLayout.setKey7(getRectForView(customPinPadKeyboard.getKey_7()));
pinpadLayout.setKey8(getRectForView(customPinPadKeyboard.getKey_8()));
pinpadLayout.setKey9(getRectForView(customPinPadKeyboard.getKey_9()));
pinpadLayout.setKey10(getRectForView(customPinPadKeyboard.getKey_0()));
pinpadLayout.setKeyCancel(getRectForView(customPinPadKeyboard.getKey_cancel()));
pinpadLayout.setKeyClear(getRectForView(customPinPadKeyboard.getKey_clear()));
pinpadLayout.setKeyConfirm(getRectForView(customPinPadKeyboard.getKey_ok()));
byte[] number = pinPad.setPinpadLayout(pinpadLayout);
OnPinPadInputListener pinPadInputListener = new OnPinPadInputListener() {
@Override
public void onInputResult(final int retCode, final byte[] data) {
if (retCode == SdkResult.Success) {
LogUtil.d(TAG, "Success");
if(isOnlinePin) {
mPayDetail.setPINCipher(ByteUtil.bytes2HexStr(data));
}
mHandler.obtainMessage(PIN_CLICK_CONFIRM).sendToTarget();
} else if (retCode == SdkResult.Fail) {
LogUtil.d(TAG, "Failure");
} else if (retCode == SdkResult.PinPad_Input_Cancel) {
LogUtil.d(TAG, "Cancel");
mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
} else if (retCode == SdkResult.PinPad_Input_Timeout) {
mHandler.obtainMessage(PIN_TIME_OUT,-7009).sendToTarget();
} else if (retCode == SdkResult.PinPad_No_Pin_Input) {
mHandler.obtainMessage(PIN_CLICK_CONFIRM).sendToTarget();
} else {
mHandler.obtainMessage(PIN_ERROR).sendToTarget();
}
LogUtil.d(TAG, "RetCode:" + retCode);
LogUtil.d(TAG, "data bytes:" + ByteUtil.bytes2HexStr(data));
}
@Override
public void onSendKey(byte keyCode) {
increaseCount();
if (keyCode == PinPadKeyCode.KEYCODE_CLEAR) {
LogUtil.d(TAG, "on clear");
mHandler.obtainMessage(PIN_CLICK_CLEAR).sendToTarget();
} else if (keyCode == PinPadKeyCode.KEYCODE_CANCEL) {
LogUtil.d(TAG, "on click cancel");
mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
} else if (keyCode == PinPadKeyCode.KEYCODE_CONFIRM) {
LogUtil.d(TAG, "on click confirm");
mHandler.obtainMessage(PIN_CLICK_CONFIRM).sendToTarget();
} else {
LogUtil.d(TAG, "on click number");
mHandler.obtainMessage(PIN_CLICK_NUMBER, pinEnterCount, 0).sendToTarget();
}
LogUtil.d(TAG, "SendKey: " + ByteUtil.byte2HexStr(keyCode));
}
};
if (number != null) {
customPinPadKeyboard.setKeyBoard(number);
if (number != null) {
customPinPadKeyboard.setKeyBoard(number);
// customPinPadKeyboard.setKeyBoard(ByteUtil.bytes2HexStr(number));
LogUtil.d(TAG, "PinPad: " + ByteUtil.bytes2HexStr(number));
int[] supperLen = new int[]{0x00, 0x04, 0x06, 0x0c};
LogUtil.d(TAG, "PinPad: " + ByteUtil.bytes2HexStr(number));
int[] supperLen = new int[]{0x00, 0x04, 0x06, 0x0c};
pinPad.setPinKeyboardViewMode(PinKeyboardViewModeEnum.DEFAULT);
pinPad.setPinKeyboardMode(PinKeyboardModeEnum.FIXED);
pinPad.setPinKeyboardViewMode(PinKeyboardViewModeEnum.DEFAULT);
pinPad.setPinKeyboardMode(PinKeyboardModeEnum.FIXED);
// pinPad.setAlgorithmMode(AlgorithmModeEnum.DES);
if(cardNo == null){
cardNo = emvHandler.getEmvCardDataInfo().getCardNo();
}
int length = cardNo.length();
byte[] panBytes = cardNo.substring( length- 13).getBytes(StandardCharsets.US_ASCII);
LogUtil.d(TAG,"card num :"+cardNo);
LogUtil.d(TAG,"Is Online Pin:"+isOnlinePin);
if(cardNo == null){
cardNo = emvHandler.getEmvCardDataInfo().getCardNo();
}
int length = cardNo.length();
byte[] panBytes = cardNo.substring( length- 13).getBytes(StandardCharsets.US_ASCII);
LogUtil.d(TAG,"card num :"+cardNo);
LogUtil.d(TAG,"Is Online Pin:"+isOnlinePin);
// pinPad.inputOnlinePin(supperLen, 60, pan, 0, PinAlgorithmModeEnum.ISO9564FMT0, pinPadInputListener);
if (isOnlinePin) {
if (isOnlinePin) {
pinPad.inputOnlinePin(supperLen, 60, panBytes, pinIndex, PinAlgorithmModeEnum.ISO9564FMT0, pinPadInputListener);
pinPad.inputOnlinePin(supperLen, 60, panBytes, pinIndex, PinAlgorithmModeEnum.ISO9564FMT0, pinPadInputListener);
} else {
mPayDetail.transCVM = TransCVM.OFFLINE_PIN;
pinPad.inputOfflinePin(supperLen, 60, pinPadInputListener);
}
}
}
}
);
} else {
mPayDetail.transCVM = TransCVM.OFFLINE_PIN;
pinPad.inputOfflinePin(supperLen, 60, pinPadInputListener);
}
}
}
// Reusable rect helper
private Rect getRectForView(View view) {
int[] location = new int[2];
view.getLocationOnScreen(location);
Rect r = new Rect();
r.left = location[0];
r.top = location[1];
r.right = view.getWidth() + r.left;
r.bottom = view.getHeight() + r.top;
return r;
}
private void increaseCount() {
@ -613,11 +676,11 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
}
} else {
//contact terminal capability ; if different card brand(depend on aid) have different terminal capability
// if (ByteUtils.byteArray2HexString(aid).toUpperCase().contains("A000000004")) {
// emvHandler.setTlv(new byte[]{(byte) 0x9F, (byte) 0x33}, ByteUtil.hexStr2Bytes(terminalCapability));
// emvHandler.setTlv(new byte[]{(byte) 0xE0, (byte) 0x1D}, ByteUtils.hexString2ByteArray("6C00800000000000"));//terminal risk
//
// }
if (ByteUtils.byteArray2HexString(aid).toUpperCase().contains("A000000004")) {
emvHandler.setTlv(new byte[]{(byte) 0x9F, (byte) 0x33}, ByteUtil.hexStr2Bytes(terminalCapability));
emvHandler.setTlv(new byte[]{(byte) 0xE0, (byte) 0x1D}, ByteUtils.hexString2ByteArray("6C00800000000000"));//terminal risk
}
}
emvHandler.onSetTransInitBeforeGPOResponse(true);
@ -642,9 +705,6 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
public void onCardHolderInputPin(boolean isOnlinePin, int leftTimes) {
LogUtil.d(TAG, "onCardHolderInputPin isOnlinePin = " + isOnlinePin);
LogUtil.d(TAG, "onCardHolderInputPin leftTimes = " + leftTimes);
if (isOnlinePin) {
pinRemainingCount.postValue("");
}
// startPinProcess(isOnlinePin ? 1 : 0);
mProcessStep = EMV_SHOW_PIN_PAD;
// mHandler.obtainMessage(EMV_SHOW_PIN_PAD, isOnlinePin ? 1 : 0).sendToTarget();
@ -683,17 +743,7 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
@Override
public void onPrompt(PromptEnum promptEnum) {
LogUtil.d(TAG, "onPrompt->" + promptEnum);
if( promptEnum == PromptEnum.OFFLINE_PIN_INCORRECT_TRY_AGAIN) {
offlinePinIncorrectPromptCount++;
pinEnterCount = 0;
pinText.postValue("");
int attemptLeft = Math.max(0, 3 - offlinePinIncorrectPromptCount);
pinRemainingCount.postValue("Please try again!\n" + attemptLeft + " attempt left!");
emvHandler.onSetPromptResponse(false);
} else {
emvHandler.onSetPromptResponse(true);
}
emvHandler.onSetPromptResponse(true);
}
@Override
@ -751,9 +801,6 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
byte[] tlv_50 = emvHandler.getTlv(new byte[]{(byte) 0x50}, EmvDataSourceEnum.FROM_KERNEL);
LogUtil.d(TAG, "tlv_50--" + ByteUtils.byteArray2HexString(tlv_50));
byte[] tlv_9B = emvHandler.getTlv(new byte[]{(byte) 0x9B}, EmvDataSourceEnum.FROM_KERNEL);
LogUtil.d(TAG, "tlv_9B--" + ByteUtils.byteArray2HexString(tlv_9B));
switch (retCode) {
case SdkResult.Emv_Success_Arpc_Fail:
case SdkResult.Success:
@ -920,7 +967,6 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
emvCardType.postValue("");
pinText.setValue("");
pinEnterCount = 0;
offlinePinIncorrectPromptCount = 0;
}
protected void getCardInfo() {
@ -1211,6 +1257,7 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
kernelTTQ[2] = TTQ[2];
kernelTTQ[3] = TTQ[3];
// FIXME: 2019/3/20
//If there is no special requirements, do not change TTQ byte1
//if online force required , can set byte2 bit 8 = 1
emvHandler.setTlv(ByteUtils.hexString2ByteArray("9F66"), kernelTTQ);

View File

@ -14,7 +14,7 @@
"tacOnline": "DC4004F800",
"tacDenial": "0000000000",
"floorLimit": "000000000000",
"cvmLimit": 30000,
"cvmLimit": 75000,
"transLimit": "9999999999",
"transLimitCDV": "9999999999",
"terminalCapability": "0000000000000000",
@ -26,6 +26,7 @@
},
{
"aidEnable": true,
"aid": "A000000333010102",
"cardLabel": "UPI",
"applicationVersion": "0002",
"emvDDOL": "9F3704",
@ -38,57 +39,7 @@
"tacOnline": "DC4004F800",
"tacDenial": "0000000000",
"floorLimit": "000000000000",
"cvmLimit": 30000,
"transLimit": "9999999999",
"transLimitCDV": "9999999999",
"terminalCapability": "0000000000000000",
"riskManageData": "01",
"kernelType": "01",
"ttq": "36800000",
"cateCode": "2701",
"currencyCode": "0104"
},
{
"aidEnable": true,
"aid": "A000000333010105",
"cardLabel": "UPI",
"applicationVersion": "0002",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
"targetPercent": "99",
"maxTargetPercent": "99",
"threshold": "00000000",
"tacDefault": "D84000A800",
"tacOnline": "DC4004F800",
"tacDenial": "0000000000",
"floorLimit": "000000000000",
"cvmLimit": 30000,
"transLimit": "9999999999",
"transLimitCDV": "9999999999",
"terminalCapability": "0000000000000000",
"riskManageData": "01",
"kernelType": "01",
"ttq": "36800000",
"cateCode": "2701",
"currencyCode": "0104"
},
{
"aidEnable": true,
"aid": "A000000333010106",
"cardLabel": "UPI",
"applicationVersion": "0002",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
"targetPercent": "99",
"maxTargetPercent": "99",
"threshold": "00000000",
"tacDefault": "D84000A800",
"tacOnline": "DC4004F800",
"tacDenial": "0000000000",
"floorLimit": "000000000000",
"cvmLimit": 30000,
"cvmLimit": 75000,
"transLimit": "9999999999",
"transLimitCDV": "9999999999",
"terminalCapability": "0000000000000000",

View File

@ -6,7 +6,6 @@ import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import com.nexgo.common.LogUtils;
import com.nexgo.oaf.apiv3.SdkResult;
import com.nexgo.oaf.apiv3.device.reader.CardInfoEntity;
import com.nexgo.oaf.apiv3.device.reader.CardSlotTypeEnum;
@ -107,14 +106,6 @@ public class CheckCardX {
Log.d(TAG, "Find IC");
} else if(cardInfoEntity.getCardExistslot() == CardSlotTypeEnum.RF) {
checkCardResultX.onSuccess(CardTypeX.NFC,false);
} else if(cardInfoEntity.getCardExistslot() == CardSlotTypeEnum.SWIPE) {
LogUtils.debug(TAG,"Found Swipe");
Bundle info = new Bundle();
info.putString("TRACK1",cardInfoEntity.getTk1());
info.putString("TRACK2",cardInfoEntity.getTk2());
info.putString("TRACK3",cardInfoEntity.getTk3());
MAGXReadCard.getInstance().setBundle(info);
checkCardResultX.onSuccess(CardTypeX.MAG,false);
}
} else if( i == SdkResult.Fail) {
checkCardResultX.onError(i,"Failure");

View File

@ -1,10 +1,9 @@
package com.utsmyanmar.paylibs.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class CardSettleData implements Serializable {
public class CardSettleData {
private String cardType;
private String cardNum;

View File

@ -1,10 +1,9 @@
package com.utsmyanmar.paylibs.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class QRSettleData implements Serializable {
public class QRSettleData {
private String transId;
private String date;

View File

@ -1,8 +1,6 @@
package com.utsmyanmar.paylibs.model;
import java.io.Serializable;
public class SettleData implements Serializable {
public class SettleData {
private int saleCount;
private long saleAmount;

View File

@ -1,8 +1,6 @@
package com.utsmyanmar.paylibs.model.enums;
import java.io.Serializable;
public enum TransCVM implements Serializable {
public enum TransCVM {
OFFLINE_PIN("Offline PIN"),
ONLINE_PIN("Online PIN"),
SIGNATURE("Signature"),

View File

@ -154,6 +154,7 @@ public class AuthorizationProcessUtil {
hexValues[i] = value;
}
int status;
String f055Data = getF055Data();
LogUtil.d(TAG,"is equal:"+equals);
LogUtil.d(TAG,"Emv Online Result:"+emvOnlineResult);
if (equals) {
@ -176,7 +177,7 @@ public class AuthorizationProcessUtil {
LogUtil.e(Constant.TAG, "scriptResult: " + scriptResult);
payDetail.setScriptResult(scriptResult);
String f055Data = getF055Data();
LogUtil.e(Constant.TAG, "f055Data: " + f055Data);
// if (status >= 0) {
@ -204,9 +205,6 @@ public class AuthorizationProcessUtil {
private void importOnlineProcessStatus(int sdkResult,EmvOnlineResultEntity emvOnlineResult) {
LogUtil.d(TAG, "importOnlineProcessStatus sdkResult:"+sdkResult);
LogUtil.d(TAG, "importOnlineProcessStatus emvOnlineResult:"+emvOnlineResult.toString());
LogUtil.d(TAG, "importOnlineProcessStatus emvOnlineResult:"+emvOnlineResult.getAuthCode());
LogUtil.d(TAG, "importOnlineProcessStatus emvOnlineResult:"+emvOnlineResult.getRejCode());
LogUtil.d(TAG, "importOnlineProcessStatus emvOnlineResult:"+ ByteUtil.bytes2HexStr(emvOnlineResult.getRecvField55()));
PayLibNex.getInstance().deviceEngine.getEmvHandler2("app2").onSetOnlineProcResponse(sdkResult, emvOnlineResult);
}

View File

@ -2,10 +2,7 @@ package com.utsmyanmar.paylibs.utils.core_utils;
import android.text.TextUtils;
import com.nexgo.oaf.apiv3.emv.EmvDataSourceEnum;
import com.nexgo.oaf.apiv3.emv.EmvHandler2;
import com.utsmyanmar.paylibs.Constant;
import com.utsmyanmar.paylibs.PayLibNex;
import com.utsmyanmar.paylibs.model.BaseCardInfo;
import com.utsmyanmar.paylibs.model.CardInfo;
import com.utsmyanmar.paylibs.model.ICCardInfo;
@ -673,42 +670,43 @@ public class KernelDataProcessUtil {
}
LogUtil.d(TAG,"9F6E data :"+hexStr);
byte[] dataOut = new byte[1024];
EmvHandler2 emvHandler = PayLibNex.getInstance().deviceEngine.getEmvHandler2("app2");
try {
byte[] dateValue = emvHandler.getTlv(ByteUtil.hexStr2Bytes("9F6E"), EmvDataSourceEnum.FROM_CARD);
if (dateValue != null) {
hexStr = ByteUtil.bytes2HexStr(dateValue);
LogUtil.d(TAG, "get 9F6E Data :" + hexStr);
} else {
LogUtil.e(TAG, "Get the data length of payWave is null = " );
}
} catch (Exception e) {
e.printStackTrace();
}
// byte[] dataOut = new byte[1024];
//
// try {
// int len = PayLibsUtils.getInstance().emvOptV2.getTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_PAYWAVE, tagList, dataOut);
// if (len > 0) {
// byte[] dataOutBytes = Arrays.copyOf(dataOut, len);
// hexStr = ByteUtil.bytes2HexStr(dataOutBytes);
// LogUtil.d(TAG, "get 9F6E Data :" + hexStr);
// Map<String, TLV> map = TLVUtil.buildTLVMap(hexStr);
// LogUtil.d(TAG, "get 9F6E Data :" + map);
//
// } else {
// LogUtil.e(TAG, "Get the data length of payWave is negative = " + len);
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
//
// if (hexStr.equals("9F6E00")) {
// try {
// byte[] dateValue = emvHandler.getTlv(ByteUtil.hexStr2Bytes("9F6E"), EmvDataSourceEnum.FROM_CARD);
// if (dateValue != null) {
// hexStr = ByteUtil.bytes2HexStr(dateValue);
// int len = PayLibsUtils.getInstance().emvOptV2.getTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_PAYPASS, tagList, dataOut);
// if (len > 0) {
// byte[] dataOutBytes = Arrays.copyOf(dataOut, len);
// hexStr = ByteUtil.bytes2HexStr(dataOutBytes);
// LogUtil.d(TAG, "get 9F6E Data :" + hexStr);
// Map<String, TLV> map = TLVUtil.buildTLVMap(hexStr);
// LogUtil.d(TAG, "get 9F6E Data :" + map);
//
// } else {
// LogUtil.e(TAG, "Get the data length of payPass is null = ");
// LogUtil.e(TAG, "Get the data length of payPass is negative = " + len);
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// if (!hexStr.isEmpty()) {
// f55WaveDataStr += "9F6E04"+hexStr;
// if (!hexStr.equals("9F6E00")) {
// f55WaveDataStr += hexStr;
// }
icCardInfo.setICC55(f55WaveDataStr);
payDetail.setICC55(f55WaveDataStr);

View File

@ -69,8 +69,7 @@ public class BitmapConfig {
// public static final String BPC_VOID = "3230058028C08000";
// commented on Nov 13,2024
// public static final String BPC_VOID = "3230058028C18000"; // original
public static final String BPC_VOID = "3230058028C08000"; // original March 25, 2026
public static final String BPC_VOID = "3230058028C18000"; // original
// public static final String BPC_VOID = "3230058028C08000"; // 16-May-2025 removed DE48 requested by KoAAT added DE2
// public static final String BPC_VOID = "3230058028C08000"; // 16-May-2025 removed DE48 requested by KoAAT
// public static final String BPC_VOID = "3230058028C18200";
@ -109,9 +108,8 @@ public class BitmapConfig {
// public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "7230058028C19800"; // added DE 2
// public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "7234058008C09000"; // for tmk MPU
// public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "7230058008C09000"; // for KBZ MPU
// public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "7234058008C09000"; // for KBZ MPU added DE 14 Mar 25, 26
public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "3230058028C08000"; // from log March 25
public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "7234058008C09000"; // for KBZ MPU added DE 14
// public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "3230058028C19800";
// public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "3230058028C19A00"; //DE55
//
// public static final String BPC_PRE_AUTH_SALE_COMPLETE_VOID = "3230058028C09200";

View File

@ -341,8 +341,7 @@ public class FieldUtils {
} else if (BaseCardType.IC.getValue() == cardType) { // IC
value = "05";
} else if (FALLBACK == cardType){ // Fallback
value = "72";
// value = "08";
value = "08";
} else { // Hand-in card number
value = "01";
}
@ -351,16 +350,11 @@ public class FieldUtils {
if(payDetail.getTransCVM() == TransCVM.OFFLINE_PIN) {
value += "9";
} else {
if(payDetail.getTransactionType() == VOID.value) {
value += "0";
if (payDetail.getPINCipher() != null && !payDetail.getPINCipher().trim().isEmpty()) {
value += "1";
} else {
if (payDetail.getPINCipher() != null && !payDetail.getPINCipher().trim().isEmpty()) {
value += "1";
} else {
value += "2";
}
value += "2";
}
}

View File

@ -32,7 +32,7 @@ include ':baselib'
include ':mpulib'
//include ':ecr-client-lib'
//include ':ecr-service'
include ':ecr-service'
include ':xpay'
include ':ecr'
include ':ecr-service-lib'