Data Models
MhdEmvTransactionDto
data class MhdEmvTransactionDto(
/* Mandatory,the transaction amount.
* Be careful, the amount should be transferred to long based on ISO4217
*/
var txnAmount: Long,
/* Deprecated, ignored by the SDK. The amount on the payment screen and the PIN pad is always
* formatted from txnAmount in the terminal currency, so what the cardholder sees cannot
* differ from what is authorised.
*/
@Deprecated("Ignored by the SDK.")
var displayAmountText: String? = null,
/* Mandatory,Transaction currency text */
var txnCurrencyText: String? = "USD",
/* Optional,the unique transaction number assigned by application.*/
var txnNo: Long = 0,
/* Optional,transaction type */
var txnType: TranType = TranType.SALE,
/* Optional,card reading time out, 0-no timeout forever */
var timeout: Int = 60,
/**
* Optional,the encryption mode for track2 data encryption. it can be CBC or GCM.
* track2 data is encrypted and returned as IV||encrypted data.
* example:
* track2 : 5500000000000004=22041015432112345678
* iv : 11000000000000000000000000000022
* key : 00000000000000000000000000000000
* mode : CBC
* encrypt : CCF9C6F00685AF3AD912E0FA4E8E8BEF4EB940EB045A0FA358B66F9FCD6F962F
* SDK returns encrypted track2:
* 11000000000000000000000000000022
* CCF9C6F00685AF3AD912E0FA4E8E8BEF
* 4EB940EB045A0FA358B66F9FCD6F962F
*/
var encryptMode: EncryptMode = EncryptMode.CBC,
/* Optional, transaction description */
var description: String? = null,
/* Optional, used for PIN pad UI customization: a PinPadConfig object serialised to a JSON string.
* If the string is not valid PinPadConfig JSON the SDK uses the default PinPadConfig() and
* reports no error. See "PIN Pad Customization" in the PIN Capture page.
*/
val pinpadConfig: String? = null,
val supportedPaymentMethod: List<PaymentMethod>? = null,
/**
* Optional,wrapped HMAC key used for computing the SHA-256 hash of card sensitive data,
* This key must be wrapped (encrypted) using the SDK RSA KEK.
* it is provided in returned object of MPoCAPI.getSDKInfo() with field "kekCert"
* encode : Base64 of encrypted bytearray
* rsa wrap method : RSA/ECB/OAEPWithSHA-256AndMGF1Padding
* OAEPParameterSpec : SHA1
**/
val wrappedHMacKey: String? = null,
/* Optional, how many times a card read is retried before the transaction gives up. */
val allowMaxRetries: Int = 3,
/* Optional, turns on the EMV kernel debug logs for this transaction. Never enable in production. */
val enableEmvLogs: Boolean = false,
/**
* Optional, decides who collects the PIN when the card asks for an online PIN.
* true (default) - the SDK opens its own PIN screen right after the card is read. The PIN block
* and PIN key id come back in MhdEmvTransResult.
* false - the SDK does NOT open the PIN screen. The transaction returns right after the
* card read with cardCVM = PIN and no PIN block (pinKeyId has no value), and your
* app collects the PIN itself afterwards.
* Cards that do not ask for a PIN are not affected either way.
*/
val autoPinEntry: Boolean = true,
/**
* Optional field for app customization.
* This data can be used by the app to customize UI elements, such as displaying
* specific information during card reading or other app-defined behaviors.
*/
val extData: Map<String,String>? = null
)MhdEmvTransResult
public final data class MhdEmvTransResult(
// "0" means success , others means fail
val outComeCode: String? = null,
// fail message when it's failure
val outComeMessage: String? = null,
// EMV tag data. Track2 (57) is encrypted under the card key and returned as IV||ciphertext.
// The online PIN block (ISO 9564 format 4), when a PIN was entered, is under key "99".
val kernelInfoData: MutableMap<String, String>? = HashMap(),
// CardKey KSN
val cardKeyId: String? = null,
// PIN Key KSN. Has no value when no PIN was entered, e.g. when autoPinEntry = false
val pinKeyId: String? = null,
// PaymentMethod: VISA, MASTERCARD,JCB,AMEX,DISCOVER,UNIONPAY, ... see PaymentMethod
val paymentMethod: PaymentMethod? = null,
// masked Pan: 1234 56** **** 7890
val maskedPan: String? = null,
// indicate the CVM type. NO_CVM,SIGNATURE,PIN,OFFLINE_PIN,CDCVM,PIN_BYPASS
// With autoPinEntry = false, PIN means the card asked for a PIN that your app still has to collect.
val cardCVM: CardCVM? = null,
// The HMAC-SHA256 hash of card sensitive data, calculated using the wrappedHMAC key.
// cardHasValues = Hmac(PAN||PAN Sequence Number|| expiration date, hmacKey)
var cardHashValue: String? = null
)MhdEmvPinResult(result ofMPoCAPI.pinCapture)
data class MhdEmvPinResult(
// PIN block, ISO 9564 format 4
val pinBlock: String,
// PIN key KSN
val pinKeyId: String,
// last 4 digits of the PAN the PIN block was built against
val panLast4: String
)- PIN pad models
PinPadConfig, PinPadStyle, PinEntryDetails, PinPadDimensions, TextStyleConfig, ButtonsColor,
PreparingStyle and PinEntryMode configure the PIN pad. They are described in full, with every field, in
PIN Capture.
MPoCResult
sealed class MPoCResult<out T> {
data class Success<T>(val data: T) : MPoCResult<T>()
data class Failure(val code: Int, val message: String, val contextual: String = "")
: MPoCResult<Nothing>()
}PaymentMethod
enum class PaymentMethod {
VISA,
MASTERCARD,
UNIONPAY,
AMEX,
JCB,
DISCOVER,
DINERS,
MYDEBIT,
// mobile wallets
APPLE_PAY,
GOOGLE_PAY,
SAMSUNG_PAY,
HUAWEI_PAY,
UNKNOWN
}TranType
enum class TranType {
SALE,
REFUND
}CardCVM
enum class CardCVM {
NO_CVM,
// The sdk doesn't include signature pad
SIGNATURE,
// PIN Block format4 will be returned.
// If MhdEmvTransactionDto.autoPinEntry = false, the PIN is NOT collected by the SDK: this value only
// tells you the card asked for a PIN, and no PIN block is returned.
PIN,
// OFFLINE_PIN won't be available in MPoC.
OFFLINE_PIN,
CDCVM,
// The cardholder skipped the PIN entry (see PinEntryDetails.supportPINBypass)
PIN_BYPASS
}EncryptMode
enum class EncryptMode {
// Encrypted with CBC mode. the first 16 bytes of returned data is the IV
CBC,
// Encrypted with GCM mode. the first 12 bytes of returned data is the IV
GCM
}MhdEncryptedData(result ofMPoCAPI.encryptData, see Sign & Encrypt Data)
data class MhdEncryptedData(
// hex of IV || ciphertext (CBC) or IV || ciphertext || tag (GCM). The IV is random on every call
val encryptedHex: String,
// the 12-byte KSN (24 hex characters) the key was derived at
val ksn: String,
val mode: EncryptMode
)EmvAppUpdateMode
enum class EmvAppUpdateMode {
// append the emvAppCfg into EMV list. If AID inside emvAppCfg exist in SDK already, then do a replacement
APPEND,
// clean all existing records , and add emvAppCfg
CLEAN_BEFORE_SET
}UiState
sealed interface UiState {
//Before card reading, the SDK has to do preparations such as security checking, key preparation etc.
//Errors happens in this stage will terminate the activity and return.
sealed interface Preparing : UiState {
data object Idle : Preparing
}
//Once preparation is done, SDK card reading flow jumps into AwaitingCardScreen to start card reading.
//PIN Entry may be required during this period.
sealed interface Awaiting : UiState {
data class Idle(
val supportedPayments: List<PaymentMethod>
) : Awaiting
data object OperationErrorCheck : Awaiting
}
}- MPoC
PaymentErrorCodeserror code (for card reading process)
enum class PaymentErrorCodes(val code: Int, val message: String) {
// general errors
InvalidInputRequest(70_001, "Invalid Input"),
// a second request was made while another transaction is still running
TransactionInProgress(70_019, "Another transaction is already in progress"),
// initialisation
SdkNotInitialised(70_016, "SDK is not initialised"),
SdkRecoveryFailed(70_017, "SDK could not restore itself after its process restarted"),
// aborted,the acitivity will finsih with specify error code and error message.
AbortedProcessingTimeOut(70_009, "processing timeout"),
AbortedNfcTappingTimeOut(70_002, "Nfc card tapping timeout"),
AbortedUserCancelTapping(70_003, "User cancel card tapping"),
AbortedUserCancelPIN(70_004, "User cancel PIN Entry"),
AbortedPinEntryTimeOut(70_005, "PIN Entry timeout"),
AbortedSecurityAlert(70_006, "Security Checks fail"),
AbortedProcessQuit(70_007, "Processing Activity Quit"),
AbortedCardKeyLoadingFail(70_008, "CardKey Loading fails"),
AbortedCardReadRetryCountExceeded(70_018, "Card read retry count exceeded"),
AbortedCardReadError(70_010, "EMV card declined"),
AbortedCardDataValidationError(70_011, "Card data validation error"),
AbortedCryptoOperationError(70_012, "MPoC crypto operation error"),
AbortedCardDataEncryptionError(70_013, "MPoC crypto operation error"),
AbortedNotSupportedPaymentMethod(70_014, "Not supported payment method"),
AbortedScreenTooSmall(70_015, "Screen too small to display PIN pad"),
//PIN entry eror
PinKeyNotReady(71_005, "PIN Key is not ready, please retry"),
PinProcessException(71_006, "PIN Entry exception"),
PaymentProcessRetryableFail(71_004, "operation fails, please retry"),
// other resource exception
OtherSourceError(72_000, "Error from other source")
}SdkInfo
data class SdkInitResult(
// true - registered. false -- not registered
val isRegistered: Boolean,
// sdkId of the SDK
val sdkId: String,
// DEBUG -- current version is debug build
// PROD -- current version is production build
val sdkBuildModel: String ,
// SDK version
val sdkVersion: String,
// License Id
val licenseId: String,
// customer Id
val customerId: String,
// AMS server url
val serverUrl: String ,
// KEK Certificate
val kekCert: String,
// SDK Identity Certificate
val signCert: String
)