kh.gov.nbc.bakong_khqr.presenter.MerchantPresentedDecodeMode Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sdk-java Show documentation
Show all versions of sdk-java Show documentation
The standardization of KHQR code specifications will help promote wider use of
mobile retail payments in Cambodia and provide consistent user experience for merchants
and consumers. It can enable interoperability in the payment industry. A common QR code
would facilitate payments among different schemes, e-wallets and banks and would
encourage small merchants to adopt KHQR code as payment method.
KHQR is created for retail or remittance in Cambodia and Cross-Border. It only
requires a single QR for receiving transactions from any payment provider through Bakong
including Bakong App.
The newest version!
package kh.gov.nbc.bakong_khqr.presenter;
import kh.gov.nbc.bakong_khqr.exception.KHQRException;
import kh.gov.nbc.bakong_khqr.model.*;
import kh.gov.nbc.bakong_khqr.core.TagLengthString;
import java.util.HashMap;
import java.util.Objects;
import static kh.gov.nbc.bakong_khqr.model.KHQRMerchantPresentedCodes.*;
public class MerchantPresentedDecodeMode {
private static final int TAG_ID_COUNT = 2;
private static final int TAG_LENGTH_WORD_COUNT = 2;
private static boolean mIsRestrict;
private String payloadFormatIndicator;//m
private String merchantCategoryCode;//m
private String countryCode;//m
private String merchantName;//m
private String merchantCity;//m
private String transactionCurrency;//m
private String crc;//m
private String bakongAccountId;//m
private String merchantType;//m
private String billNumber;//o
private String storeLabel;//o
private String terminalLabel;//o
private String transactionAmount;//o
private String pointOfInitiationMethod;//o
private String timestamp;//o
private String mobileNumber;//o'
private String merchantId; //m for merchant type
private String acquiringBank; //m for merchant type
private String accountInformation; // o
private String upiAccountInformation;
private String purposeOfTransaction;
private String languagePreference;
private String merchantNameAlternateLanguage;
private String merchantCityAlternateLanguage;
public KHQRDecodeData decode(String qr, Boolean isRestrict) throws KHQRException {
mIsRestrict = isRestrict;
MerchantPresentedDecodeMode merchantPresentedDecodeMode = new MerchantPresentedDecodeMode();
int currentIndex = 0;
if (mIsRestrict) {
if (!KHQRValidation.isContainCrcTagValue(qr)) {
KHQRException.throwCustomerException(KHQRErrorCode.CRC_REQUIRED);
} else if (!KHQRValidation.isQrValidCrc(qr)) {
KHQRException.throwCustomerException(KHQRErrorCode.KHQR_INVALID);
} else {
while (currentIndex < qr.length()) {
TagLengthString tagLengthString = getSpecificTagValue(qr, currentIndex);
//check tag order
//checkLengthOrder(startTag, tagLengthString.getTag());
currentIndex += TAG_ID_COUNT + TAG_LENGTH_WORD_COUNT + tagLengthString.getLength();
merchantPresentedDecodeMode.assignValue(tagLengthString);
}
}
} else {
while (currentIndex < qr.length()) {
TagLengthString tagLengthString = getSpecificTagValue(qr, currentIndex);
currentIndex += TAG_ID_COUNT + TAG_LENGTH_WORD_COUNT + tagLengthString.getLength();
merchantPresentedDecodeMode.assignValue(tagLengthString);
}
}
return merchantPresentedDecodeMode.getDecodeData();
}
private HashMap decodeChildTag(String qr) throws KHQRException {
HashMap tagLengthStrings = new HashMap<>();
int currentIndex = 0;
if (mIsRestrict) {
while (currentIndex < qr.length()) {
TagLengthString tagLengthString = getSpecificTagValue(qr, currentIndex);
//check tag order
//checkLengthOrder(startTag, tagLengthString.getTag());
currentIndex += TAG_ID_COUNT + TAG_LENGTH_WORD_COUNT + tagLengthString.getLength();
tagLengthStrings.put(tagLengthString.getTag(), tagLengthString);
}
} else {
while (currentIndex < qr.length()) {
TagLengthString tagLengthString = getSpecificTagValue(qr, currentIndex);
currentIndex += TAG_ID_COUNT + TAG_LENGTH_WORD_COUNT + tagLengthString.getLength();
tagLengthStrings.put(tagLengthString.getTag(), tagLengthString);
}
}
return tagLengthStrings;
}
private TagLengthString getSpecificTagValue(String source, int currentIndex) {
int tagCount = currentIndex + TAG_ID_COUNT;
int lengthCount = currentIndex + TAG_LENGTH_WORD_COUNT;
String tag;
String value;
try {
tag = source.substring(currentIndex, tagCount);
} catch (Exception e) {
tag = "";
}
try {
int length = Integer.parseInt(source.substring(lengthCount, lengthCount + TAG_LENGTH_WORD_COUNT));
int dataStartLength = currentIndex + TAG_ID_COUNT + TAG_LENGTH_WORD_COUNT;
int dataLength = currentIndex + TAG_LENGTH_WORD_COUNT + TAG_ID_COUNT + length;
value = source.substring(dataStartLength, dataLength);
} catch (Exception e) {
value = "";
}
return new TagLengthString(tag, value);
}
private void assignValue(TagLengthString tagLengthString) throws KHQRException {
String tag = tagLengthString.getTag();
String value = tagLengthString.getValue();
switch (tag) {
case PAYLOAD_FORMAT_INDICATOR: {
setPayloadFormatIndicator(value);
break;
}
case UPI_ACCOUNT_INFORMATION: {
setUpiAccountInformation(value);
break;
}
case MERCHANT_ACCOUNT_INFORMATION_INDIVIDUAL:
case MERCHANT_ACCOUNT_INFORMATION_MERCHANT: {
HashMap internalTagLengthString;
internalTagLengthString = decodeChildTag(value);
if (internalTagLengthString.get(MERCHANT_ACCOUNT_INFORMATION_GLOBALLY_UNIQUE_IDENTIFIER) != null) {
String accountId = Objects.requireNonNull(internalTagLengthString.get(MERCHANT_ACCOUNT_INFORMATION_GLOBALLY_UNIQUE_IDENTIFIER)).getValue();
setBakongAccountId(accountId);
}
if (internalTagLengthString.get(MERCHANT_ACCOUNT_INFORMATION_MERCHANT_ID) != null) {
String merchantInfo = Objects.requireNonNull(internalTagLengthString.get(MERCHANT_ACCOUNT_INFORMATION_MERCHANT_ID)).getValue();
if (tag.equals(MERCHANT_ACCOUNT_INFORMATION_MERCHANT)) {
setMerchantId(merchantInfo);
} else {
setAccountInformation(merchantInfo);
}
}
if (internalTagLengthString.get(MERCHANT_ACCOUNT_INFORMATION_ACQUIRING_BANK) != null) {
String acquiringBank = Objects.requireNonNull(internalTagLengthString.get(MERCHANT_ACCOUNT_INFORMATION_ACQUIRING_BANK)).getValue();
setAcquiringBank(acquiringBank);
}
setMerchantType(tag);
break;
}
case MERCHANT_CATEGORY_CODE: {
setMerchantCategoryCode(value);
break;
}
case COUNTRY_CODE: {
setCountryCode(value);
break;
}
case MERCHANT_NAME: {
setMerchantName(value);
break;
}
case MERCHANT_CITY: {
setMerchantCity(value);
break;
}
case TRANSACTION_CURRENCY: {
setTransactionCurrency(value);
break;
}
case CRC: {
setCrc(value);
break;
}
case ADDITIONAL_DATA_FIELD_TEMPLATE: {
HashMap internalTagLengthString;
internalTagLengthString = decodeChildTag(value);
if (internalTagLengthString.get(ADDITIONAL_DATA_FIELD_BILL_NUMBER) != null) {
String billNumber = Objects.requireNonNull(internalTagLengthString.get(ADDITIONAL_DATA_FIELD_BILL_NUMBER)).getValue();
setBillNumber(billNumber);
}
if (internalTagLengthString.get(ADDITIONAL_DATA_FIELD_STORE_LABEL) != null) {
String storeLabel = Objects.requireNonNull(internalTagLengthString.get(ADDITIONAL_DATA_FIELD_STORE_LABEL)).getValue();
setStoreLabel(storeLabel);
}
if (internalTagLengthString.get(ADDITIONAL_DATA_FIELD_TERMINAL_LABEL) != null) {
String terminalLabel = Objects.requireNonNull(internalTagLengthString.get(ADDITIONAL_DATA_FIELD_TERMINAL_LABEL)).getValue();
setTerminalLabel(terminalLabel);
}
if (internalTagLengthString.get(ADDITIONAL_DATA_FIELD_MOBILE_NUMBER) != null) {
String mobileNumber = Objects.requireNonNull(internalTagLengthString.get(ADDITIONAL_DATA_FIELD_MOBILE_NUMBER)).getValue();
setMobileNumber(mobileNumber);
}
if (internalTagLengthString.get(ADDITIONAL_DATA_FIELD_PURPOSE_OF_TRANSACTION) != null) {
String purposeOfTransaction = Objects.requireNonNull(internalTagLengthString.get(ADDITIONAL_DATA_FIELD_PURPOSE_OF_TRANSACTION)).getValue();
setPurposeOfTransaction(purposeOfTransaction);
}
break;
}
case RFU_FOR_KHQR: {
TagLengthString tagLengthStringRfu = getSpecificTagValue(value, 0);
if (tagLengthStringRfu.getTag().equals(TIMESTAMP)) {
setTimestamp(tagLengthStringRfu.getValue());
}
break;
}
case POINT_OF_INITIATION_METHOD: {
setPointOfInitiationMethod(value);
break;
}
case TRANSACTION_AMOUNT: {
setTransactionAmount(value);
break;
}
case MERCHANT_INFORMATION_LANGUAGE_TEMPLATE: {
HashMap internalTagLengthString;
internalTagLengthString = decodeChildTag(value);
if (internalTagLengthString.get(MERCHANT_INFORMATION_LANGUAGE_LANGUAGE_PREFERENCE) != null) {
String languagePreference = Objects.requireNonNull(internalTagLengthString.get(MERCHANT_INFORMATION_LANGUAGE_LANGUAGE_PREFERENCE)).getValue();
setLanguagePreference(languagePreference);
}
if (internalTagLengthString.get(MERCHANT_INFORMATION_LANGUAGE_MERCHANT_NAME) != null) {
String merchantNameAlternativeLanguage = Objects.requireNonNull(internalTagLengthString.get(MERCHANT_INFORMATION_LANGUAGE_MERCHANT_NAME)).getValue();
setMerchantNameAlternateLanguage(merchantNameAlternativeLanguage);
}
if (internalTagLengthString.get(MERCHANT_INFORMATION_LANGUAGE_MERCHANT_CITY) != null) {
String merchantCityAlternativeLanguage = Objects.requireNonNull(internalTagLengthString.get(MERCHANT_INFORMATION_LANGUAGE_MERCHANT_CITY)).getValue();
setMerchantCityAlternateLanguage(merchantCityAlternativeLanguage);
}
break;
}
}
}
private KHQRDecodeData getDecodeData() throws KHQRException {
KHQRDecodeData khqrDecodeData = new KHQRDecodeData();
khqrDecodeData.setCrc(crc);
khqrDecodeData.setPayloadFormatIndicator(payloadFormatIndicator);
khqrDecodeData.setPointOfInitiationMethod(pointOfInitiationMethod);
khqrDecodeData.setMerchantType(merchantType);
khqrDecodeData.setBakongAccountID(bakongAccountId);
khqrDecodeData.setMerchantId(merchantId);
khqrDecodeData.setAccountInformation(accountInformation);
khqrDecodeData.setAcquiringBank(acquiringBank);
khqrDecodeData.setMerchantCategoryCode(merchantCategoryCode);
khqrDecodeData.setTransactionCurrency(transactionCurrency);
khqrDecodeData.setTransactionAmount(transactionAmount);
khqrDecodeData.setCountryCode(countryCode);
khqrDecodeData.setMerchantName(merchantName);
khqrDecodeData.setMerchantCity(merchantCity);
khqrDecodeData.setBillNumber(billNumber);
khqrDecodeData.setMobileNumber(mobileNumber);
khqrDecodeData.setStoreLabel(storeLabel);
khqrDecodeData.setTerminalLabel(terminalLabel);
khqrDecodeData.setTimestamp(timestamp);
khqrDecodeData.setUpiAccountInformation(upiAccountInformation);
khqrDecodeData.setPurposeOfTransaction(purposeOfTransaction);
khqrDecodeData.setMerchantAlternateLanguagePreference(languagePreference);
khqrDecodeData.setMerchantNameAlternateLanguage(merchantNameAlternateLanguage);
khqrDecodeData.setMerchantCityAlternateLanguage(merchantCityAlternateLanguage);
//validate field
if (mIsRestrict) KHQRValidation.validate(khqrDecodeData);
return khqrDecodeData;
}
private void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
private void setMerchantType(String merchantType) {
this.merchantType = merchantType;
}
private void setPayloadFormatIndicator(String payloadFormatIndicator) {
this.payloadFormatIndicator = payloadFormatIndicator;
}
private void setMerchantCategoryCode(String merchantCategoryCode) {
this.merchantCategoryCode = merchantCategoryCode;
}
private void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
private void setMerchantName(String merchantName) {
this.merchantName = merchantName;
}
private void setMerchantCity(String merchantCity) {
this.merchantCity = merchantCity;
}
private void setTransactionCurrency(String transactionCurrency) {
this.transactionCurrency = transactionCurrency;
}
private void setCrc(String crc) {
this.crc = crc;
}
private void setBillNumber(String billNumber) {
this.billNumber = billNumber;
}
private void setStoreLabel(String storeLabel) {
this.storeLabel = storeLabel;
}
private void setTerminalLabel(String terminalLabel) {
this.terminalLabel = terminalLabel;
}
private void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
private void setTransactionAmount(String transactionAmount) {
this.transactionAmount = transactionAmount;
}
private void setPointOfInitiationMethod(String pointOfInitiationMethod) {
this.pointOfInitiationMethod = pointOfInitiationMethod;
}
private void setBakongAccountId(String bakongAccountId) {
this.bakongAccountId = bakongAccountId;
}
private void setMerchantId(String merchantId) {
this.merchantId = merchantId;
}
private void setAcquiringBank(String acquiringBank) {
this.acquiringBank = acquiringBank;
}
private void setAccountInformation(String accountInformation) {
this.accountInformation = accountInformation;
}
private void setUpiAccountInformation(String upiAccountInformation) {
this.upiAccountInformation = upiAccountInformation;
}
private void setPurposeOfTransaction(String purposeOfTransaction) {
this.purposeOfTransaction = purposeOfTransaction;
}
private void setLanguagePreference(String languagePreference) {
this.languagePreference = languagePreference;
}
private void setMerchantNameAlternateLanguage(String merchantNameAlternateLanguage) {
this.merchantNameAlternateLanguage = merchantNameAlternateLanguage;
}
private void setMerchantCityAlternateLanguage(String merchantCityAlternateLanguage) {
this.merchantCityAlternateLanguage = merchantCityAlternateLanguage;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy