fixed for pinpad retry
This commit is contained in:
parent
ffc3908446
commit
e60985b2ec
@ -290,7 +290,7 @@ public class CardWaitingFragment extends DataBindingFragment implements DataBind
|
||||
|
||||
} else if (isFallback && cardType == CardTypeX.MAG) {
|
||||
/* do fallback transactions */
|
||||
sharedViewModel.isEmv.setValue(false);
|
||||
sharedViewModel.isEmv.postValue(false);
|
||||
cardReadViewModel.setCardTransactionType(CardTransactionType.FALLBACK);
|
||||
|
||||
} else if (cardType == CardTypeX.IC || cardType == CardTypeX.NFC) {
|
||||
|
||||
@ -244,7 +244,7 @@ public class EmvTransactionFragment extends DataBindingFragment {
|
||||
isCardTaped("Please try again",new CardDetectCallback() {
|
||||
@Override
|
||||
public void onComplete() {
|
||||
sharedViewModel.setIsSeePhone(true);
|
||||
sharedViewModel.setIsSeePhone(false);
|
||||
navigateToCheckCard();
|
||||
}
|
||||
});
|
||||
|
||||
@ -413,6 +413,7 @@ public class EmvParamHelper {
|
||||
aidV2.setTransType("FF");
|
||||
aidV2.setOnlinePinCap(1);
|
||||
aidV2.setAsi(1);
|
||||
aidV2.setThreshold(99);
|
||||
|
||||
if (!(contactAid.getCvmLimit() < 0)) {
|
||||
aidV2.setContactlessCvmLimit(contactAid.getCvmLimit());
|
||||
|
||||
@ -6,6 +6,7 @@ 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 androidx.annotation.NonNull;
|
||||
@ -260,7 +261,8 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
|
||||
unionPayTransDataEntity.setSupportCDCVM(true);
|
||||
//if support QPS, please enable below lines
|
||||
unionPayTransDataEntity.setSupportContactlessQps(true);
|
||||
unionPayTransDataEntity.setContactlessQpsLimit("000090000000");
|
||||
unionPayTransDataEntity.setContactlessQpsLimit("000000030000");
|
||||
|
||||
transData.setUnionPayTransDataEntity(unionPayTransDataEntity);
|
||||
|
||||
|
||||
@ -425,213 +427,142 @@ 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!");
|
||||
customPinPadKeyboard.getViewTreeObserver().addOnGlobalLayoutListener(
|
||||
new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
customPinPadKeyboard.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
LogUtil.d(TAG, "pin pad is visible now!");
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@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);
|
||||
// customPinPadKeyboard.setKeyBoard(ByteUtil.bytes2HexStr(number));
|
||||
|
||||
LogUtil.d(TAG, "PinPad: " + ByteUtil.bytes2HexStr(number));
|
||||
int[] supperLen = new int[]{0x00, 0x04, 0x06, 0x0c};
|
||||
|
||||
|
||||
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);
|
||||
// pinPad.inputOnlinePin(supperLen, 60, pan, 0, PinAlgorithmModeEnum.ISO9564FMT0, pinPadInputListener);
|
||||
if (isOnlinePin) {
|
||||
|
||||
pinPad.inputOnlinePin(supperLen, 60, panBytes, pinIndex, PinAlgorithmModeEnum.ISO9564FMT0, pinPadInputListener);
|
||||
|
||||
} else {
|
||||
mPayDetail.transCVM = TransCVM.OFFLINE_PIN;
|
||||
pinPad.inputOfflinePin(supperLen, 60, pinPadInputListener);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupPinPadLayout(boolean isOnlinePin) {
|
||||
LogUtil.d(TAG, "inside the global layout!");
|
||||
PinpadLayoutEntity pinpadLayout = new PinpadLayoutEntity();
|
||||
|
||||
// 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);
|
||||
// customPinPadKeyboard.setKeyBoard(ByteUtil.bytes2HexStr(number));
|
||||
|
||||
LogUtil.d(TAG, "PinPad: " + ByteUtil.bytes2HexStr(number));
|
||||
int[] supperLen = new int[]{0x00, 0x04, 0x06, 0x0c};
|
||||
|
||||
|
||||
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);
|
||||
// pinPad.inputOnlinePin(supperLen, 60, pan, 0, PinAlgorithmModeEnum.ISO9564FMT0, pinPadInputListener);
|
||||
if (isOnlinePin) {
|
||||
|
||||
pinPad.inputOnlinePin(supperLen, 60, panBytes, pinIndex, PinAlgorithmModeEnum.ISO9564FMT0, 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() {
|
||||
@ -676,11 +607,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);
|
||||
@ -743,7 +674,12 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
|
||||
@Override
|
||||
public void onPrompt(PromptEnum promptEnum) {
|
||||
LogUtil.d(TAG, "onPrompt->" + promptEnum);
|
||||
emvHandler.onSetPromptResponse(true);
|
||||
if( promptEnum == PromptEnum.OFFLINE_PIN_INCORRECT_TRY_AGAIN) {
|
||||
emvHandler.onSetPromptResponse(false);
|
||||
} else {
|
||||
emvHandler.onSetPromptResponse(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -341,7 +341,8 @@ public class FieldUtils {
|
||||
} else if (BaseCardType.IC.getValue() == cardType) { // IC
|
||||
value = "05";
|
||||
} else if (FALLBACK == cardType){ // Fallback
|
||||
value = "08";
|
||||
value = "72";
|
||||
// value = "08";
|
||||
} else { // Hand-in card number
|
||||
value = "01";
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user