Merge remote-tracking branch 'origin/mpu_latest' into latest

This commit is contained in:
MooN 2025-11-23 15:56:10 +06:30
commit 3d2b316e99
34 changed files with 420 additions and 43 deletions

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,12 @@
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
<SelectionState runConfigName="testVoidPacket()">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
<SelectionState runConfigName="ExampleInstrumentedTest">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
</selectionStates>
</component>
</project>

View File

@ -11,7 +11,7 @@ android {
compileSdk 34
defaultConfig {
applicationId "com.utsmm.kbz"
applicationId "com.utsmm.kbz" //mpu
minSdk 24
targetSdk 33
versionCode 8

Binary file not shown.

View File

@ -4,15 +4,15 @@
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.utsmm.kbz",
"applicationId": "com.utsmm.kbz.mpu",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 7,
"versionName": "1.07",
"versionCode": 8,
"versionName": "1.08",
"outputFile": "app-release.apk"
}
],

View File

@ -52,7 +52,9 @@
<!-- android:screenOrientation="portrait"-->
<!-- android:name=".config.UTSManageSpaceActivity"/>-->
<activity android:name="com.utsmm.kbz.MainActivity"
android:exported="true">
android:exported="true"
android:showWhenLocked="true"
android:turnScreenOn="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME"/>

View File

@ -382,6 +382,32 @@ public class MainActivity extends AppCompatActivity implements
SystemParamsOperation.getInstance().setSetupEcr(false);
SystemParamsOperation.getInstance().setDownloadedParams(false);
handleAutoSettlementIntent(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
handleAutoSettlementIntent(intent);
}
private void handleAutoSettlementIntent(Intent intent) {
if (intent == null) return;
boolean auto = intent.getBooleanExtra("AUTO_SETTLEMENT", false);
if (!auto) return;
com.utsmyanmar.paylibs.model.PayDetail payDetail = (com.utsmyanmar.paylibs.model.PayDetail) intent.getSerializableExtra("EXTRA_PAY_DETAIL");
if (payDetail != null) {
sharedViewModel.payDetail.setValue(payDetail);
sharedViewModel.transactionsType.setValue(com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType.SETTLEMENT);
try {
navController.navigate(R.id.transactionResultFragment);
} catch (Exception e) {
LogUtil.e(TAG, "Navigation error: " + e.getMessage());
}
}
}
@Override

View File

@ -36,6 +36,7 @@ import com.utsmyanmar.ecr.data.model.Transactions;
import com.utsmyanmar.paylibs.model.PayDetail;
import com.utsmyanmar.paylibs.print.PrintHelper;
import com.utsmyanmar.paylibs.print.printx.PrintXReceipt;
import com.utsmyanmar.paylibs.utils.POSUtil;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
import com.utsmyanmar.paylibs.utils.enums.CurrencyType;
@ -134,6 +135,8 @@ public class MainFragment extends DataBindingFragment {
sharedViewModel.setAmountExist(false);
sharedViewModel.setCardDataExist(false);
sharedViewModel.setTransMenu(null);
PrintXReceipt.getInstance().setSignatureBitmap(null);
updateButtonStatus();
delayFunctionCall(this::checkTerminalStatus);
@ -844,6 +847,7 @@ public class MainFragment extends DataBindingFragment {
} else {
processBatch();
sharedViewModel.transactionsType.setValue(TransactionsType.SALE);
sharedViewModel.setTransMenu(TransMenu.SALE);
sharedViewModel.processCode.postValue(ProcessCode.SALE_PURCHASE + ProcessCode.SMART + ProcessCode.TO_ACCOUNT);
navigateToAmount();
}

View File

@ -7,6 +7,7 @@ import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
@ -23,8 +24,7 @@ import javax.inject.Inject;
import dagger.hilt.android.AndroidEntryPoint;
import com.utsmyanmar.paylibs.utils.LogUtil;
// Temporarily disabled Hilt
// @AndroidEntryPoint
@AndroidEntryPoint
public class SmileSettleService extends Service {
private static final String TAG = SmileSettleService.class.getSimpleName();
@ -157,7 +157,131 @@ public class SmileSettleService extends Service {
// }catch (Exception e){
// e.printStackTrace();
// }
if(com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation.getInstance().getSettlementStatus()) {
final com.utsmyanmar.paylibs.isobuilder.builderx.ISOMsgX isoMsgX = new com.utsmyanmar.paylibs.isobuilder.builderx.ISOMsgX.ISOMsgXBuilder(
com.utsmyanmar.paylibs.isobuilder.builderx.ISOVersion.VERSION_1993,
com.utsmyanmar.paylibs.isobuilder.ISOMode.BOTH_HEADER_TPDU,
com.utsmyanmar.paylibs.utils.enums.HostName.BPC
).build();
repository.getSettlementPOS().observeForever(list -> {
int saleCount = 0;
long saleAmount = 0L;
int preCount = 0;
long preAmount = 0L;
int refundCount = 0;
long refundAmount = 0L;
int caCount = 0;
long caAmount = 0L;
if(list != null && !list.isEmpty()) {
for (com.utsmyanmar.paylibs.model.PayDetail pay : list) {
if (pay.getTransactionType() == com.utsmyanmar.paylibs.utils.iso_utils.TransactionType.SALE && !pay.isCanceled) {
saleCount++;
saleAmount += pay.getAmount();
} else if (pay.getTransactionType() == com.utsmyanmar.paylibs.utils.iso_utils.TransactionType.PRE_SALE_COMPLETE && !pay.isCanceled) {
preCount++;
preAmount += pay.getAmount();
} else if (pay.getTransactionType() == com.utsmyanmar.paylibs.utils.iso_utils.TransactionType.REFUND) {
refundCount++;
refundAmount += pay.getAmount();
} else if (pay.getTransactionType() == com.utsmyanmar.paylibs.utils.iso_utils.TransactionType.CASH_ADVANCE) {
caCount++;
caAmount += pay.getAmount();
}
}
}
com.utsmyanmar.paylibs.model.TradeData tradeData = com.utsmyanmar.paylibs.utils.params.Params.newTrade(true);
com.utsmyanmar.paylibs.model.PayDetail payDetail = tradeData.getPayDetail();
String bitmap = com.utsmyanmar.paylibs.utils.iso_utils.BitmapConfig.BPC_SETTLEMENT;
payDetail.setTransType(com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType.SETTLEMENT.name);
payDetail.setTransactionType(com.utsmyanmar.paylibs.utils.iso_utils.TransactionType.SETTLEMENT);
payDetail.setProcessCode(com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType.SETTLEMENT.processCode);
payDetail.setBatchNo(com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation.getInstance().getCurrentBatchNum());
com.utsmyanmar.paylibs.model.SettleData settleData = new com.utsmyanmar.paylibs.model.SettleData(
saleCount,
saleAmount,
preCount,
preAmount,
refundCount,
refundAmount,
caCount,
caAmount
);
payDetail.setSettleDataObj(settleData);
long totalAmount = saleAmount + preAmount + refundAmount + caAmount;
String settlementData;
if (refundAmount != 0L) {
long creditTotal = saleAmount + preAmount + caAmount;
long subTotal = creditTotal - refundAmount;
if (subTotal < 0L) {
settlementData = "D" + String.format(java.util.Locale.getDefault(), "%012d", Math.abs(subTotal));
} else {
settlementData = "C" + String.format(java.util.Locale.getDefault(), "%012d", subTotal);
}
} else {
settlementData = "C" + String.format(java.util.Locale.getDefault(), "%012d", totalAmount);
}
payDetail.setSettleData(settlementData);
payDetail.setAmount(totalAmount);
tradeData.setPayDetail(payDetail);
tradeData.setField60(com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation.getInstance().getCurrentBatchNum());
byte[] sendBytes = isoMsgX.buildISOPackets(tradeData, bitmap, com.utsmyanmar.paylibs.utils.MessageType.SETTLEMENT);
com.utsmyanmar.paylibs.network.ISOSocket.getInstance().enqueue(sendBytes, sendBytes.length, false, new com.utsmyanmar.paylibs.network.ISOCallback() {
@Override
public void onReceive(byte[] bytes, int length) {
java.util.Map<String, com.utsmyanmar.paylibs.model.MsgField> responseMap = isoMsgX.parseISOPackets(bytes, length);
if (responseMap != null) {
String resultStr = "";
try {
resultStr = responseMap.get("F039").getDataStr();
} catch (NullPointerException e) {
e.printStackTrace();
payDetail.setIsNeedReversal(true);
return;
}
payDetail.setTradeAnswerCode(resultStr);
if (TextUtils.equals(resultStr, com.utsmyanmar.paylibs.Constant.ANSWER_CODE_ACCEPT) || TextUtils.equals(resultStr, com.utsmyanmar.paylibs.Constant.ANSWER_CODE_APPROVED)) {
payDetail.setIsNeedReversal(false);
} else if (TextUtils.equals(resultStr, "95") || TextUtils.equals(resultStr, "095")) {
payDetail.setIsNeedReversal(true);
}
}
}
@Override
public void onError(String msg) {
com.utsmyanmar.paylibs.network.ISOSocket.getInstance().switchIp();
com.utsmyanmar.paylibs.network.ISOSocket.getInstance().enqueue(sendBytes, sendBytes.length, false, this);
}
@Override
public void onComplete() {
if(list != null && !list.isEmpty()) {
for (com.utsmyanmar.paylibs.model.PayDetail p : list) {
repository.deletePayDetail(p);
}
}
repository.insertPayDetail(payDetail);
Intent uiIntent = new Intent(getApplicationContext(), com.utsmm.kbz.MainActivity.class);
uiIntent.putExtra("AUTO_SETTLEMENT", true);
uiIntent.putExtra("EXTRA_TRANSACTION_TYPE", com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType.SETTLEMENT.value);
uiIntent.putExtra("EXTRA_PAY_DETAIL", payDetail);
uiIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(uiIntent);
}
});
});
}
return START_NOT_STICKY;
}

View File

@ -220,6 +220,7 @@ public class InputRRNFragment extends DataBindingFragment {
newPay = transProcessViewModel.getPayDetail();
}
newPay.setReferNo(rrnNo);
if(sharedViewModel.getTransMenu().getValue() == TransMenu.PRE_AUTH_FULL_VOID) {
newPay.setAmount(payDetail.getAmount());
@ -311,7 +312,9 @@ public class InputRRNFragment extends DataBindingFragment {
}
newPay.setReferNo(rrnNo);
newPay.setApprovalCode(payDetail.getApprovalCode());
newPay.setTradeTime(payDetail.getTradeTime());
newPay.setTradeDate(payDetail.getTradeDate());
if(newPay.getAmount() > payDetail.getAmount()) {
newPay.setTradeAnswerCode("C1"); // ---> refer to BaseErrorCode class// ,
newPay.setTransType(sharedViewModel.transactionsType.getValue().name);

View File

@ -112,8 +112,8 @@ public class ProcessingCardFragment extends DataBindingFragment {
private void mockMPUCard() {
LogUtil.d(TAG,"initialize mock card data...");
routeId = R.id.action_processingCardFragment_to_pinPadFragment;
transProcessViewModel.transType.postValue(sharedViewModel.transactionsType.getValue());
pinPadViewModel.transType.postValue(sharedViewModel.transactionsType.getValue());
transProcessViewModel.transType.setValue(sharedViewModel.transactionsType.getValue());
pinPadViewModel.transType.setValue(sharedViewModel.transactionsType.getValue());
CardDataX cardDataX = MockData.getInstance().generateMPUCard();

View File

@ -16,6 +16,8 @@ import com.utsmm.kbz.R;
import com.utsmm.kbz.config.Constants;
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
import com.utsmyanmar.paylibs.print.printx.PrintX;
import com.utsmyanmar.paylibs.print.printx.PrintXReceipt;
import com.utsmyanmar.paylibs.utils.LogUtil;
public class SignatureFragment extends DataBindingFragment {
@ -138,6 +140,7 @@ public class SignatureFragment extends DataBindingFragment {
// Handle digital signature
if (isSigned) {
sharedViewModel.signBitmap = mSignaturePad.getSignatureBitmap();
PrintXReceipt.getInstance().setSignatureBitmap(mSignaturePad.getSignatureBitmap());
LogUtil.d(TAG, "Digital signature confirmed and stored");
callNextScreen();
} else {
@ -146,8 +149,8 @@ public class SignatureFragment extends DataBindingFragment {
} else {
// Handle manual signature on paper
sharedViewModel.signBitmap = null; // No digital signature
PrintXReceipt.getInstance().setSignatureBitmap(null);
LogUtil.d(TAG, "Manual signature on paper selected - no digital signature stored");
showSingleInfoDialog("Please sign on the printed receipt manually and proceed.");
callNextScreen();
}
}

View File

@ -147,6 +147,8 @@ public class TransactionResultFragment extends DataBindingFragment implements Da
PayDetail payDetail = sharedViewModel.payDetail.getValue();
if (payDetail == null) {
navigateToMainScreen();
return;

View File

@ -316,7 +316,9 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
dismissLoadingDialog();
updateData();
if (!SystemParamsOperation.getInstance().getDemoStatus()) {
networkCutOver();
// networkCutOver(); // bpc
navigateToNext();
} else {
navigateToNext();
}

View File

@ -121,7 +121,7 @@ public class SettlementViewModel extends ViewModel {
ca_count.setValue(0);
ca_amount.setValue(0L);
isoMsgX = new ISOMsgX.ISOMsgXBuilder(ISOVersion.VERSION_1993, ISOMode.BOTH_HEADER_TPDU,HostName.BPC)
isoMsgX = new ISOMsgX.ISOMsgXBuilder(ISOVersion.VERSION_1987, ISOMode.ONLY_HEADER,HostName.FINEXUS)
.build();
// setUpSettlementData();
@ -339,7 +339,7 @@ public class SettlementViewModel extends ViewModel {
HostName hostName = HostName.BPC;
HostName hostName = HostName.FINEXUS;
String field60 = SystemParamsOperation.getInstance().getCurrentBatchNum();
@ -361,14 +361,26 @@ public class SettlementViewModel extends ViewModel {
payDetail = tradeData.getPayDetail();
bitmap = BitmapConfig.BPC_SETTLEMENT;
//
if(hostName == HostName.BPC) {
bitmap = BitmapConfig.BPC_SETTLEMENT;
} else {
bitmap = BitmapConfig.MPU_NEW_SETTLE;
}
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");
if(hostName == HostName.BPC) {
bitmap = BitmapConfig.BPC_SETTLEMENT_TRAILER;
payDetail.setProcessCode("910000");
} else {
bitmap = BitmapConfig.MPU_NEW_SETTLE;
payDetail.setProcessCode("960000");
}
}
// CA:CA - CD - FT
@ -403,7 +415,8 @@ public class SettlementViewModel extends ViewModel {
payDetail.setSettleData(settlementData);
payDetail.setAmount(totalAmount);
} else {
payDetail.setSettleData(totalSaleCount + totalSaleAmount + totalRefundCount + totalRefundAmount + totalDebitSaleCount + totalDebitSaleAmount + totalERefundCount + totalERefundAmount); //field 63
// payDetail.setSettleData(totalSaleCount + totalSaleAmount + totalRefundCount + totalRefundAmount + totalDebitSaleCount + totalDebitSaleAmount + totalERefundCount + totalERefundAmount); //field 63 BPC
payDetail.setSettleData(totalSaleCount + totalSaleAmount + totalRefundCount + totalRefundAmount + totalDebitSaleCount + totalDebitSaleAmount ); //field 63
}

View File

@ -213,6 +213,7 @@ public class TMSProcessFragment extends DataBindingFragment {
CurrencyType currencyType = SystemParamsOperation.getInstance().getCurrencyType();
sharedViewModel.set_currencyText(currencyType.name);
// tmsProcessViewModel.loadEmvParameters();
// scheduleAutoSettlement();
navigateToMain();
}
});
@ -224,4 +225,48 @@ public class TMSProcessFragment extends DataBindingFragment {
}
private void scheduleAutoSettlement() {
String timeStr = SystemParamsOperation.getInstance().getClearBatchTime();
if(timeStr == null || timeStr.trim().isEmpty()) {
return;
}
String[] parts = timeStr.trim().split(":");
if(parts.length != 2) {
return;
}
int hour;
int minute;
try {
hour = Integer.parseInt(parts[0]);
minute = Integer.parseInt(parts[1]);
} catch (Exception e) {
return;
}
android.app.AlarmManager alarmManager = (android.app.AlarmManager) requireContext().getSystemService(android.content.Context.ALARM_SERVICE);
if(alarmManager == null) return;
java.util.Calendar calendar = java.util.Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(java.util.Calendar.HOUR_OF_DAY, hour);
calendar.set(java.util.Calendar.MINUTE, minute);
calendar.set(java.util.Calendar.SECOND, 0);
long triggerAtMillis = calendar.getTimeInMillis();
if(System.currentTimeMillis() > triggerAtMillis) {
calendar.add(java.util.Calendar.DAY_OF_YEAR, 1);
triggerAtMillis = calendar.getTimeInMillis();
}
android.content.Intent intent = new android.content.Intent(requireContext(), com.utsmm.kbz.service.SmileAlarmReceiver.class);
android.app.PendingIntent pendingIntent = android.app.PendingIntent.getBroadcast(
requireContext(),
1001,
intent,
android.app.PendingIntent.FLAG_UPDATE_CURRENT
);
alarmManager.setRepeating(android.app.AlarmManager.RTC_WAKEUP, triggerAtMillis, android.app.AlarmManager.INTERVAL_DAY, pendingIntent);
}
}

View File

@ -63,7 +63,7 @@ public class MockData {
mockCardData = new MockCardData.Builder()
.cardNo("9503712156912514")
.expDate("1229")
.expDate("2912")
.cardScheme("MPU")
.cardHolderName("Htin Kyaw Win")
.iccData("9503712156912514=29121010000000000000")

View File

@ -235,6 +235,86 @@
</androidx.cardview.widget.CardView>
<!-- &lt;!&ndash; Demo Mode Card &ndash;&gt;-->
<!-- <androidx.cardview.widget.CardView-->
<!-- android:id="@+id/demoCard"-->
<!-- 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.onDemoClick()}"-->
<!-- 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_swap"-->
<!-- 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="Reversal On/Off"-->
<!-- android:textColor="@color/colorTextTitle"-->
<!-- android:textSize="18sp"-->
<!-- android:textStyle="bold"-->
<!-- tools:fontFamily="sans-serif-medium" />-->
<!-- <TextView-->
<!-- android:id="@+id/reversalSwitch"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginTop="2dp"-->
<!-- android:fontFamily="@font/rubik_regular"-->
<!-- android:text="Demo mode active - Test transactions"-->
<!-- android:textColor="@color/colorTextContent"-->
<!-- android:textSize="14sp"-->
<!-- tools:fontFamily="sans-serif" />-->
<!-- </LinearLayout>-->
<!-- <Switch-->
<!-- android:id="@+id/demoSwitch"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginStart="8dp"-->
<!-- android:clickable="false"-->
<!-- android:focusable="false" />-->
<!-- </LinearLayout>-->
<!-- </androidx.cardview.widget.CardView>-->
<!-- Demo Mode Card -->
<androidx.cardview.widget.CardView
android:id="@+id/demoCard"

View File

@ -43,7 +43,7 @@ public class BatchUploadProcess {
}
private BatchUploadProcess() {
isoMsgX = new ISOMsgX.ISOMsgXBuilder(ISOVersion.VERSION_1993, ISOMode.BOTH_HEADER_TPDU,HostName.BPC)
isoMsgX = new ISOMsgX.ISOMsgXBuilder(ISOVersion.VERSION_1987, ISOMode.ONLY_HEADER,HostName.FINEXUS)
.build();
}
@ -77,9 +77,11 @@ public class BatchUploadProcess {
return new StartBatchUpload() {
@Override
public void startBatchUpload(BatchListener batchListener) {
HostName hostName = HostName.BPC;
HostName hostName = HostName.FINEXUS;
LogUtil.d(TAG, "Starting Batch Upload");
byte[] sendBytes = isoMsgX.buildISOPackets(tradeData, BitmapConfig.BPC_BATCH_UPLOAD, MessageType.BATCH_UPLOAD);
byte[] sendBytes = isoMsgX.buildISOPackets(tradeData, BitmapConfig.MPU_NEW_BATCH_UPLOAD, MessageType.BATCH_UPLOAD);
// byte[] sendBytes = isoMsgX.buildISOPackets(tradeData, BitmapConfig.BPC_BATCH_UPLOAD, MessageType.BATCH_UPLOAD);
ISOSocket.getInstance().enqueue(sendBytes, sendBytes.length,false, new ISOCallback() {
@Override
public void onReceive(byte[] bytes, int length) {

View File

@ -363,7 +363,7 @@ public class DecodePackage {
// varLen = outField.getLengthType();
byte[] varValue = new byte[varLen];
if(i==62){
if(i==62 || i==63){
tmpLen++;
}
@ -414,6 +414,7 @@ public class DecodePackage {
//
} catch (IndexOutOfBoundsException e){
e.printStackTrace();
System.arraycopy(body, tmpLen, nextData, 0, datLen);
}
// Data length

View File

@ -257,9 +257,12 @@ public class EncodePackage {
* for Smart Vista >>>>>>> Aug 29 , 2023 <<<<<<<<
* */
byte[] varValue = (String.format("%0" + msgField.getLengthType() + "d", msgField.getDataLength())).getBytes();
System.arraycopy(varValue, 0, body, index, varValue.length);
index += varValue.length;
if(hostName == HostName.BPC) {
byte[] varValue = (String.format("%0" + msgField.getLengthType() + "d", msgField.getDataLength())).getBytes();
System.arraycopy(varValue, 0, body, index, varValue.length);
index += varValue.length;
}
}
}
LogUtil.d(Constant.TAG, "Pack Field[" + msgField.getFieldPos() + "]: " + msgField.getDataStr());
@ -282,7 +285,7 @@ public class EncodePackage {
Utils.BCDEncode(fieldHead, dat, msgField.getAlignType(), msgField.getFillChar());
System.arraycopy(dat, 0, body, index, bcdLen);
index += bcdLen;
String fieldBody=msgField.getDataStr().substring(4,msgField.getDataLength());
String fieldBody = msgField.getDataStr().substring(4,msgField.getDataLength());
System.arraycopy(fieldBody.getBytes(StandardCharsets.ISO_8859_1), 0, body, index, fieldBody.length());
LogUtil.d(Constant.TAG,"fieldBody : "+fieldBody);
index += fieldBody.length();

View File

@ -80,6 +80,12 @@ public abstract class BaseXPrint {
protected FontEntity fontBold = new FontEntity(DotMatrixFontEnum.CH_SONG_24X24, DotMatrixFontEnum.ASC_SONG_BOLD_16X24);
protected FontEntity fontBig = new FontEntity(DotMatrixFontEnum.CH_SONG_24X24, DotMatrixFontEnum.ASC_SONG_12X24, false, true);
protected Bitmap signatureBitmap;
public void setSignatureBitmap(Bitmap signatureBitmap) {
this.signatureBitmap = signatureBitmap;
}
public static byte[] boldOn() {
byte[] result = new byte[3];
result[0] = 0x1B;
@ -718,8 +724,14 @@ public abstract class BaseXPrint {
cvmText = "NO SIGNATURE REQUIRED";
break;
}
addSignatureBitmap();
printer.appendPrnStr(cvmText, fontBold, AlignEnum.CENTER);
// if (payDetail.getIsFreeSign()) {
// printer.printText("NO SIGNATURE REQUIRED", innerResultCallback);
// } else {
@ -745,6 +757,12 @@ public abstract class BaseXPrint {
}
private void addSignatureBitmap() {
if (signatureBitmap != null) {
printer.appendImage(signatureBitmap, AlignEnum.CENTER);
}
}
protected String beautifyIsoPacket(String isoMsg) {
StringBuilder sb = new StringBuilder(isoMsg);
StringBuilder msg = new StringBuilder();

View File

@ -1,5 +1,7 @@
package com.utsmyanmar.paylibs.print.printx;
import android.graphics.Bitmap;
import com.utsmyanmar.paylibs.model.PayDetail;
import com.utsmyanmar.paylibs.utils.enums.HostType;
@ -20,4 +22,6 @@ public interface PrintX {
void printDetailReport(PayDetail payDetail, List<PayDetail> lists, HostType hostType,PrintXStatus printXStatus);
void printKeyStatus();
void setSignatureBitmap(Bitmap signatureBitmap);
}

View File

@ -1,6 +1,7 @@
package com.utsmyanmar.paylibs.print.printx;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.RemoteException;
@ -43,6 +44,13 @@ public class PrintXImpl extends BaseXPrint implements PrintX {
bitmap = BitmapFactory.decodeResource(resources, R.drawable.print_logo_mpu, opts);
}
@Override
public void setSignatureBitmap(Bitmap signatureBitmap) {
super.setSignatureBitmap(signatureBitmap);
}
@Override
public void printSimple() {
try {

View File

@ -1,5 +1,7 @@
package com.utsmyanmar.paylibs.print.printx;
import android.graphics.Bitmap;
import com.utsmyanmar.paylibs.model.PayDetail;
import com.utsmyanmar.paylibs.utils.enums.HostType;
@ -19,6 +21,12 @@ public class PrintXReceipt {
public void printSimple() {
printX.printSimple();
}
public void setSignatureBitmap(Bitmap signatureBitmap) {
printX.setSignatureBitmap(signatureBitmap);
}
public void printSmileReceipt(PayDetail payDetail,boolean isMerchantCopy,PrintXStatus printXStatus) {

View File

@ -128,7 +128,8 @@ public class ReversalAction {
public void startReversal(ReversalListener reversalListener) {
HostName hostName = HostName.BPC;
LogUtil.d(TAG, "Starting Reversal....");
byte[] sendBytes = isoMsgX.buildISOPackets(tradeData, BitmapConfig.BPC_AUTOMATIC_REVERSAL, 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

@ -177,8 +177,11 @@ public class TransactionsOperation {
if (responseMap.get("F038") != null) {
transPayDetail.setApprovalCode(Objects.requireNonNull(responseMap.get("F038")).getDataStr());
} else {
transPayDetail.setIsNeedReversal(true);
return;
if(hostName == HostName.BPC) {
transPayDetail.setIsNeedReversal(true);
return;
}
}
if (responseMap.get("F046") != null) {
@ -376,7 +379,11 @@ public class TransactionsOperation {
newPay.setCardInfo(oldPay.getCardInfo());
newPay.setPINCipher(oldPay.getPINCipher());
newPay.setReferNo(oldPay.getReferNo());
newPay.setApprovalCode(oldPay.getApprovalCode());
newPay.setTempKSN(oldPay.getTempKSN());
newPay.setTradeTime(oldPay.getTradeTime()); // mpu
newPay.setTradeDate(oldPay.getTradeDate()); // mpu
} else if (transactionsType == TransactionsType.PRE_AUTH_COMPLETE_VOID) {
newPay.setVoucherNo(oldPay.getVoucherNo());
newPay.setCustomOrderNo(oldPay.getVoucherNo());

View File

@ -13,6 +13,7 @@ public enum TransMenu {
REVERSAL,
CASH_OUT,
SALE,
CLEAR_BATCH,
CLEAR_REVERSAL,

View File

@ -126,7 +126,7 @@ public class HostUtils {
if (hostName == HostName.BPC) {
msgType = MessageType.REVERSAL;
} else {
msgType = MessageType.FINANCIAL;
msgType = MessageType.REVERSAL;
}
break;
case SETTLEMENT:

View File

@ -170,31 +170,38 @@ public class BitmapConfig {
public static final String MPU_NEW_SALE ="7020058020C09000";
public static final String MPU_NEW_VOID ="7038058028C00010";
// public static final String MPU_NEW_VOID ="7038058028C00010";
public static final String MPU_NEW_VOID ="7038058008C00010"; // removed DE 35
public static final String MPU_NEW_SETTLE ="2020010000C00012";
// 7038058028C00000 7038058020C00000
public static final String MPU_NEW_REVERSAL ="7038058028C08004";
// public static final String MPU_NEW_REVERSAL ="7038058028C08004";
public static final String MPU_NEW_REVERSAL ="7038058028C08000";
//703C058008C00000
// public static final String MPU_NEW_BATCH_UPLOAD ="703C058008C00000";
public static final String MPU_NEW_BATCH_UPLOAD ="703C058008C00000";
// 703C058008C08000 7038058028C00000
public static final String MPU_NEW_REFUND ="703C058008C08000";
// public static final String MPU_NEW_REFUND ="703C058008C08000";
public static final String MPU_NEW_REFUND ="7024058008C08000";
public static final String MPU_NEW_PRE_AUTH ="7020058020C08000";
public static final String MPU_NEW_PRE_AUTH ="7020058020C09000";
// public static final String MPU_NEW_PRE_AUTH ="7020058020C08000"; // without DE52
// 7038058028C08000
public static final String MPU_NEW_PRE_AUTH_CANCEL="7038058028C08000";
// public static final String MPU_NEW_PRE_AUTH_CANCEL="7038058028C08000"; // without DE52
// 703805802CC08000 703805802CC08000
public static final String MPU_NEW_PRE_AUTH_COMPLETE_BITMAP="703805802CC08000";
public static final String MPU_NEW_PRE_AUTH_COMPLETE_BITMAP="703805802CC09000";
// public static final String MPU_NEW_PRE_AUTH_COMPLETE_BITMAP="703805802CC08000"; // without DE52
/* need to check bitmap*/
public static final String MPU_NEW_PRE_AUTH_COMPLETE_CANCEL="703805802CC08004";
public static final String MPU_NEW_PRE_AUTH_COMPLETE_CANCEL="7038058008C08000";
public static final String MPU_NEW_CASH_ADVANCE="7020058020C09000";

View File

@ -295,9 +295,9 @@ public class FieldConfig {
/* FLD 62 */ {2, 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, ' '},
// /* 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

@ -390,7 +390,11 @@ public class FieldUtils {
// }
if(payDetail.getTransactionType() == REFUND.value) {
field.setDataStr("61");
// field.setDataStr("61"); // BPC
field.setDataStr("00");// MPU
} if (payDetail.getTransactionType() == PRE_AUTH_SALE.value) { // || payDetail.getTransactionType() == PRE_AUTH_VOID.value BPC need 06
field.setDataStr("06");
} else {
field.setDataStr("00");
}
@ -539,8 +543,10 @@ public class FieldUtils {
break;
case 63: //Private Use
String settleData = payDetail.getSettleData();
field.setDataStr(settleData);
String finalValue = String.format(Locale.getDefault(),"%04d", settleData.length())+settleData;
field.setDataStr(finalValue);
break;
case 64: //Message Authentication Code (MAC) Required when the 39 field in the response message is "00"
field.setDataStr("0000000000000000");