fixed ISO packet format for DE55

This commit is contained in:
kizzy 2026-01-09 17:35:37 +07:00
parent 6bb3ab45c1
commit 452f0beb97
9 changed files with 131 additions and 15 deletions

View File

@ -13,6 +13,12 @@
</DropdownSelection> </DropdownSelection>
<DialogSelection /> <DialogSelection />
</SelectionState> </SelectionState>
<SelectionState runConfigName="testSalePacket()">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
<SelectionState runConfigName="testResponseSalePacket()">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
</selectionStates> </selectionStates>
</component> </component>
</project> </project>

View File

@ -10,7 +10,6 @@ import org.junit.runner.RunWith;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import com.sunmi.pay.hardware.aidl.AidlConstants;
import com.utsmm.kbz.util.MockData; import com.utsmm.kbz.util.MockData;
import com.utsmm.kbz.util.TransactionUtil; import com.utsmm.kbz.util.TransactionUtil;
import com.utsmyanmar.checkxread.model.CardDataX; import com.utsmyanmar.checkxread.model.CardDataX;
@ -19,6 +18,7 @@ import com.utsmyanmar.paylibs.Constant;
import com.utsmyanmar.paylibs.isobuilder.ISOMode; import com.utsmyanmar.paylibs.isobuilder.ISOMode;
import com.utsmyanmar.paylibs.isobuilder.builderx.ISOMsgX; import com.utsmyanmar.paylibs.isobuilder.builderx.ISOMsgX;
import com.utsmyanmar.paylibs.isobuilder.builderx.ISOVersion; import com.utsmyanmar.paylibs.isobuilder.builderx.ISOVersion;
import com.utsmyanmar.paylibs.model.MsgField;
import com.utsmyanmar.paylibs.model.PayDetail; import com.utsmyanmar.paylibs.model.PayDetail;
import com.utsmyanmar.paylibs.model.TradeData; import com.utsmyanmar.paylibs.model.TradeData;
import com.utsmyanmar.paylibs.model.enums.TransCVM; import com.utsmyanmar.paylibs.model.enums.TransCVM;
@ -26,12 +26,15 @@ import com.utsmyanmar.paylibs.utils.LogUtil;
import com.utsmyanmar.paylibs.utils.MessageType; import com.utsmyanmar.paylibs.utils.MessageType;
import com.utsmyanmar.paylibs.utils.core_utils.ByteUtil; import com.utsmyanmar.paylibs.utils.core_utils.ByteUtil;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation; import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
import com.utsmyanmar.paylibs.utils.enums.BaseCardType;
import com.utsmyanmar.paylibs.utils.enums.HostName; import com.utsmyanmar.paylibs.utils.enums.HostName;
import com.utsmyanmar.paylibs.utils.iso_utils.BitmapConfig; import com.utsmyanmar.paylibs.utils.iso_utils.BitmapConfig;
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionType;
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType; import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
import com.utsmyanmar.paylibs.utils.params.Params; import com.utsmyanmar.paylibs.utils.params.Params;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
/** /**
* Instrumented test, which will execute on an Android device. * Instrumented test, which will execute on an Android device.
@ -76,6 +79,58 @@ public class ExampleInstrumentedTest {
} }
} }
@Test
public void testSalePacket() {
CardDataX cardDataX = MockData.getInstance().generateMPUCard();
TradeData tradeData = TransactionUtil.getInstance().initEMVTransaction(cardDataX, CardTypeX.IC);
PayDetail payDetail = tradeData.getPayDetail();
payDetail.setTransactionType(TransactionType.SALE);
String bitmap = BitmapConfig.BPC_SALE;
MessageType messageType = MessageType.FINANCIAL;
ISOMsgX isoMsgX = new ISOMsgX.ISOMsgXBuilder(ISOVersion.VERSION_1993, ISOMode.BOTH_HEADER_TPDU, HostName.BPC)
.build();
byte[] sendBytes;
try {
sendBytes = isoMsgX.buildISOPackets(tradeData, bitmap, messageType);
System.out.println("Hex Str : "+ ByteUtil.bytes2HexStr(sendBytes));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testResponseSalePacket() {
String resp = "0071600000051730323130723000000A80820031363437363137333130303030303030323730303030303030303030303030353530303030313039313634353532303030303033323630313039313731353532303031303030303735343431393130303030343733343531303400048A023936";
byte[] response = ByteUtil.hexStr2Bytes(resp);
String bitmap = BitmapConfig.BPC_SALE;
MessageType messageType = MessageType.FINANCIAL;
ISOMsgX isoMsgX = new ISOMsgX.ISOMsgXBuilder(ISOVersion.VERSION_1993, ISOMode.BOTH_HEADER_TPDU, HostName.BPC)
.build();
Map<String, MsgField> responseMap = isoMsgX.parseISOPackets(response,response.length);
System.out.println("Resp Str : "+ responseMap);
// try {
// responseMap = isoMsgX.parseISOPackets(response,response.length);
//
// System.out.println("Resp Str : "+ responseMap);
// } catch (Exception e) {
// e.printStackTrace();
// }
}
private TradeData setUpRebuildTransactions(TradeData tradeData, TransactionsType transactionsType, HostName hostName) { private TradeData setUpRebuildTransactions(TradeData tradeData, TransactionsType transactionsType, HostName hostName) {
LogUtil.d(Constant.TAG, "Starting Online Transaction--" + hostName + "--" + transactionsType); LogUtil.d(Constant.TAG, "Starting Online Transaction--" + hostName + "--" + transactionsType);
@ -159,7 +214,7 @@ public class ExampleInstrumentedTest {
/* /*
* new requirements */ * new requirements */
newPay.setCardType(AidlConstants.CardType.IC.getValue()); newPay.setCardType(BaseCardType.IC.getValue());
newPay.setPINCipher("55"); newPay.setPINCipher("55");
newPay.setTransCVM(TransCVM.SIGNATURE); newPay.setTransCVM(TransCVM.SIGNATURE);
} }

View File

@ -66,6 +66,25 @@ public class TransactionUtil {
return tradeData; return tradeData;
} }
public TradeData initEMVTransaction(CardDataX cardDataX,CardTypeX cardTypeX) {
LogUtil.d(TAG,"CardDataX : "+cardDataX.toString());
TradeData tradeData = Params.newTrade(false);
PayDetail payDetail = tradeData.getPayDetail();
payDetail.setCardNo(cardDataX.getPan());
payDetail.setEXPDate(cardDataX.getExp());
payDetail.setCardType(cardTypeX.value);
payDetail.setAccountType("VISA");
payDetail.setAmount(100000);
payDetail.setCardHolderName(cardDataX.getCardHolderName());
CardInfo cardInfo = new CardInfo();
MAGCardInfo magCardInfo = new MAGCardInfo();
magCardInfo.setTrack2Cipher(cardDataX.getTrack2());
cardInfo.setMAGCardInfo(magCardInfo);
payDetail.setCardInfo(cardInfo);
payDetail.setICC55("5F2A0201045F340100820218008407A0000000031010950580800080009A032601099C01009F02060000000500009F03060000000000009F090200209F100706011203A0B8009F1A0201049F1E0820202020202020209F26088D3992CD453684B69F2701809F3303E0E8C89F34031E03009B0268009F3501229F360200049F370416C252349F41030000019F530152");
return tradeData;
}
public TradeData initMagStripeTransaction(CardDataX cardDataX,boolean isFallback) { public TradeData initMagStripeTransaction(CardDataX cardDataX,boolean isFallback) {

View File

@ -353,7 +353,12 @@ public class DecodePackage {
if (outField.getLengthType() > 0) { if (outField.getLengthType() > 0) {
int varLen; int varLen;
if( hostName == HostName.BPC) { if( hostName == HostName.BPC) {
if(outField.getFieldPos() == 55) {
varLen = (outField.getLengthType() + 1) / 2;
} else {
varLen = outField.getLengthType(); varLen = outField.getLengthType();
}
} else { } else {
varLen = (outField.getLengthType() + 1) / 2; varLen = (outField.getLengthType() + 1) / 2;
} }
@ -376,7 +381,13 @@ public class DecodePackage {
int datLen; int datLen;
int bcdLength = 0; int bcdLength = 0;
if( hostName == HostName.BPC) { if( hostName == HostName.BPC) {
if(outField.getFieldPos() == 55) {
bcdLength = Utils.bcdToint(varValue); //31
} else {
bcdLength = Integer.parseInt(new String(varValue)); //31 bcdLength = Integer.parseInt(new String(varValue)); //31
}
} else { } else {
bcdLength = Utils.bcdToint(varValue); //31 bcdLength = Utils.bcdToint(varValue); //31
// bcdLength = Integer.parseInt(new String(varValue)); //31 // bcdLength = Integer.parseInt(new String(varValue)); //31

View File

@ -233,14 +233,27 @@ public class EncodePackage {
// Data is variable length: spelling variable length values // Data is variable length: spelling variable length values
int dataType = msgField.getDataType(); int dataType = msgField.getDataType();
if (dataType == FieldConfig.SDK_8583_DATA_BIT) { if (dataType == FieldConfig.SDK_8583_DATA_BIT) {
byte[] varValue = (String.format("%0" + msgField.getLengthType() + "d", msgField.getDataLength()/2)).getBytes(); byte[] varValue;
// byte[] varValue = Utils.StrToBCDBytes(String.format("%0" + msgField.getLengthType() + "d", msgField.getDataLength() / 2)); if(entry.getKey().equals("F055")) {
varValue = Utils.StrToBCDBytes(String.format("%0" + msgField.getLengthType() + "d", msgField.getDataLength() / 2));
} else {
varValue = (String.format("%0" + msgField.getLengthType() + "d", msgField.getDataLength()/2)).getBytes();
}
//
System.arraycopy(varValue, 0, body, index, varValue.length); System.arraycopy(varValue, 0, body, index, varValue.length);
index += varValue.length; index += varValue.length;
} else if (dataType == FieldConfig.SDK_8583_DATA_BCD) { } else if (dataType == FieldConfig.SDK_8583_DATA_BCD) {
byte[] varValue; byte[] varValue;
if(hostName == HostName.BPC) {
if(hostName == HostName.BPC ) {
if(msgField.getLengthType() == 4) {
varValue = Utils.StrToBCDBytes(String.format("%0"+msgField.getLengthType() + "d",msgField.getDataLength()));
} else {
varValue = (String.format("%0" + msgField.getLengthType() + "d", msgField.getDataLength()/2)).getBytes(); varValue = (String.format("%0" + msgField.getLengthType() + "d", msgField.getDataLength()/2)).getBytes();
}
} else { } else {
varValue = Utils.StrToBCDBytes(String.format("%0"+msgField.getLengthType() + "d",msgField.getDataLength())); varValue = Utils.StrToBCDBytes(String.format("%0"+msgField.getLengthType() + "d",msgField.getDataLength()));
} }

View File

@ -536,7 +536,7 @@ public abstract class BaseXPrint {
lineBreak(); lineBreak();
} else { } else {
lineBreak(); // lineBreak();
emptyLine(1); emptyLine(1);
printer.appendPrnStr(BaseErrorCode.getCode(payDetail.getTradeAnswerCode()), fontNormal, AlignEnum.CENTER,true); printer.appendPrnStr(BaseErrorCode.getCode(payDetail.getTradeAnswerCode()), fontNormal, AlignEnum.CENTER,true);
emptyLine(1); emptyLine(1);

View File

@ -441,9 +441,11 @@ public class TransactionsOperation {
field39 = resp.get("F039"); field39 = resp.get("F039");
field55 = resp.get("F055"); field55 = resp.get("F055");
LogUtil.d(TAG,"Field 38:"+field38); if(equals)
LogUtil.d(TAG,"Field 39:"+field39); LogUtil.d(TAG,"Field 38:"+field38.getDataStr());
LogUtil.d(TAG,"Field 55:"+field55); LogUtil.d(TAG,"Field 39:"+field39.getDataStr());
LogUtil.d(TAG,"Field 55:"+field55.getDataStr());
if(equals)
emvOnlineResult.setAuthCode(field38.getDataStr()); emvOnlineResult.setAuthCode(field38.getDataStr());
emvOnlineResult.setRejCode(field39.getDataStr()); emvOnlineResult.setRejCode(field39.getDataStr());
emvOnlineResult.setRecvField55(ByteUtil.hexStr2Bytes(field55.getDataStr())); emvOnlineResult.setRecvField55(ByteUtil.hexStr2Bytes(field55.getDataStr()));

View File

@ -108,8 +108,8 @@ public class FieldConfig {
/* FLD 53 */ {2, SDK_8583_LEN_ASC, 32, SDK_8583_DATA_BCD, SDK_8583_ALIGN_L, '0'}, /* FLD 53 */ {2, SDK_8583_LEN_ASC, 32, SDK_8583_DATA_BCD, SDK_8583_ALIGN_L, '0'},
/* FLD 54 */ {3, SDK_8583_LEN_BCD, 40, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, ' '}, /* FLD 54 */ {3, SDK_8583_LEN_BCD, 40, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, ' '},
// /* FLD 55 */ {3, SDK_8583_LEN_ASC, 255, SDK_8583_DATA_BIT, SDK_8583_ALIGN_L, '0'}, /* FLD 55 */ {3, SDK_8583_LEN_ASC, 255, SDK_8583_DATA_BIT, SDK_8583_ALIGN_L, '0'},
/* FLD 55 */ {4, SDK_8583_LEN_BCD, 255, SDK_8583_DATA_BIT, SDK_8583_ALIGN_L, '0'}, // /* FLD 55 */ {4, SDK_8583_LEN_BCD, 255, SDK_8583_DATA_BIT, SDK_8583_ALIGN_L, '0'},
/* FLD 56 */ {0, SDK_8583_LEN_BCD, 12, SDK_8583_DATA_BCD, SDK_8583_ALIGN_R, '0'}, /* FLD 56 */ {0, SDK_8583_LEN_BCD, 12, SDK_8583_DATA_BCD, SDK_8583_ALIGN_R, '0'},
// /* FLD 57 */ {3, SDK_8583_LEN_BCD, 999, SDK_8583_DATA_ASC, SDK_8583_ALIGN_R, '0'}, // /* FLD 57 */ {3, SDK_8583_LEN_BCD, 999, SDK_8583_DATA_ASC, SDK_8583_ALIGN_R, '0'},

View File

@ -4,7 +4,10 @@ import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import com.utsmyanmar.paylibs.model.MsgField;
import com.utsmyanmar.paylibs.print.PrintUtils; import com.utsmyanmar.paylibs.print.PrintUtils;
import com.utsmyanmar.paylibs.utils.core_utils.ByteUtil;
import com.utsmyanmar.paylibs.utils.core_utils.Utils;
/** /**
* Example local unit test, which will execute on the development machine (host). * Example local unit test, which will execute on the development machine (host).
@ -25,5 +28,12 @@ public class ExampleUnitTest {
String converted = PrintUtils.getInstance().getSeparatorOnlyNumberFormat(num); String converted = PrintUtils.getInstance().getSeparatorOnlyNumberFormat(num);
System.out.println("Converted Number: " + converted); System.out.println("Converted Number: " + converted);
MsgField msgField = new MsgField();
msgField.setLengthType(4);
msgField.setDataLength(255);
byte[] res = Utils.StrToBCDBytes(String.format("%0"+msgField.getLengthType() + "d",msgField.getDataLength()));
System.out.println("result : "+ ByteUtil.bytes2HexStr(res));
} }
} }