MPU certification in progress

This commit is contained in:
kizzy 2026-06-10 16:40:02 +07:00
parent 8e6fde9856
commit 4fefae3646
13 changed files with 98 additions and 33 deletions

View File

@ -349,7 +349,15 @@ fun AppNavGraph(
launchSingleTop = true
}
},
onBack = { navController.popBackStack() }
onBack = { navController.popBackStack() },
onNavigateMain = {
navController.navigate(Routes.Dashboard.route) {
popUpTo(Routes.Dashboard.route) {
inclusive = false
}
launchSingleTop = true
}
}
)
}

View File

@ -22,7 +22,8 @@ fun PinPadRoute(
transProcessViewModel: TransProcessViewModel,
onNavigateInputRrn: () -> Unit,
onNavigateProcessing: () -> Unit,
onBack: () -> Unit
onBack: () -> Unit,
onNavigateMain: () -> Unit,
) {
val pinText by pinPadViewModel.pinText.collectAsStateWithLifecycle()
val alertMsg by pinPadViewModel.alertMsg.collectAsStateWithLifecycle()
@ -67,6 +68,9 @@ fun PinPadRoute(
onBack()
}
PinPadStatus.ON_ERROR -> {
onNavigateMain()
}
else -> {}
}
}

View File

@ -41,14 +41,22 @@ fun ProcessingRoute(
}
} else {
LaunchedEffect(Unit) {
transProcessViewModel.resetTransactionStatus()
transProcessViewModel.startOnlineProcess()
}
}
LaunchedEffect(transStatus) {
when(transStatus) {
TransResultStatus.SUCCESS -> onNavigateTransactionResult()
TransResultStatus.FAIL -> onNavigateTransactionResult()
TransResultStatus.SUCCESS -> {
sharedViewModel.payDetail.value = transProcessViewModel.payDetailResult.value
onNavigateTransactionResult()
}
TransResultStatus.FAIL -> {
sharedViewModel.payDetail.value = transProcessViewModel.payDetailResult.value
onNavigateTransactionResult()
}
TransResultStatus.REVERSAL_SUCCESS -> onNavigateMain()
TransResultStatus.REVERSAL_FAIL -> onNavigateMain()
else -> {}

View File

@ -92,6 +92,7 @@ class SettlementViewModel @Inject constructor(
init {
viewModelScope.launch {
records.asFlow().collect { list ->
setPayDetails(list)
setSettlementData(list)
}
}

View File

@ -1,5 +1,6 @@
package com.mob.utsmyanmar.ui.transaction_result
import android.R
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
@ -12,6 +13,7 @@ import androidx.compose.material.icons.filled.CalendarMonth
import androidx.compose.material.icons.filled.Numbers
import androidx.compose.material.icons.filled.Print
import androidx.compose.material.icons.rounded.Check
import androidx.compose.material.icons.rounded.Close
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@ -55,7 +57,8 @@ fun TransactionResultScreen(
Spacer(modifier = Modifier.height(8.dp))
SuccessIcon()
if(state.payDetail?.tradeAnswerCode.equals("00")) SuccessIcon()
else FailIcon()
Spacer(modifier = Modifier.height(16.dp))
@ -115,6 +118,7 @@ private fun SuccessIcon() {
),
contentAlignment = Alignment.Center
) {
Icon(
imageVector = Icons.Rounded.Check,
contentDescription = "Success",
@ -125,6 +129,42 @@ private fun SuccessIcon() {
}
}
@Composable
private fun FailIcon() {
Box(
modifier = Modifier.size(132.dp),
contentAlignment = Alignment.Center
) {
Box(
modifier = Modifier
.size(132.dp)
.background(
color = Color.Error.copy(alpha = 0.12f),
shape = CircleShape
)
)
Box(
modifier = Modifier
.size(96.dp)
.background(
color = Color.Error,
shape = CircleShape
),
contentAlignment = Alignment.Center
) {
Icon(
imageVector = Icons.Rounded.Close,
contentDescription = "Failed",
tint = Color.White,
modifier = Modifier.size(64.dp)
)
}
}
}
@Composable
private fun AmountCard(
amount: String

View File

@ -51,7 +51,10 @@ class TransactionResultViewModel @Inject constructor(
sharedViewModel: SharedViewModel
) {
when (event) {
TransactionResultEvent.Start -> start(sharedViewModel)
TransactionResultEvent.Start -> {
started = false
start(sharedViewModel)
}
TransactionResultEvent.BackClick -> isCardInside()
TransactionResultEvent.RetryPrint -> startPrintProcess(sharedViewModel, false)
TransactionResultEvent.PrintLater -> isCardInside()
@ -59,6 +62,7 @@ class TransactionResultViewModel @Inject constructor(
}
private fun start(sharedViewModel: SharedViewModel) {
if (started) return
started = true

View File

@ -62,6 +62,10 @@ class TransProcessViewModel @Inject constructor(
_transType.value = type
}
fun resetTransactionResultStatus() {
_transResultStatus.value = null
}
private val _printStatus =
MutableStateFlow(PrintStatus.FIRST_PRINT)

View File

@ -45,6 +45,7 @@ public final class TerminalKeyUtil {
int result = 0;
SystemParamsOperation.getInstance().setTMKIndex("9");
if(!SystemParamsOperation.getInstance().isInjectOnce()) {
try {
// result = mSecurityOptV2.saveKeyDukpt(AidlConstantsV2.Security.KEY_TYPE_DUPKT_IPEK,IPEKByte,IPEKKCVByte,KSNByte,AidlConstantsV2.Security.KEY_ALG_TYPE_3DES,9);

View File

@ -493,6 +493,11 @@ public class ISOSocket {
int len = -1;
if (reversalTestCaseFlag) {
len = inputStream.read(recBuff);
} else {
int lenn = inputStream.read(recBuff);
String received = ByteUtil.bytes2HexStr(recBuff);
LogUtil.d(TAG,"Received Response :"+received);
}
rLen = len;
@ -544,6 +549,11 @@ public class ISOSocket {
int len = -1;
if (reversalTestCaseFlag) {
len = inputStream.read(recBuff);
} else {
int lenn = inputStream.read(recBuff);
String received = ByteUtil.bytes2HexStr(recBuff);
LogUtil.d(TAG,"Received Response :"+received);
}
rLen = len;

View File

@ -16,7 +16,6 @@ import com.utsmyanmar.paylibs.network.ISOCallback;
import com.utsmyanmar.paylibs.network.ISOSocket;
import com.utsmyanmar.paylibs.utils.MessageType;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
import com.utsmyanmar.paylibs.utils.enums.CardScheme;
import com.utsmyanmar.paylibs.utils.enums.HostName;
import com.utsmyanmar.paylibs.utils.iso_utils.BitmapConfig;
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionType;
@ -26,6 +25,7 @@ import java.util.Map;
import sunmi.sunmiui.utils.LogUtil;
public class ReversalAction {
private static final String TAG = ReversalAction.class.getSimpleName();
@ -42,9 +42,6 @@ public class ReversalAction {
private ISOMsgX isoMsgX;
private boolean isVoid = false;
private boolean isPreAuthCancel = false;
public static ReversalAction getInstance() {
if (INSTANCE == null) {
INSTANCE = new ReversalAction();
@ -53,15 +50,13 @@ public class ReversalAction {
}
private ReversalAction() {
isoMsgX = new ISOMsgX.ISOMsgXBuilder(ISOVersion.VERSION_1993, ISOMode.ONLY_HEADER,HostName.MPU)
isoMsgX = new ISOMsgX.ISOMsgXBuilder(ISOVersion.VERSION_1993, ISOMode.ONLY_HEADER,HostName.FINEXUS)
.build();
}
public ReversalAction setData(TradeData tradeData) {
this.tradeData = tradeData;
payDetail = tradeData.getPayDetail();
isVoid = payDetail.getTransactionType() == TransactionsType.VOID.value;
isPreAuthCancel = payDetail.getTransactionType() == TransactionsType.PRE_AUTH_VOID.value;
payDetail.setTransactionType(TransactionType.REVERSAL);
// payDetail.setTransType(REVERSAL);
if (TextUtils.equals(payDetail.getAccountType(), MPU)) {
@ -134,19 +129,8 @@ public class ReversalAction {
public void startReversal(ReversalListener reversalListener) {
HostName hostName = HostName.BPC;
LogUtil.d(TAG, "Starting Reversal....");
boolean isUPI = TextUtils.equals(payDetail.getAccountType(), CardScheme.UPI.name);
String bitmap = BitmapConfig.BPC_AUTOMATIC_REVERSAL;
if((isVoid && isUPI) || (isPreAuthCancel && isUPI)) {
bitmap = BitmapConfig.BPC_AUTOMATIC_REVERSAL_UPI;
}
if(payDetail.getReversalReason().equals(Constant.ISSUER_AUTHENTICATION_FAILURE)) {
bitmap = BitmapConfig.BPC_AUTOMATIC_REVERSAL_DE55;
}
byte[] sendBytes = isoMsgX.buildISOPackets(tradeData, bitmap, MessageType.REVERSAL);
byte[] sendBytes = isoMsgX.buildISOPackets(tradeData, BitmapConfig.MPU_NEW_REVERSAL, MessageType.REVERSAL);
// byte[] sendBytes = isoMsgX.buildISOPackets(tradeData, BitmapConfig.BPC_AUTOMATIC_REVERSAL, MessageType.REVERSAL);
ISOSocket.getInstance().enqueue(sendBytes, sendBytes.length,true, new ISOCallback() {
@Override
public void onReceive(byte[] bytes, int length) {

View File

@ -137,7 +137,7 @@ public class SignOnProcess {
SystemParamsOperation.getInstance().saveKeyPIK(encryptedPIK, kcv);
// int res = PayLibNex.getInstance().deviceEngine.getPinPad().writeWKey(9, WorkKeyTypeEnum.PINKEY,encryptedPIK,encryptedPIK.length);
int res = PayLibsUtils.getInstance().securityOptV2.saveCiphertextKey(AidlConstantsV2.Security.KEY_TYPE_PIK, encryptedPIK, null, tmkIndex, AidlConstantsV2.Security.KEY_ALG_TYPE_3DES, 11);
int res = PayLibsUtils.getInstance().securityOptV2.saveCiphertextKey(AidlConstantsV2.Security.KEY_TYPE_PIK, encryptedPIK, null, 9, AidlConstantsV2.Security.KEY_ALG_TYPE_3DES, 11);
resultCode = res;
if (res < 0) {
flag = false;

View File

@ -270,7 +270,8 @@ public class FieldConfig {
/* FLD 48 */ {3, SDK_8583_LEN_BCD, 322, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, '0'},
// /* FLD 49 */ {0, SDK_8583_LEN_BCD, 3, SDK_8583_DATA_BCD, SDK_8583_ALIGN_R, '0'},
/* FLD 49 */ {0, SDK_8583_LEN_BCD, 3, SDK_8583_DATA_ASC, SDK_8583_ALIGN_R, ' '},
// /* FLD 49 */ {0, SDK_8583_LEN_BCD, 3, SDK_8583_DATA_ASC, SDK_8583_ALIGN_R, ' '},
/* FLD 49 */ {0, SDK_8583_LEN_BCD, 3, SDK_8583_DATA_BCD, SDK_8583_ALIGN_R, ' '},
/* FLD 50 */ {0, SDK_8583_LEN_BCD, 12, SDK_8583_DATA_BCD, SDK_8583_ALIGN_R, '0'},
/* FLD 51 */ {0, SDK_8583_LEN_BCD, 12, SDK_8583_DATA_BCD, SDK_8583_ALIGN_R, '0'},
/* FLD 52 */ {0, SDK_8583_LEN_BCD, 8, SDK_8583_DATA_BIT, SDK_8583_ALIGN_L, 0},
@ -289,15 +290,15 @@ public class FieldConfig {
/* FLD 59 */ {3, SDK_8583_LEN_BCD, 999, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, '0'},
// original /* FLD 60 */ {3, SDK_8583_LEN_BCD, 17, SDK_8583_DATA_BCD, SDK_8583_ALIGN_L, '0'},
// MPU /*FLD 60 */ {2, SDK_8583_LEN_BCD, 255, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, ' '},
/*FLD 60 */ {3, SDK_8583_LEN_BCD, 255, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, '0'},
/*FLD 60 */ {2, SDK_8583_LEN_BCD, 255, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, ' '}, // MPU
// /*FLD 60 */ {3, SDK_8583_LEN_BCD, 255, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, '0'},
/* FLD 61 */ {3, SDK_8583_LEN_BCD, 29, SDK_8583_DATA_BCD, SDK_8583_ALIGN_L, '0'},
// /* FLD 62 */ {3, SDK_8583_LEN_BCD, 255, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, '0'}, // Jun 1 2023
/* FLD 62 */ {2, SDK_8583_LEN_BCD, 255, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, ' '},
// /* FLD 62 */ {2, SDK_8583_LEN_BCD, 255, SDK_8583_DATA_BCD, SDK_8583_ALIGN_R, '0'},
// original /* FLD 63 */ {2, SDK_8583_LEN_BCD, 255, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, ' '},
/* FLD 63 */ {3, SDK_8583_LEN_BCD, 255, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, '0'},
/* FLD 63 */ {2, SDK_8583_LEN_BCD, 255, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, ' '}, // MPU
// /* FLD 63 */ {3, SDK_8583_LEN_BCD, 255, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, '0'},
/* FLD 64 */ {0, SDK_8583_LEN_BCD, 8, SDK_8583_DATA_BIT, SDK_8583_ALIGN_L, 0},
/* FLD 65 */ {0, SDK_8583_LEN_BCD, 8, SDK_8583_DATA_BIT, SDK_8583_ALIGN_L, 0},

View File

@ -381,7 +381,7 @@ public class FieldUtils {
// }
if(payDetail.getTransactionType() == REFUND.value) {
field.setDataStr("61");
field.setDataStr("00"); // MPU
} else if(payDetail.getCardType() == -1) {
field.setDataStr("08");
}