fixed signature
This commit is contained in:
parent
62bae0df0c
commit
af9ef8367c
@ -90,3 +90,8 @@
|
|||||||
|
|
||||||
- 6. Reprint Last Settlement Report
|
- 6. Reprint Last Settlement Report
|
||||||
Same process with settlement
|
Same process with settlement
|
||||||
|
|
||||||
|
## [2.41]
|
||||||
|
- clear batch time fix
|
||||||
|
- removed mock qr button
|
||||||
|
- support Id fix for signature
|
||||||
@ -39,8 +39,8 @@ android {
|
|||||||
applicationId "com.utsmm.kbz.uat"
|
applicationId "com.utsmm.kbz.uat"
|
||||||
versionNameSuffix "-uat"
|
versionNameSuffix "-uat"
|
||||||
resValue "string", "app_name", "KBZ-UAT"
|
resValue "string", "app_name", "KBZ-UAT"
|
||||||
versionCode 44
|
versionCode 46
|
||||||
versionName "2.39"
|
versionName "2.41"
|
||||||
}
|
}
|
||||||
|
|
||||||
prod {
|
prod {
|
||||||
|
|||||||
@ -573,6 +573,7 @@ public class ProcessingFragment extends DataBindingFragment {
|
|||||||
request.setDE39(isSuccess ? "A" : "E");
|
request.setDE39(isSuccess ? "A" : "E");
|
||||||
request.setDE41(terminalId);
|
request.setDE41(terminalId);
|
||||||
request.setDE42(merchantId);
|
request.setDE42(merchantId);
|
||||||
|
request.setHostId(SystemParamsOperation.getInstance().getHostId());
|
||||||
request.setDE49(mapCurrency(payDetail.getCurrencyCode()));
|
request.setDE49(mapCurrency(payDetail.getCurrencyCode()));
|
||||||
request.setSerial(serial);
|
request.setSerial(serial);
|
||||||
request.setInvoiceNumber(payDetail.getInvoiceNo());
|
request.setInvoiceNumber(payDetail.getInvoiceNo());
|
||||||
|
|||||||
@ -169,7 +169,15 @@ 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
|
||||||
LogUtil.d(TAG, "Manual signature on paper selected - no digital signature stored");
|
PayDetail payDetail = sharedViewModel.payDetail.getValue();
|
||||||
|
EReceiptCardRequest request = EReceiptHelper.buildEReceiptCardReceipt(
|
||||||
|
requireContext(),
|
||||||
|
payDetail,
|
||||||
|
true,
|
||||||
|
BaseErrorCode.getCode(payDetail.getTradeAnswerCode()),
|
||||||
|
null);
|
||||||
|
sharedViewModel.pushReceipt(request);
|
||||||
|
LogUtil.d(TAG, "Manual signature on paper selected - receipt submitted without image");
|
||||||
callNextScreen();
|
callNextScreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -63,7 +63,7 @@ public class QRPayFragment extends DataBindingFragment {
|
|||||||
features.add(new QRPayItem("Refund", R.drawable.ic_refund, true));
|
features.add(new QRPayItem("Refund", R.drawable.ic_refund, true));
|
||||||
}
|
}
|
||||||
features.add(new QRPayItem("History", R.drawable.ic_history, true));
|
features.add(new QRPayItem("History", R.drawable.ic_history, true));
|
||||||
features.add(new QRPayItem("Mock QR", R.drawable.ic_qr_pay, true));
|
// features.add(new QRPayItem("Mock QR", R.drawable.ic_qr_pay, true));
|
||||||
|
|
||||||
// List<QRPayItem> features = List.of(
|
// List<QRPayItem> features = List.of(
|
||||||
// new QRPayItem("Sale", R.drawable.ic_qr_pay, true),
|
// new QRPayItem("Sale", R.drawable.ic_qr_pay, true),
|
||||||
|
|||||||
@ -56,6 +56,7 @@ public class EReceiptHelper {
|
|||||||
request.setDE39(isSuccess ? "A" : "E");
|
request.setDE39(isSuccess ? "A" : "E");
|
||||||
request.setDE41(terminalId);
|
request.setDE41(terminalId);
|
||||||
request.setDE42(merchantId);
|
request.setDE42(merchantId);
|
||||||
|
request.setHostId(SystemParamsOperation.getInstance().getHostId());
|
||||||
request.setDE49(mapCurrency(payDetail.getCurrencyCode()));
|
request.setDE49(mapCurrency(payDetail.getCurrencyCode()));
|
||||||
request.setSerial(serial);
|
request.setSerial(serial);
|
||||||
request.setInvoiceNumber(payDetail.getInvoiceNo());
|
request.setInvoiceNumber(payDetail.getInvoiceNo());
|
||||||
|
|||||||
@ -460,7 +460,7 @@ public class TMSSetupsImpl implements TMSSetups{
|
|||||||
SystemParamsOperation.getInstance().setRandomPinPad(parseBoolean(data));
|
SystemParamsOperation.getInstance().setRandomPinPad(parseBoolean(data));
|
||||||
} else if (TextUtils.equals(name,"clear_batch_time")) {
|
} else if (TextUtils.equals(name,"clear_batch_time")) {
|
||||||
|
|
||||||
SystemParamsOperation.getInstance().setClearBatchTime("22:00");
|
SystemParamsOperation.getInstance().setClearBatchTime(data);
|
||||||
} else if (TextUtils.equals(name,"alert_sound_enable")) {
|
} else if (TextUtils.equals(name,"alert_sound_enable")) {
|
||||||
|
|
||||||
SystemParamsOperation.getInstance().setAlertSound(parseBoolean(data));
|
SystemParamsOperation.getInstance().setAlertSound(parseBoolean(data));
|
||||||
|
|||||||
@ -12,6 +12,19 @@ import java.util.TreeMap;
|
|||||||
|
|
||||||
public class SignGenerateTest {
|
public class SignGenerateTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void tmsSignatureMatchesToolForFixedTimestamp() {
|
||||||
|
String secret = "y812J21lhha11OS";
|
||||||
|
String timestamp = "1786609802730";
|
||||||
|
|
||||||
|
String signature = EReceiptHelper.sha256("{}" + secret + timestamp);
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
"3f1bfe50289d706074560fa22f424f3665c9c3022362aa89a6ea9c37469a0774",
|
||||||
|
signature
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private static final String APP_KEY = "UTSMMuat@2025";
|
private static final String APP_KEY = "UTSMMuat@2025";
|
||||||
private static final String EXPECTED_SIGN = "D86AE09024C6581273C27B95A3BDBDBF3AC8EC20191365C8047ED6C42FC00DA5";
|
private static final String EXPECTED_SIGN = "D86AE09024C6581273C27B95A3BDBDBF3AC8EC20191365C8047ED6C42FC00DA5";
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -11,8 +11,8 @@
|
|||||||
"type": "SINGLE",
|
"type": "SINGLE",
|
||||||
"filters": [],
|
"filters": [],
|
||||||
"attributes": [],
|
"attributes": [],
|
||||||
"versionCode": 44,
|
"versionCode": 46,
|
||||||
"versionName": "2.39-uat",
|
"versionName": "2.41-uat",
|
||||||
"outputFile": "app-uat-release.apk"
|
"outputFile": "app-uat-release.apk"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@ -116,7 +116,7 @@ public class EmvParamOperation extends ParamOperation{
|
|||||||
processPayWave();
|
processPayWave();
|
||||||
processPayPass();
|
processPayPass();
|
||||||
processQuickPass();
|
processQuickPass();
|
||||||
// processJSpeedy();
|
processJSpeedy();
|
||||||
processMPUCtls();
|
processMPUCtls();
|
||||||
processChips();
|
processChips();
|
||||||
processRids();
|
processRids();
|
||||||
|
|||||||
@ -14,6 +14,7 @@ public class EReceiptCardRequest {
|
|||||||
private String DE7;
|
private String DE7;
|
||||||
private String DE4;
|
private String DE4;
|
||||||
private String appId;
|
private String appId;
|
||||||
|
private String hostId;
|
||||||
private String invoiceNumber;
|
private String invoiceNumber;
|
||||||
private String DE11;
|
private String DE11;
|
||||||
private String description;
|
private String description;
|
||||||
@ -73,6 +74,10 @@ public class EReceiptCardRequest {
|
|||||||
return appId;
|
return appId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getHostId(){
|
||||||
|
return hostId;
|
||||||
|
}
|
||||||
|
|
||||||
public String getDE55(){return DE55;}
|
public String getDE55(){return DE55;}
|
||||||
|
|
||||||
public String getInvoiceNumber(){
|
public String getInvoiceNumber(){
|
||||||
@ -133,6 +138,10 @@ public class EReceiptCardRequest {
|
|||||||
this.appId = appId;
|
this.appId = appId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setHostId(String hostId){
|
||||||
|
this.hostId = hostId;
|
||||||
|
}
|
||||||
|
|
||||||
public void setInvoiceNumber(String invoiceNumber){
|
public void setInvoiceNumber(String invoiceNumber){
|
||||||
this.invoiceNumber = invoiceNumber;
|
this.invoiceNumber = invoiceNumber;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,10 +41,7 @@ import com.utsmyanmar.baselib.network.model.KPayRefund;
|
|||||||
import com.utsmyanmar.baselib.repo.local.PayWaveRepository;
|
import com.utsmyanmar.baselib.repo.local.PayWaveRepository;
|
||||||
import com.utsmyanmar.baselib.util.EReceiptHelper;
|
import com.utsmyanmar.baselib.util.EReceiptHelper;
|
||||||
import com.utsmyanmar.paylibs.model.PayDetail;
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
import com.utsmyanmar.paylibs.utils.LogUtil;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
@ -128,7 +125,6 @@ public class Repository {
|
|||||||
}
|
}
|
||||||
public Observable<EReceiptResponse> sendReceipt(Object body){
|
public Observable<EReceiptResponse> sendReceipt(Object body){
|
||||||
String apiSecret = BuildConfig.ERECEIPT_SECRET;
|
String apiSecret = BuildConfig.ERECEIPT_SECRET;
|
||||||
// LogUtil.d("kmk", "receipt secret =>" + apiSecret);
|
|
||||||
String timestamp = String.valueOf(System.currentTimeMillis());
|
String timestamp = String.valueOf(System.currentTimeMillis());
|
||||||
String bodyString = new Gson().toJson(body);
|
String bodyString = new Gson().toJson(body);
|
||||||
String dataToHash = bodyString + apiSecret + timestamp;
|
String dataToHash = bodyString + apiSecret + timestamp;
|
||||||
@ -141,7 +137,6 @@ public class Repository {
|
|||||||
String timestamp = String.valueOf(System.currentTimeMillis());
|
String timestamp = String.valueOf(System.currentTimeMillis());
|
||||||
String bodyString = buildMultipartSignaturePayload(request);
|
String bodyString = buildMultipartSignaturePayload(request);
|
||||||
String dataToHash = bodyString + apiSecret + timestamp;
|
String dataToHash = bodyString + apiSecret + timestamp;
|
||||||
// LogUtil.d("HTTP", dataToHash);
|
|
||||||
String apiKey = EReceiptHelper.sha256(dataToHash);
|
String apiKey = EReceiptHelper.sha256(dataToHash);
|
||||||
|
|
||||||
Map<String, RequestBody> fields = buildFormFields(request);
|
Map<String, RequestBody> fields = buildFormFields(request);
|
||||||
@ -155,31 +150,33 @@ public class Repository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String buildMultipartSignaturePayload(EReceiptCardRequest request) {
|
private String buildMultipartSignaturePayload(EReceiptCardRequest request) {
|
||||||
Map<String, String> flatBody = new LinkedHashMap<>();
|
Map<String, String> flatBody = new TreeMap<>();
|
||||||
putIfNotEmpty(flatBody, "DE2", request.getDE2());
|
putIfNotEmpty(flatBody, "DE2", request.getDE2());
|
||||||
putIfNotEmpty(flatBody, "DE3", request.getDE3());
|
|
||||||
putIfNotEmpty(flatBody, "DE4", request.getDE4());
|
|
||||||
putIfNotEmpty(flatBody, "DE7", request.getDE7());
|
|
||||||
putIfNotEmpty(flatBody, "DE11", request.getDE11());
|
|
||||||
putIfNotEmpty(flatBody, "DE14", request.getDE14());
|
|
||||||
putIfNotEmpty(flatBody, "DE22", request.getDE22());
|
putIfNotEmpty(flatBody, "DE22", request.getDE22());
|
||||||
putIfNotEmpty(flatBody, "DE37", request.getDE37());
|
putIfNotEmpty(flatBody, "DE3", request.getDE3());
|
||||||
putIfNotEmpty(flatBody, "DE38", request.getDE38());
|
|
||||||
putIfNotEmpty(flatBody, "DE39", request.getDE39());
|
putIfNotEmpty(flatBody, "DE39", request.getDE39());
|
||||||
putIfNotEmpty(flatBody, "DE41", request.getDE41());
|
putIfNotEmpty(flatBody, "DE41", request.getDE41());
|
||||||
putIfNotEmpty(flatBody, "DE42", request.getDE42());
|
putIfNotEmpty(flatBody, "DE42", request.getDE42());
|
||||||
putIfNotEmpty(flatBody, "DE43", request.getDE43());
|
|
||||||
putIfNotEmpty(flatBody, "DE48", request.getDE48());
|
|
||||||
putIfNotEmpty(flatBody, "DE49", request.getDE49());
|
|
||||||
putIfNotEmpty(flatBody, "DE55", request.getDE55());
|
|
||||||
putIfNotEmpty(flatBody, "appId", request.getAppId());
|
|
||||||
putIfNotEmpty(flatBody, "batchNumber", request.getBatchNumber());
|
|
||||||
putIfNotEmpty(flatBody, "cardLabel", request.getCardLabel());
|
|
||||||
putIfNotEmpty(flatBody, "description", request.getDescription());
|
|
||||||
putIfNotEmpty(flatBody, "invoiceNumber", request.getInvoiceNumber());
|
|
||||||
putIfNotEmpty(flatBody, "serial", request.getSerial());
|
putIfNotEmpty(flatBody, "serial", request.getSerial());
|
||||||
|
putIfNotEmpty(flatBody, "DE49", request.getDE49());
|
||||||
|
putIfNotEmpty(flatBody, "DE37", request.getDE37());
|
||||||
|
putIfNotEmpty(flatBody, "DE7", request.getDE7());
|
||||||
|
putIfNotEmpty(flatBody, "DE4", request.getDE4());
|
||||||
|
putIfNotEmpty(flatBody, "appId", request.getAppId());
|
||||||
|
putIfNotEmpty(flatBody, "hostId", request.getHostId());
|
||||||
|
putIfNotEmpty(flatBody, "invoiceNumber", request.getInvoiceNumber());
|
||||||
|
putIfNotEmpty(flatBody, "DE11", request.getDE11());
|
||||||
|
putIfNotEmpty(flatBody, "description", request.getDescription());
|
||||||
|
putIfNotEmpty(flatBody, "DE38", request.getDE38());
|
||||||
|
putIfNotEmpty(flatBody, "batchNumber", request.getBatchNumber());
|
||||||
|
putValueOrEmpty(flatBody, "DE55", request.getDE55());
|
||||||
|
putIfNotEmpty(flatBody, "DE14", request.getDE14());
|
||||||
|
putIfNotEmpty(flatBody, "cardLabel", request.getCardLabel());
|
||||||
|
putIfNotEmpty(flatBody, "DE43", request.getDE43());
|
||||||
|
putValueOrEmpty(flatBody, "DE48", request.getDE48());
|
||||||
|
|
||||||
return new Gson().toJson(new TreeMap<>(flatBody));
|
// DE115 is intentionally omitted because it is sent as the image part.
|
||||||
|
return new Gson().toJson(flatBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putIfNotEmpty(Map<String, String> map, String key, String value) {
|
private void putIfNotEmpty(Map<String, String> map, String key, String value) {
|
||||||
@ -188,8 +185,12 @@ public class Repository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void putValueOrEmpty(Map<String, String> map, String key, String value) {
|
||||||
|
map.put(key, value == null || value.trim().isEmpty() ? "" : value);
|
||||||
|
}
|
||||||
|
|
||||||
private Map<String, RequestBody> buildFormFields(EReceiptCardRequest request) {
|
private Map<String, RequestBody> buildFormFields(EReceiptCardRequest request) {
|
||||||
Map<String, RequestBody> map = new HashMap<>();
|
Map<String, RequestBody> map = new TreeMap<>();
|
||||||
putField(map, "DE2", request.getDE2());
|
putField(map, "DE2", request.getDE2());
|
||||||
putField(map, "DE3", request.getDE3());
|
putField(map, "DE3", request.getDE3());
|
||||||
putField(map, "DE4", request.getDE4());
|
putField(map, "DE4", request.getDE4());
|
||||||
@ -203,10 +204,11 @@ public class Repository {
|
|||||||
putField(map, "DE41", request.getDE41());
|
putField(map, "DE41", request.getDE41());
|
||||||
putField(map, "DE42", request.getDE42());
|
putField(map, "DE42", request.getDE42());
|
||||||
putField(map, "DE43", request.getDE43());
|
putField(map, "DE43", request.getDE43());
|
||||||
putField(map, "DE48", request.getDE48());
|
putFieldValueOrEmpty(map, "DE48", request.getDE48());
|
||||||
putField(map, "DE49", request.getDE49());
|
putField(map, "DE49", request.getDE49());
|
||||||
putField(map, "DE55", request.getDE55());
|
putFieldValueOrEmpty(map, "DE55", request.getDE55());
|
||||||
putField(map, "appId", request.getAppId());
|
putField(map, "appId", request.getAppId());
|
||||||
|
putField(map, "hostId", request.getHostId());
|
||||||
putField(map, "batchNumber", request.getBatchNumber());
|
putField(map, "batchNumber", request.getBatchNumber());
|
||||||
putField(map, "cardLabel", request.getCardLabel());
|
putField(map, "cardLabel", request.getCardLabel());
|
||||||
putField(map, "description", request.getDescription());
|
putField(map, "description", request.getDescription());
|
||||||
@ -221,6 +223,11 @@ public class Repository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void putFieldValueOrEmpty(Map<String, RequestBody> map, String key, String value) {
|
||||||
|
String normalizedValue = value == null || value.trim().isEmpty() ? "" : value;
|
||||||
|
map.put(key, RequestBody.create(MediaType.parse("text/plain"), normalizedValue));
|
||||||
|
}
|
||||||
|
|
||||||
public void insertPayDetail(PayDetail payDetail){ payDetailDao.insert(payDetail);}
|
public void insertPayDetail(PayDetail payDetail){ payDetailDao.insert(payDetail);}
|
||||||
|
|
||||||
public Completable insertPay(PayDetail payDetail) { return payDetailDao.insertPay(payDetail); }
|
public Completable insertPay(PayDetail payDetail) { return payDetailDao.insertPay(payDetail); }
|
||||||
|
|||||||
@ -530,7 +530,7 @@
|
|||||||
"currencyCode": "0104"
|
"currencyCode": "0104"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aidEnable": false,
|
"aidEnable": true,
|
||||||
"aid": "A00000006510",
|
"aid": "A00000006510",
|
||||||
"cardScheme": "JCB",
|
"cardScheme": "JCB",
|
||||||
"applicationVersion": "0200",
|
"applicationVersion": "0200",
|
||||||
@ -553,7 +553,7 @@
|
|||||||
"currencyCode": "0104"
|
"currencyCode": "0104"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aidEnable": false,
|
"aidEnable": true,
|
||||||
"aid": "A0000000651010",
|
"aid": "A0000000651010",
|
||||||
"cardScheme": "JCB",
|
"cardScheme": "JCB",
|
||||||
"applicationVersion": "0200",
|
"applicationVersion": "0200",
|
||||||
@ -576,7 +576,7 @@
|
|||||||
"currencyCode": "0104"
|
"currencyCode": "0104"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"aidEnable": false,
|
"aidEnable": true,
|
||||||
"aid": "A0000001570040",
|
"aid": "A0000001570040",
|
||||||
"cardScheme": "JCB",
|
"cardScheme": "JCB",
|
||||||
"applicationVersion": "0200",
|
"applicationVersion": "0200",
|
||||||
|
|||||||
@ -46,7 +46,6 @@ public class SystemParamsSettings implements Serializable {
|
|||||||
// private String ereceiptAddress = "https://api-tms-uat.kbzbank.com:8443/receipt";
|
// private String ereceiptAddress = "https://api-tms-uat.kbzbank.com:8443/receipt";
|
||||||
private String tmsAddress = "https://sirius-nest.utsmyanmar.com/api/v1";
|
private String tmsAddress = "https://sirius-nest.utsmyanmar.com/api/v1";
|
||||||
private String ereceiptAddress = "https://receipt-nest.utsmyanmar.com";
|
private String ereceiptAddress = "https://receipt-nest.utsmyanmar.com";
|
||||||
// private String ereceiptAddress = "http://192.168.10.104:3003";
|
|
||||||
|
|
||||||
private String binValues = "";
|
private String binValues = "";
|
||||||
private String restrictedBinValues = "";
|
private String restrictedBinValues = "";
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user