mpu certi final

This commit is contained in:
kizzy 2025-11-21 14:34:06 +07:00
parent a8624195b0
commit ced683e302
34 changed files with 422 additions and 45 deletions

File diff suppressed because one or more lines are too long

View File

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

View File

@ -11,11 +11,11 @@ android {
compileSdk 34 compileSdk 34
defaultConfig { defaultConfig {
applicationId "com.utsmm.kbz" applicationId "com.utsmm.kbz" //mpu
minSdk 24 minSdk 24
targetSdk 33 targetSdk 33
versionCode 7 versionCode 8
versionName "1.07" versionName "1.08"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

Binary file not shown.

View File

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

View File

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

View File

@ -382,6 +382,32 @@ public class MainActivity extends AppCompatActivity implements
SystemParamsOperation.getInstance().setSetupEcr(false); SystemParamsOperation.getInstance().setSetupEcr(false);
SystemParamsOperation.getInstance().setDownloadedParams(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 @Override

View File

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

View File

@ -7,6 +7,7 @@ import android.app.Service;
import android.content.Intent; import android.content.Intent;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.text.TextUtils;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
@ -23,8 +24,7 @@ import javax.inject.Inject;
import dagger.hilt.android.AndroidEntryPoint; import dagger.hilt.android.AndroidEntryPoint;
import com.utsmyanmar.paylibs.utils.LogUtil; import com.utsmyanmar.paylibs.utils.LogUtil;
// Temporarily disabled Hilt @AndroidEntryPoint
// @AndroidEntryPoint
public class SmileSettleService extends Service { public class SmileSettleService extends Service {
private static final String TAG = SmileSettleService.class.getSimpleName(); private static final String TAG = SmileSettleService.class.getSimpleName();
@ -157,7 +157,131 @@ public class SmileSettleService extends Service {
// }catch (Exception e){ // }catch (Exception e){
// e.printStackTrace(); // 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; return START_NOT_STICKY;
} }

View File

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

View File

@ -112,8 +112,8 @@ public class ProcessingCardFragment extends DataBindingFragment {
private void mockMPUCard() { private void mockMPUCard() {
LogUtil.d(TAG,"initialize mock card data..."); LogUtil.d(TAG,"initialize mock card data...");
routeId = R.id.action_processingCardFragment_to_pinPadFragment; routeId = R.id.action_processingCardFragment_to_pinPadFragment;
transProcessViewModel.transType.postValue(sharedViewModel.transactionsType.getValue()); transProcessViewModel.transType.setValue(sharedViewModel.transactionsType.getValue());
pinPadViewModel.transType.postValue(sharedViewModel.transactionsType.getValue()); pinPadViewModel.transType.setValue(sharedViewModel.transactionsType.getValue());
CardDataX cardDataX = MockData.getInstance().generateMPUCard(); 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.config.Constants;
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel; 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; import com.utsmyanmar.paylibs.utils.LogUtil;
public class SignatureFragment extends DataBindingFragment { public class SignatureFragment extends DataBindingFragment {
@ -138,6 +140,7 @@ public class SignatureFragment extends DataBindingFragment {
// Handle digital signature // Handle digital signature
if (isSigned) { if (isSigned) {
sharedViewModel.signBitmap = mSignaturePad.getSignatureBitmap(); sharedViewModel.signBitmap = mSignaturePad.getSignatureBitmap();
PrintXReceipt.getInstance().setSignatureBitmap(mSignaturePad.getSignatureBitmap());
LogUtil.d(TAG, "Digital signature confirmed and stored"); LogUtil.d(TAG, "Digital signature confirmed and stored");
callNextScreen(); callNextScreen();
} else { } else {
@ -146,8 +149,8 @@ public class SignatureFragment extends DataBindingFragment {
} else { } else {
// Handle manual signature on paper // Handle manual signature on paper
sharedViewModel.signBitmap = null; // No digital signature sharedViewModel.signBitmap = null; // No digital signature
PrintXReceipt.getInstance().setSignatureBitmap(null);
LogUtil.d(TAG, "Manual signature on paper selected - no digital signature stored"); LogUtil.d(TAG, "Manual signature on paper selected - no digital signature stored");
showSingleInfoDialog("Please sign on the printed receipt manually and proceed.");
callNextScreen(); callNextScreen();
} }
} }

View File

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

View File

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

View File

@ -121,7 +121,7 @@ public class SettlementViewModel extends ViewModel {
ca_count.setValue(0); ca_count.setValue(0);
ca_amount.setValue(0L); 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(); .build();
// setUpSettlementData(); // setUpSettlementData();
@ -339,7 +339,7 @@ public class SettlementViewModel extends ViewModel {
HostName hostName = HostName.BPC; HostName hostName = HostName.FINEXUS;
String field60 = SystemParamsOperation.getInstance().getCurrentBatchNum(); String field60 = SystemParamsOperation.getInstance().getCurrentBatchNum();
@ -361,14 +361,26 @@ public class SettlementViewModel extends ViewModel {
payDetail = tradeData.getPayDetail(); 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.setTransType(TransactionsType.SETTLEMENT.name);
payDetail.setTransactionType(TransactionType.SETTLEMENT); payDetail.setTransactionType(TransactionType.SETTLEMENT);
if (!flag) { if (!flag) {
payDetail.setProcessCode(TransactionsType.SETTLEMENT.processCode); payDetail.setProcessCode(TransactionsType.SETTLEMENT.processCode);
} else { } else {
bitmap = BitmapConfig.BPC_SETTLEMENT_TRAILER; if(hostName == HostName.BPC) {
payDetail.setProcessCode("910000"); bitmap = BitmapConfig.BPC_SETTLEMENT_TRAILER;
payDetail.setProcessCode("910000");
} else {
bitmap = BitmapConfig.MPU_NEW_SETTLE;
payDetail.setProcessCode("960000");
}
} }
// CA:CA - CD - FT // CA:CA - CD - FT
@ -403,7 +415,8 @@ public class SettlementViewModel extends ViewModel {
payDetail.setSettleData(settlementData); payDetail.setSettleData(settlementData);
payDetail.setAmount(totalAmount); payDetail.setAmount(totalAmount);
} else { } 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(); CurrencyType currencyType = SystemParamsOperation.getInstance().getCurrencyType();
sharedViewModel.set_currencyText(currencyType.name); sharedViewModel.set_currencyText(currencyType.name);
// tmsProcessViewModel.loadEmvParameters(); // tmsProcessViewModel.loadEmvParameters();
// scheduleAutoSettlement();
navigateToMain(); 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() mockCardData = new MockCardData.Builder()
.cardNo("9503712156912514") .cardNo("9503712156912514")
.expDate("1229") .expDate("2912")
.cardScheme("MPU") .cardScheme("MPU")
.cardHolderName("Htin Kyaw Win") .cardHolderName("Htin Kyaw Win")
.iccData("9503712156912514=29121010000000000000") .iccData("9503712156912514=29121010000000000000")

View File

@ -235,6 +235,86 @@
</androidx.cardview.widget.CardView> </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 --> <!-- Demo Mode Card -->
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/demoCard" android:id="@+id/demoCard"

View File

@ -43,7 +43,7 @@ public class BatchUploadProcess {
} }
private 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(); .build();
} }
@ -77,9 +77,11 @@ public class BatchUploadProcess {
return new StartBatchUpload() { return new StartBatchUpload() {
@Override @Override
public void startBatchUpload(BatchListener batchListener) { public void startBatchUpload(BatchListener batchListener) {
HostName hostName = HostName.BPC; HostName hostName = HostName.FINEXUS;
LogUtil.d(TAG, "Starting Batch Upload"); 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() { ISOSocket.getInstance().enqueue(sendBytes, sendBytes.length,false, new ISOCallback() {
@Override @Override
public void onReceive(byte[] bytes, int length) { public void onReceive(byte[] bytes, int length) {

View File

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

View File

@ -257,9 +257,12 @@ public class EncodePackage {
* for Smart Vista >>>>>>> Aug 29 , 2023 <<<<<<<< * for Smart Vista >>>>>>> Aug 29 , 2023 <<<<<<<<
* */ * */
byte[] varValue = (String.format("%0" + msgField.getLengthType() + "d", msgField.getDataLength())).getBytes(); if(hostName == HostName.BPC) {
System.arraycopy(varValue, 0, body, index, varValue.length); byte[] varValue = (String.format("%0" + msgField.getLengthType() + "d", msgField.getDataLength())).getBytes();
index += varValue.length; System.arraycopy(varValue, 0, body, index, varValue.length);
index += varValue.length;
}
} }
} }
LogUtil.d(Constant.TAG, "Pack Field[" + msgField.getFieldPos() + "]: " + msgField.getDataStr()); 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()); Utils.BCDEncode(fieldHead, dat, msgField.getAlignType(), msgField.getFillChar());
System.arraycopy(dat, 0, body, index, bcdLen); System.arraycopy(dat, 0, body, index, bcdLen);
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()); System.arraycopy(fieldBody.getBytes(StandardCharsets.ISO_8859_1), 0, body, index, fieldBody.length());
LogUtil.d(Constant.TAG,"fieldBody : "+fieldBody); LogUtil.d(Constant.TAG,"fieldBody : "+fieldBody);
index += fieldBody.length(); 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 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 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() { public static byte[] boldOn() {
byte[] result = new byte[3]; byte[] result = new byte[3];
result[0] = 0x1B; result[0] = 0x1B;
@ -718,8 +724,14 @@ public abstract class BaseXPrint {
cvmText = "NO SIGNATURE REQUIRED"; cvmText = "NO SIGNATURE REQUIRED";
break; break;
} }
addSignatureBitmap();
printer.appendPrnStr(cvmText, fontBold, AlignEnum.CENTER); printer.appendPrnStr(cvmText, fontBold, AlignEnum.CENTER);
// if (payDetail.getIsFreeSign()) { // if (payDetail.getIsFreeSign()) {
// printer.printText("NO SIGNATURE REQUIRED", innerResultCallback); // printer.printText("NO SIGNATURE REQUIRED", innerResultCallback);
// } else { // } 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) { protected String beautifyIsoPacket(String isoMsg) {
StringBuilder sb = new StringBuilder(isoMsg); StringBuilder sb = new StringBuilder(isoMsg);
StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder();

View File

@ -1,5 +1,7 @@
package com.utsmyanmar.paylibs.print.printx; package com.utsmyanmar.paylibs.print.printx;
import android.graphics.Bitmap;
import com.utsmyanmar.paylibs.model.PayDetail; import com.utsmyanmar.paylibs.model.PayDetail;
import com.utsmyanmar.paylibs.utils.enums.HostType; 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 printDetailReport(PayDetail payDetail, List<PayDetail> lists, HostType hostType,PrintXStatus printXStatus);
void printKeyStatus(); void printKeyStatus();
void setSignatureBitmap(Bitmap signatureBitmap);
} }

View File

@ -1,6 +1,7 @@
package com.utsmyanmar.paylibs.print.printx; package com.utsmyanmar.paylibs.print.printx;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.os.RemoteException; 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); bitmap = BitmapFactory.decodeResource(resources, R.drawable.print_logo_mpu, opts);
} }
@Override
public void setSignatureBitmap(Bitmap signatureBitmap) {
super.setSignatureBitmap(signatureBitmap);
}
@Override @Override
public void printSimple() { public void printSimple() {
try { try {

View File

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

View File

@ -128,7 +128,8 @@ public class ReversalAction {
public void startReversal(ReversalListener reversalListener) { public void startReversal(ReversalListener reversalListener) {
HostName hostName = HostName.BPC; HostName hostName = HostName.BPC;
LogUtil.d(TAG, "Starting Reversal...."); 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() { ISOSocket.getInstance().enqueue(sendBytes, sendBytes.length,true, new ISOCallback() {
@Override @Override
public void onReceive(byte[] bytes, int length) { public void onReceive(byte[] bytes, int length) {

View File

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

View File

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

View File

@ -126,7 +126,7 @@ public class HostUtils {
if (hostName == HostName.BPC) { if (hostName == HostName.BPC) {
msgType = MessageType.REVERSAL; msgType = MessageType.REVERSAL;
} else { } else {
msgType = MessageType.FINANCIAL; msgType = MessageType.REVERSAL;
} }
break; break;
case SETTLEMENT: 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_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"; public static final String MPU_NEW_SETTLE ="2020010000C00012";
// 7038058028C00000 7038058020C00000 // 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 //703C058008C00000
// public static final String MPU_NEW_BATCH_UPLOAD ="703C058008C00000";
public static final String MPU_NEW_BATCH_UPLOAD ="703C058008C00000"; public static final String MPU_NEW_BATCH_UPLOAD ="703C058008C00000";
// 703C058008C08000 7038058028C00000 // 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 // 7038058028C08000
public static final String MPU_NEW_PRE_AUTH_CANCEL="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 // 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*/ /* 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"; 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, '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_ASC, SDK_8583_ALIGN_L, ' '},
// /* FLD 62 */ {2, SDK_8583_LEN_BCD, 255, SDK_8583_DATA_BCD, SDK_8583_ALIGN_R, '0'}, // /* 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 */ {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 */ {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 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}, /* 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) { 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 { } else {
field.setDataStr("00"); field.setDataStr("00");
} }
@ -539,8 +543,10 @@ public class FieldUtils {
break; break;
case 63: //Private Use case 63: //Private Use
String settleData = payDetail.getSettleData(); String settleData = payDetail.getSettleData();
field.setDataStr(settleData); String finalValue = String.format(Locale.getDefault(),"%04d", settleData.length())+settleData;
field.setDataStr(finalValue);
break; break;
case 64: //Message Authentication Code (MAC) Required when the 39 field in the response message is "00" case 64: //Message Authentication Code (MAC) Required when the 39 field in the response message is "00"
field.setDataStr("0000000000000000"); field.setDataStr("0000000000000000");