From e929f63618527dcc13f78733d78bc2d88930b9d8 Mon Sep 17 00:00:00 2001 From: kizzy Date: Sun, 17 May 2026 15:01:40 +0700 Subject: [PATCH] MPU-UPI contactless is restricted, need to put it in db later. --- .../kbz/ui/core_ui/CardWaitingFragment.java | 9 +++- .../ui/core_ui/EmvTransactionFragment.java | 11 +++++ .../EmvTransactionProcessViewModel.java | 3 ++ .../ui/core_viewmodel/SharedViewModel.java | 6 +++ .../baselib/util/enums/EmvResultStatus.java | 3 +- .../baselib/viewModel/EmvBaseViewModel.java | 48 +++++++++++++++++-- 6 files changed, 75 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_ui/CardWaitingFragment.java b/app/src/main/java/com/utsmm/kbz/ui/core_ui/CardWaitingFragment.java index 759f8b3..5ae02ab 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/core_ui/CardWaitingFragment.java +++ b/app/src/main/java/com/utsmm/kbz/ui/core_ui/CardWaitingFragment.java @@ -154,6 +154,9 @@ public class CardWaitingFragment extends DataBindingFragment implements DataBind } else if(sharedViewModel.getIsCardAppBlock().getValue() != null && sharedViewModel.getIsCardAppBlock().getValue()) { cardReadViewModel.setCheckCardAlertMsg("Magstripe not allowed!",false); setupCardReadProcess(true); + } else if(sharedViewModel.getIsContactlessRestricted().getValue() != null && sharedViewModel.getIsContactlessRestricted().getValue()) { + cardReadViewModel.setCheckCardAlertMsg("Tap not allowed!",false); + setupCardReadProcess(true); } else { setupCardReadProcess(false); } @@ -166,6 +169,7 @@ public class CardWaitingFragment extends DataBindingFragment implements DataBind sharedViewModel.setIsFallback(false); sharedViewModel.setIsSeePhone(false); + sharedViewModel.setIsContactlessRestricted(false); // cardReadViewModel.cancelCheckCard(); @@ -262,7 +266,10 @@ public class CardWaitingFragment extends DataBindingFragment implements DataBind } else if(!SystemParamsOperation.getInstance().isNfcEnabled()) { allType.add(CardSlotTypeEnum.ICC1); allType.add(CardSlotTypeEnum.SWIPE); - } else { + } else if(sharedViewModel.getIsContactlessRestricted().getValue() != null && sharedViewModel.getIsContactlessRestricted().getValue()) { + allType.add(CardSlotTypeEnum.ICC1); +// allType.add(CardSlotTypeEnum.SWIPE); + } else { allType.add(CardSlotTypeEnum.ICC1); allType.add(CardSlotTypeEnum.RF); diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_ui/EmvTransactionFragment.java b/app/src/main/java/com/utsmm/kbz/ui/core_ui/EmvTransactionFragment.java index babb908..ecd9418 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/core_ui/EmvTransactionFragment.java +++ b/app/src/main/java/com/utsmm/kbz/ui/core_ui/EmvTransactionFragment.java @@ -232,6 +232,17 @@ public class EmvTransactionFragment extends DataBindingFragment { case ON_NEXT_SCREEN: navigateToRRNScreen(); break; + case INSERT_OR_MANUAL: + if(cardReadViewModel.cardTypeData.getValue() != null && cardReadViewModel.cardTypeData.getValue() == CardTypeX.NFC.value) { + isCardTaped("Please insert or type card",new CardDetectCallback() { + @Override + public void onComplete() { + sharedViewModel.setIsContactlessRestricted(true); + navigateToCheckCard(); + } + }); + } + break; case READ_CARD_RETRY: LogUtil.d(TAG,"Card type :"+cardReadViewModel.cardTypeData.getValue()); if(cardReadViewModel.cardTypeData.getValue()!= null && cardReadViewModel.cardTypeData.getValue() == CardTypeX.IC.value) { diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/EmvTransactionProcessViewModel.java b/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/EmvTransactionProcessViewModel.java index 1f72414..8fe765d 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/EmvTransactionProcessViewModel.java +++ b/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/EmvTransactionProcessViewModel.java @@ -172,6 +172,9 @@ public class EmvTransactionProcessViewModel extends EmvBaseViewModel implements case EMV_TRY_AGAIN: emvResultStatus.postValue(EmvResultStatus.READ_CARD_RETRY); break; + case EMV_INSERT_OR_MANUAL: + emvResultStatus.postValue(EmvResultStatus.INSERT_OR_MANUAL); + break; case EMV_CARD_APP_BLOCK: emvResultStatus.postValue(EmvResultStatus.CARD_APP_BLOCKED); break; diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/SharedViewModel.java b/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/SharedViewModel.java index 669fb1c..f6b74bc 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/SharedViewModel.java +++ b/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/SharedViewModel.java @@ -168,6 +168,8 @@ public class SharedViewModel extends ViewModel { private SingleLiveEvent isFallback = new SingleLiveEvent<>(); private SingleLiveEvent isSeePhone = new SingleLiveEvent<>(); + + private SingleLiveEvent isContactlessRestricted = new SingleLiveEvent<>(); private SingleLiveEvent isCardAppBlock = new SingleLiveEvent<>(); private SingleLiveEvent _isCardDataExist = new SingleLiveEvent<>(); @@ -246,6 +248,10 @@ public class SharedViewModel extends ViewModel { public SingleLiveEvent getIsSeePhone() { return isSeePhone;} + public void setIsContactlessRestricted(boolean status) { isContactlessRestricted.setValue(status);} + + public SingleLiveEvent getIsContactlessRestricted() {return isContactlessRestricted;} + public void setCardDataExist(boolean exist) { _isCardDataExist.setValue(exist);} public SingleLiveEvent getCardDataExist() { return _isCardDataExist; } diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/util/enums/EmvResultStatus.java b/baselib/src/main/java/com/utsmyanmar/baselib/util/enums/EmvResultStatus.java index fd9d20c..f6b5fea 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/util/enums/EmvResultStatus.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/util/enums/EmvResultStatus.java @@ -31,5 +31,6 @@ public enum EmvResultStatus { MPU_CARD, SEE_PHONE, OTHER_INTERFACE, - CARD_APP_BLOCKED + CARD_APP_BLOCKED, + INSERT_OR_MANUAL } diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/viewModel/EmvBaseViewModel.java b/baselib/src/main/java/com/utsmyanmar/baselib/viewModel/EmvBaseViewModel.java index 8bdf03d..de8478f 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/viewModel/EmvBaseViewModel.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/viewModel/EmvBaseViewModel.java @@ -159,6 +159,7 @@ public abstract class EmvBaseViewModel extends BaseViewModel { protected static final int EMV_ERROR = 12; protected static final int EMV_TRY_AGAIN = 13; + protected static final int EMV_INSERT_OR_MANUAL = 24; protected static final int EMV_CARD_APP_BLOCK = 23; protected static final int EMV_CTLS_TRY_AGAIN = 13; @@ -179,6 +180,21 @@ public abstract class EmvBaseViewModel extends BaseViewModel { protected int mProcessStep; protected int mAppSelect = 0; + private static final String[] RESTRICTED_BINS = {"624430", + "624431", + "624445", + "626220", + "623476", + "629214", + "623466", + "623433", + "62911028", + "62441900", + "62441901" + }; + + private boolean isMPU_UPIContactless = false; + private boolean mMPUContactlessConfigured = false; private Looper mLooper = Looper.getMainLooper(); private final Handler mHandler = new Handler(mLooper) { @@ -215,7 +231,7 @@ public abstract class EmvBaseViewModel extends BaseViewModel { public void startProcess() { isOfflinePinEntered = false; mMPUContactlessConfigured = false; - + isMPU_UPIContactless = false; initData(); // Check if initialization was successful @@ -522,6 +538,16 @@ public abstract class EmvBaseViewModel extends BaseViewModel { ++pinEnterCount; } + private boolean isRestrictedBin(String cardNo) { + if (cardNo == null || cardNo.isEmpty()) return false; + for (String bin : RESTRICTED_BINS) { + if (cardNo.startsWith(bin)) { + LogUtil.d(TAG, "isRestrictedBin: matched BIN " + bin); + return true; + } + } + return false; + } private OnEmvProcessListener2 emvProcessListener = new OnEmvProcessListener2() { @Override @@ -587,7 +613,7 @@ public abstract class EmvBaseViewModel extends BaseViewModel { } else if (aidStr.contains("A000000003")) { configPaywaveParameters(); } else if (aidStr.contains("A000000333")) { - configureQuickPassParamerter(); +// configureQuickPassParamerter(); } else if (aidStr.contains("A000000541")) { configPureContactlessParameter(); } else if (aidStr.contains("A000000065")) { @@ -650,6 +676,17 @@ public abstract class EmvBaseViewModel extends BaseViewModel { cardNo = cardInfoEntity.getCardNo(); + + if (mPayDetail.getCardType() == CardTypeX.NFC.value) { + if (isRestrictedBin(cardNo)) { + isMPU_UPIContactless = true; + LogUtil.d(TAG, "onConfirmCardNo: restricted BIN detected — " + cardNo); + emvHandler.onSetConfirmCardNoResponse(false); + emvHandler.emvProcessCancel(); + } + } + + if (mPayDetail.getCardType() == CardTypeX.NFC.value) { cardNum.postValue(cardInfoEntity.getCardNo()); mPayDetail.setCardNo(cardInfoEntity.getCardNo()); @@ -821,7 +858,12 @@ public abstract class EmvBaseViewModel extends BaseViewModel { // case SdkResult.Emv_Cancel:// Transaction Cancel // //user cancel - mHandler.obtainMessage(EMV_ERROR, retCode, retCode, "Canceled").sendToTarget(); + if(isMPU_UPIContactless) { + mHandler.sendEmptyMessage(EMV_INSERT_OR_MANUAL); + } else { + mHandler.obtainMessage(EMV_ERROR, retCode, retCode, "Canceled").sendToTarget(); + } + break; // // case SdkResult.Emv_Offline_Declined: //