# Technical documentation MDC SDK ## Introduction ### Basic abbreviations and definitions
**Field****Description**
FCMFirebase Cloud Messaging
DCData Core
MDCMobile DC module
MPAMobile Payment Application
UCPVerestro Cloud Payments
IBANBack Account Number
JWTJson Web Token
JWEJson Web Encryption
OTPOne-time password
### What is Mobile DC SDK? The Mobile DC SDK is a core module dedicated to the management of users, devices, and cards in the Verestro system. Usage of other Verestro modules (f.e. UCP - Verestro Claud Payment) always depends on this SDK and Mobile DC must be always used. ### Versioning and backward compatibility SDK version contains three numbers. For example: 1.0.0. - First version digit tracks compatibility-breaking changes in SDK public APIs. It is mandatory to update the application code and to use SDK when this is incremented. - Second version digit tracks new, not compatibility-breaking changes in the public API of SDK. It is optional to update the application code when this digit is incremented. - The third version digit tracks internal changes in SDK. No updates in the application code are necessary to update to the version, which has this number incremented. Changes not breaking compatibility: - Adding a new optional interface to SDK setup. - Adding a new method to any domain. - Adding new ENUM value to input or output. - Adding a new field in the input or output model. ## Technical overview This section describes basic information about Mobile DC SDK, SDK setup, and available methods. ### Basic configuration **Artifactory** SDK is available on the Verestro maven repository and can be configured in a project using the Gradle build system. **The username and password are provided by Verestro.**
``` repositories{ maven { credentials { username "" password "" } url "https://artifactory.upaid.pl/artifactory/libs-release-local/" } ```
**Versions** Mobile DC SDK is available in two versions: debug and release. The difference between versions is debugged version allows to use of an application with a debugger connected. Debug version is ended with appendix "-debug" in version name. Samples below: For release version, used on production environment in application uploaded to Google Play:
``` dependencies{ implementation 'pl.upaid.module:mobiledc:{version}' } ```
Debug version - could be used for application development:
``` dependencies{ implementation 'pl.upaid.module:mobiledc:{version}-debug' } ```
**Min SDK Version** The minSdkVersion must be at least 23 (Android 6.0). In case of using SDK on lower Android API version declare in the application manifest.
``` ```
SDK cannot be initialized on a lower Android API version, and none of the SDK methods should be used on it. **Android APIs 31+** Android Worker uses PendingIntent which causes some problems with the newest Android APIs. To resolve this problem application Gradle dependency configuration must override this dependency.
``` dependencies{ implementation 'androidx.work:work-runtime-ktx:2.7.1' } ```
Native libs extraction in AndroidManifest and Gradle. Native libs should be packaged in application in uncompressed form due to security reasons. This solution is also recommended by Google due to the smaller app install and download size. Note: Starting from Android Gradle Plugin 4.2 an attribute is replaced with parameter `android.packagingOptions.jniLibs.useLegacyOptions`. If you need to package native libraries in the compressed form please contact Verestro. Recommended solution when using Verestro SDK below:
``` //AndroidManifest.xml ```
``` //build.gradle android { packagingOptions { jniLibs { useLegacyPackaging false } } } ```
``` ``` **Source code obfuscation and optimization** As SDK is written in Kotlin the language we recommend adding following code to Gradle configuration:
``` android { ... kotlinOptions { freeCompilerArgs = [ '-Xno-param-assertions', '-Xno-call-assertions', '-Xno-receiver-assertions' ] } packagingOptions { exclude '/kotlin_metadata/**' } ... } ```
And use the newest tools for code shrinking, optimization, and obfuscation from Google by enabling R8 instead Proguard in the *gradle.properties* file:
``` android.enableR8=true ```
**Android permissions** **QUERY\_ALL\_PACKAGES** Module declares the usage of permission QUERY\_ALL\_PACKAGES, which is required since Android API 30 to list packages available on the device. Permission is used for security tasks. On 20.07.2022 Google Play introduced restrictions on high-risk permissions and the application sender could be obliged to send more information about this permission usage. The application which uses this permission is usually a bank or financial institution - in such case permission may be granted to usage. Read more [https://support.google.com/googleplay/android-developer/answer/10158779?hl=en](https://support.google.com/googleplay/android-developer/answer/10158779?hl=en) In case of lack of agreement from Google Play permission could be removed on the application side AndroidManifest.xml file. When removed application should declare package visibility to search known root packages. In case of removing this permission please contact Verestro representative. Sample code to remove QUERY\_ALL\_PACKAGES permission in the AndroidManigest.xml file and package visibility declaration:
``` ```
### MDC SDK Size The size of SDK is dependent on the apk distribution system. The table below shows the size of the module for apk and bundle file.
**Format****Size****Notes**
APK~15,1 MB
Bundle~2,5 MB - ~3,6 MBRanged size depends on the ABI of the device. SDK contains native libraries used by different ABI. By using a bundle only the necessary version of the native library will be downloaded to a device.
Additional information - size from the table above is referred to release version; - size depends on configured proguard (module provides consumer progurd rules); ### MDC SDK usage This chapter describes the structure and basic usage of Mobile DC SDK. #### Domains Every described facade is divided into domains with different responsibilities. Available domains: - Cards. - User. - Device. - CloudMessaging. - TransactionsHistory. Every domain contains domain-related methods. #### Facade The facade is an entry point to communication with Mobile DC SDK. Contains an SDK initialization method and domains which allows to manage Verestro account. #### Multiple facade types Mobile DC SDK provides three public APIs with the same functionalities, the APIs are: - MobileDcApiJava for projects which use Java programming language. - MobileDcApiKotlin for projects which use Kotlin programming language. The difference between the APIs is a way of providing data to SDK methods and getting the results from them. Input and output as information data are always the same. This documentation presents I/O types in a Kotlin way as it’s easier to mark nullable fields (as a question mark). #### Method structure Every method described in documentation has same structure. **Execution type:** - Asynchronous - Operation could take more time and method is called on thread different than main. The result of execution is provided in callback (described below). - Synchronous - Result of operation is provided as method return type. **Method type:** - Online - Operation requires internet connection. - Offline - Operation can be called without internet access. **Input** Input parameters with name, description and validation rules. For some methods input is result of different uPaid method. **Output** If present is delivered in success callback with data described below. **Callbacks** - Success callback - Depends on used programming language and facade type [Multiple facade types.](https://wiki.verestro.com/pages/viewpage.action?pageId=67340674) s onSuccess or success callback inform about operation success. - Success callback with data - Callback with additional result object. - Failure callback - Informs about failure. Contains information about exception ([Error handling.](https://wiki.verestro.com/pages/viewpage.action?pageId=67340690)). Exception can contains additional details. **Sample usage:**
``` //java sample cardsService.getAll( new SuccessDataCallback>() { @Override public void onSuccess(List cards) { //show cards on UI } }, new FailureCallback() { @Override public void onFailure(@NotNull Throwable throwable) { //show error } }); SuccessDataCallback and FailureCallback could be replaced by lambda like in kotlin sample below //kotlin sample cardsService.getAll({ cards -> //show cards on UI }, { //show error }) ```
#### Error handling SDK returns errors by exceptions, which could be caught by the application and shown on UI with a detailed message. **Note:** Exception message is only information for a developer and shouldn't be shown on the application UI to the user. Use reason code to add a suitable message on the application layer. The table below describes exceptions types.
**Exception type****Exception class****Description**
SDK ValidationValidationExceptionEvery parameter provided in method is validated locally by SDK. For example, card number is validated with Luhn algorithm Exception object contains field reason with detailed error code
BackendBackendExceptionProvides additional validation or error on backend side Exception object contains field *reasonCode* and *message* Application should get reason code and show suitable message or made action Message should be never shown to user. Could be logged for error reporting and for developers List of available raeson in table below
Internal SdkCoreSdkExceptionProvides additional information about error in SDK Exception object contains field reason and message Application should get reason code and show suitable message or made action Message should be never shown to user. Could be logged for error reporting and for developers List of available raeson in table below
Process related-As every process is different some methods could throw specified exception. Types of exception is described in method description
NetworkNetworkConnectionExceptionProvide information about network connection error. Check table with possible reasons below
InternalUnknownExceptionFor unknown errors in SDK process
**BackendException error codes**
**Reason code** **Description**
INTERNAL\_ERROR Error occurred on server
CRYPTOGRAPHY\_ERROR Error occurred during cryptography operation
VALIDATION\_ERROR Client sent invalid data
CARD\_NO\_OUTSIDE\_RANGE\_BINS Card number is outside of preconfigured range
CARD\_KIND\_LIMIT\_REACHED Card kind limit reached
CARD\_DELETED Card was deleted and operation cannot be proceed
FAIL\_3DS\_VERIFICATION 3ds verification failed
FAIL\_AUTHORIZATION Fail authorization - error from card verification
TRANSACTION\_DENIED Transaction denied - error from card verification
FAIL\_AUTHENTICATION Invalid username or password
CARD\_EXPIRED Card expired
LIMITS\_EXCEEDED Limit of transactions has been exceeded
REJECTED\_BY\_BANK Current transaction has been rejected by bank - error from card verification
INSUFFICIENT\_FOUNDS There is no enough founds on card to complete this transaction
INVALID\_JWS\_TOKEN Specified JWS token is invalid
INVALID\_FCM\_TOKEN Given FCM token is invalid
OPERATION\_NOT\_SUPPORTED Method is not allowed
CANT\_FIND\_USER Cannot find user by requested identifier
CANT\_FIND\_CARD Cannot find card by requested identifier
CANT\_FIND\_DEVICE Cannot find device by requested identifier
CANT\_FIND\_WPIN Cannot find wallet pin
CANT\_FIND\_ADDRESS Cannot find requested address
CANT\_FIND\_INVITATION Cannot find invitation for the requested resource
RESOURCE\_NOT\_FOUND Cannot find requested resource
USER\_IS\_LOCKED Requested user is locked
CARD\_IS\_LOCKED Requested card is locked
DEVICE\_PERMANENTLY\_LOCKED Requested device is locked
DEVICE\_TEMPORARILY\_LOCKED Requested device is temporary locked
BAD\_LOGIN\_LIMIT\_REACHED Number of incorrect login attempts is reached
BAD\_WPIN\_LIMIT\_REACHED Requested user is temporary locked
SMS\_FAILCOUNT\_REACHED Sms fail count limit reached
TOO\_MANY\_REQUESTS Too Many Requests
CARD\_IS\_ALREADY\_VERIFIED Requested card has been verified
USER\_IS\_NOT\_VERIFIED User is not verified. E.g. User had registered already however did not finish the verification step and is trying to pair/login
PAYMENT\_ALREADY\_SUCCESS Requested payment has been already finished
INVALID\_CARD Card is invalid for this payment
USER\_HAS\_NOT\_SET\_A\_PASSWORD Requested user has not set password
DEVICE\_LIMIT\_REACHED Number of device is reached
BAD\_WPIN The wallet pin does not match the requested user
SMS\_LIMIT\_EXCEEDED Number of sent messages has reached the limit. Please try again later
FAIL\_COUNT\_LIMIT\_REACHED Attempt limit has exceeded
INITIALIZE\_PROCESS\_REQUIRED Fail count limit has been reached and new process has not been initialized
INVALID\_AUTHORIZATION\_AMOUNT Authorization amount is incorrect
CLIENT\_UNAUTHORIZED Client of the api is unauthorized(invalid/expired *X-Client-Auth* token)
USER\_UNAUTHORIZED User is unauthorized
VERIFICATION\_FAILED Requested card could not be verified
CARD\_NOT\_ENROLLED Card does not participate in 3ds v2, please use 3ds v1
INVALID\_AUTHENTICATION\_ID Authentication process id does not match card id
**BackendException - additional error codes** **related to TransactionsHistoryService**
**Reason code** **Description**
TRANSACTION\_ATTACHMENT\_STATUS\_APPROVED Cannot update transaction or store new attachment. Attachment status in transaction is APPROVED
MAX\_ATTACHMENTS\_COUNT Maximum number of attachments for given transaction
MAX\_ATTACHMENT\_SIZE\_EXCEEDED Maximum attachment size exceeded
EMPTY\_ATTACHMENT Empty attachment file
EMPTY\_ATTACHMENT\_NAME Empty attachment file name
NOT\_SUPPORTED\_ATTACHMENT\_FILE\_TYPE Attachment file type is not supported
CANT\_FIND\_TRANSACTION\_ATTACHMENT Cannot find transaction attachment
**CoreSdkException error codes INTERNAL\_ERROR**
Reason codeDescription
DEVICE\_NOT\_PAIREDDevice is not paired or trying to call the method without device pairing
SAFETYNET\_ERRORAn error during device authentication in Google SafetyNet service
PUSH\_INVALID\_SOURCERelates to push processing process. Push message should be consumed in another module
PUSH\_INVALID\_PUSH\_CONTENTCannot process push message. The message is invalid or some process failed
BIOMETRIC\_AUTHENTICATION\_NOT\_ENABLEDBiometric public key is invalid
BIOMETRIC\_AUTHENTICATION\_ABORTEDCannot authenticate biometric signature
KEYSTORE\_IS\_NOT\_SECUREKeystore is not secure. The device is not secured with PIN, pattern or password
CANNOT\_GET\_PUBLIC\_KEYInternal error during SDK processing
SECURITY\_EVENT\_OCCURREDSecurity event occurred during application usage. Data is cleared and the method can't be used. Application is always informed about a security issue with onSecurityIssueAppeared callback initialized in setup() method
PIN\_AUTHENTICATION\_FAILURE Provided PIN is invalid
PIN\_AUTHENTICATION\_FAILURE\_LIMIT\_EXCEEDED PIN fail count is reached, every next try PIN authentication will finish with this status
PIN\_AUTHENTICATION\_NOT\_POSSIBLE PIN authentication is not possible until the user is at least once logged online with PIN
PIN\_AUTHENTICATION\_INTERNAL\_ERROR Something went wrong
PAIRING\_IS\_ALREADY\_IN\_PROGRESSAnother pairing is now processed
PAYMENT\_INSTRUMENT\_DEFAULT\_NOT\_FOUNDNo default payment instrument for contactless payment found
PAYMENT\_INSTRUMENT\_NOT\_FOUNDPayment instrument with this id cannot be found in SDK
APPLICATION\_PROCESS\_NOT\_KILLEDApplication process is not killed after SDK reset
TOKEN\_NOT\_ACTIVERequired token status is ACTIVE
PAYMENT\_INSTRUMENT\_NOT\_FOUNDToken with that id was not found in SDK
API\_SERVICE\_NOT\_INITIALIZEDAPI service was not initialized
DIGITIZATION\_NOT\_STARTEDDigitization of that payment instrument was not started
**NetworkConnectionException error codes**
**Reason code****Description**
UNKNOWN\_HOSTHost is unreachable, check network connection and try again later
SOCKET\_TIMEOUTConnection timeout, check network connection and try again later
UNKNOWN\_HTTP\_ERRORAn unknown HTTP error
### ### Firebase Cloud Messaging configuration **Dependency** Add Firebase Cloud Messaging dependency entry to build.gradle.
``` ... implementation('com.google.firebase:firebase-messaging:22.0.0') ... ```
**Initializing** All parameter required to initialize FCM can get from firebase console.
``` val firebaseOptions = FirebaseOptions .Builder() .setApplicationId(applicationId) .setGcmSenderId(senderId) .setProjectId(projectId) .setApiKey(apiKey) .build() FirebaseApp.initializeApp(this, firebaseOptions) ```
To initialize two FCM projects should add name parameter for second one.
``` //init default project FirebaseApp.initializeApp(this, firebaseOptions) //init additional project FirebaseApp.initializeApp(this, firebaseOptionsOther, otherProjectName) ```
**Getting FCM registration token**
``` //getting token for default project FirebaseMessaging.getInstance().token .addOnCompleteListener { //handle token } //getting token for additional project val messaging = FirebaseApp.getInstance("other").get(FirebaseMessaging::class.java) messaging.token.addOnCompleteListener { //handle token } ```
### Security processes overview This document contains short information about security mechanisms used by SDK. Only high-level functions are described, without technical specifications. Security processes were designed to protect its assets, and ensure that the application using our product is installed on a safe environment. SDK security mechanism starts just after initialisation of library. Because of process optimalization part of checks are made only once, other are called periodically. **Process check** Implementation of checking application process is one of many methods that SDK uses to protect itself from hooking tools. It is based on validating app\_process file, checking if it was not manipulated, or corrupted. Many popular hooking tools used nowadays uses that method to upload its hooks, modules, or cloaks over adding root access. Validating that file helps in analysis potential threats from hazardous software, and even checking root acces. **Root check** Checking root access is one of SDK most important security processes. SDK is analysing application enviromnent in following ways: - Searching for harmful binaries: SDK analyses device in search for commonly known binaries indicating that device is rooted. Additionally in this step there are checked some binaries connected to hooking tools. - Checking system partitions permissions: SDK validates if some paths(commonly connected with root access), along with some common system directories are writtable on specific partition. - Validating installed packages : SDK analyses installed application on device in search for apps known to be connected with root access, apps requiring root, and root cloak apps. Android 11 introduced some changes reducing visibility of other packages installed on device. To keep checking harmful application there is added additional android permission: QUERY\_ALL\_PACKAGES - Checking rom settings: Analyses device rom properties, to search for flags set on rooted devices. - Checking su existance: Checks is *su* directory accessible in some common paths. **Emulator check** SDK validates application installment device by analyzing its properties and searching for evidences indicating that device is emulator. **Other packages check** Searches for well known applications connected with harmful hooking tools. Especially aimed into finding evidences of *magisk*. **Debug check** Simple check is debugger connected, based on OS properties. Used only in *release* version. **SafetyNet Api - deprecated from version 2.3.17** API tool used for protecting application from tampering, harmful applications, and validating device OS. It availability depends on project configuration. Usage of this process is configured od server side. If end application already performs this process it could be disabled during project configuration. **Play Integrity API** Due to Safetynet Attestation API planned deprecation it's replaced by Play Integrity API in Mobile DC version 2.13.7. API tool used for protecting application from tampering, harmful applications, and validating device OS. It availability depends on project configuration. Usage of this process is configured od server side. If end application already performs this process it could be disabled during project configuration. When used, Play Integrity API must be enabled Google Play Developer Console - [https://developer.android.com/google/play/integrity/setup#enable-responses](https://developer.android.com/google/play/integrity/setup#enable-responses). **Error codes handling in application** Table describes error codes which could be handled on application side with message to user about possible problem. Other error codes cannot be handled on application side.
**Code****Meaning**
80a1Device is rooted
80b1SDK cannot be used on emulator
811aUser has installed some harmful application on device
8a9bUser has attached debugger during SDK usage
### Application Isolated Process **Overview** Starting from Mobile DC SDK version 2.4.3 SDK provides additional security checks which could be enabled in [setup.](https://wiki.verestro.com/pages/viewpage.action?pageId=67340696) method using "withOptionalDeveloperOptions" and enableAdditionalSecurityChecks parameter. For some security processes SDK need to start services marked as *isolatedProcess* to ensure more security by splitting application from a security layer. It may cause problems with initialize Application as this service will run under a special process that is isolated from the rest of the system and has no permissions of its own. To avoid problems, check if application start from isolated process and do not invoke any additional action in your Application::onCreate. **Sample implementation**
``` //Mobile DC setup configuration for enableAdditionalSecurityChecks val developerOptions = DeveloperOptions() developerOptions.enableAdditionalSecurityChecks = true MobileDcApiConfigurationBuilder() // other require configuration .withOptionalDeveloperOptions(developerOptions) //Sample Application declaration for handing isolated process class SampleApplication : Application { override fun onCreate() { super.onCreate() if (isIsolatedProcess()) { return } //sample methods called in application startKoin() initializeMobileDcModule() initUcpModule() initFirebase() //other methods.. } private fun isIsolatedProcess(): Boolean { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { android.os.Process.isIsolated() } else { try { val activityManager = getSystemService(ACTIVITY_SERVICE) as ActivityManager activityManager.runningAppProcesses false } catch (securityException: SecurityException) { securityException.message?.contains("isolated", true) ?: false } catch (exception: Exception) { false } } } } ```
This functionality is introduced to protect against magisk tool. Magisk gives root access using daemon, which starts with system booting, with unrestricted SELinux context. When specific application needs access to /su it connects to daemon unix socket, process of granting access access is managed with Magisk Manager application. Magisk Hide function hides /sbin paths for specific process, what obscures magisk presence in /proc/pid/mounts. This problems is solved with isolated processes introduced in android 4.1. They are started with new, fresh SELinux context without any permissions, what keeps magisk from removing it paths with /sbin. From this process view there is possibility to check mounted paths and find evidences of magisk presence. ### Data signing and encryption #### Configuration **Signing Data Configuration** Signature will be verified using public key certificate which was signed by preconfigured Root CA. DN from the certificate will be also validated. Root CA and DN will be set during onboarding. Client has two options: - provide Root CA and DN of the public key certificate for the private key which already has and use this private key for signing data.

DN cannot change during certificate renewals and all intermediate certificates should be placed in JWT

- generate csr where `CN=Signature-${uniqueClientName}`. Csr will be signed by uPaid. Client needs to use private key for signing from key pair used to generate csr. **Encryption Data Configuration** If the client decide to encrypt data, public key certificate from RSA 2048 should be set during onboarding. Public key certificate can be self-signed. **Signed Data Verification** Some methods requires signed data verification on client side. Public key certificate from RSA 2048 will be provided during onboarding and should be used for signature validation. #### Data Encryption

Some data like Token Verification Code can be encrypted using JWE per RFC 7516.

Configured(see *Encrypting Data Configuration* *in Confoguration chapter*) public key certificate will be used to encrypt CEK(Content Encryption Key). **Algorithm used for encryption:**
**JWE header****Name****Description**
alg RSA-OAEP-256 Cryptographic algorithm used to encrypt CEK
enc A256GCM Identifies the content encryption algorithm used to perform authenticated encryption
Payload of the JWE will be json formatted object. Client needs to perform decryption with private key using standard JWE library. **Sample code which shows how to decrypt JWE for given encryptedData and privateKey**:
``` class RsaJweDecrypter { @Throws(Exception::class) fun decrypt(encryptedData: String, privateKey: PrivateKey): ByteArray { val parse = JWEObject.parse(encryptedData) parse.decrypt(RSADecrypter(privateKey)) return parse.payload.toBytes() } } ```
#### Data Signing

Some fields are signed using JWT per RFC 7519.

Data signing should be done on **server side**.

JWTs are composed of three sections: a header, a payload (containing a claim set), and a signature. The header and payload are JSON objects, which are serialized to UTF-8 bytes, then encoded using base64url encoding. The JWT’s header, payload, and signature are concatenated with periods (.). As a result, a JWT typically takes the following form:
``` {Base64url encoded header}.{Base64url encoded payload}.{Base64url encoded signature} ```
Object fields should be placed as claims in the token. Moreover there are some additional required claims that are needed to protect against replay attack:
**Name****Description**
iat The time at which the JWT was issued. UNIX Epoch timestamp, in seconds
jti JWT ID - unique identifier for the JWT
JWT tokens have TTL which is validated against "issued at" time from claims (iat). TTL is 10 minutes. JWT tokens should be signed using private key from the RSA 2048 key pair (see *Signing Data Configuration in Configuration chapter*). **JWT tokens must have additional header:**
**Name****Description**
x5c Parameter contains the X.509 certificates chain ([RFC7515#section-4.1.6](https://tools.ietf.org/html/rfc7515#section-4.1.6))
This chain will be validated against preconfigured Root CA. DN from the public key certificate(from key pair which private key was used for signing) will be also validated (See *Signing Data Configuration in Configuration chapter*). **Sample code which shows how to build JWT for given claims, certificates and private key:**
``` class JwtGenerator { fun generate( jwtClaimsSet: JWTClaimsSet, certificates: List, privateKey: PrivateKey ): String { val claims = buildFinalClaims(jwtClaimsSet) val certChains = certificates .map { it.encoded } .map { Base64.encode(it) } val jwsHeader = JWSHeader.Builder(JWSAlgorithm.RS256) .x509CertChain(certChains) .build() val signer = RSASSASigner(privateKey) val jwsObject = JWSObject( jwsHeader, Payload(claims.toJSONObject()) ) jwsObject.sign(signer) return jwsObject.serialize() } private fun buildFinalClaims(jwtClaimsSet: JWTClaimsSet): JWTClaimsSet { val epochSeconds = Instant.now().epochSecond return JWTClaimsSet .Builder(jwtClaimsSet) .claim("iat", epochSeconds) .jwtID(UUID.randomUUID().toString()) .build() } } ```
#### #### Signed data verification

Some fields are signed on Wallet Server using JWT per RFC 7519.

Wallet Server signs some data in response and signature has to be verified before this data are used. Data are signed using JWT per RFC 7519. JWTs are composed of three sections: a header, a payload (containing a claim set) and a signature. The header and payload are JSON objects, which are serialized to UTF-8 bytes, then encoded using base64url encoding. The JWT's header, payload, and signature are concatenated with periods (.). As a result, a JWT typically takes the following form:
``` {Base64url encoded header}.{Base64url encoded payload}.{Base64url encoded signature} ```
Specific object fields are placed as claims in the JWT token. Moreover there are some additional claims that are added to the JWT token to protect against replay attack:
**Name****Description**
iat The time at which the JWT was issued. UNIX Epoch timestamp, in seconds
jti JWT ID - unique identifier for the JWT
JWT tokens are signed using private key from the RSA 2048 key pair. Public key certificate will be shared as part of configuration of given project and public key should be used for signature validation. JWT tokens have additional header:
**Name****Description**
kid fingerprint of public key which's corresponding private key was used to sign data calculated as sha1Hex(publicKeyBytes)
**Sample code which shows how to verify signed JWT:**
``` class JWTVerifier { fun verify( signedData: String, rsaPublicKey: RSAPublicKey, iatToleranceSeconds: Long ): JWTClaimsSet { val signedJWT = SignedJWT.parse(signedData) val signatureResult = signedJWT.verify(RSASSAVerifier(rsaPublicKey)) if (!signatureResult) { throw ValidationException("Invalid signature") } val jwtClaimsSet = signedJWT.getJWTClaimsSet() //optionally check iat with tolerance val isIatInAllowedTimeRange = jwtClaimsSet .getIssueTime() .toInstant() .plusSeconds(iatToleranceSeconds) .isAfter(Instant.now()) if (!isIatInAllowedTimeRange) { throw ValidationException("Signed JWT expired") } return jwtClaimsSet } } ```
### APK Certificate #### About APK certificate Verestro provides mechanism which ensures that authorized entities using Verestro SDKs. To achieve that apk certificate needs to configured during onboarding. Apk Certificate is binded to given client id, if customer uses many applications then many apk certificates digest should be provided and for each client id will be given by Verestro. #### Calculate APK certificate digest You can sign your application using self managed key, or let Google Play sign using Google Play managed keys: - APK or Bundle signing key (aka "upload key"). - Google Play signing key (optional, may be enabled and configured in Google Play Console). If you update key, you must follow steps below again and provide key to representative uPaid person. Please check your installation package and follow the outlined steps. #### Using own APK Signing Key When signing apk in android studio only, please follow the steps below: 1\. Convert java keystore (eg. cert.jks) used to sign APK to p12 format using following command:
``` keytool -importkeystore -srckeystore cert.jks -destkeystore cert.p12 -srcstoretype jks -deststoretype pkcs12 ```
2\. Convert obtained p12 file (eg. cert.p12) to pem format using following command:
``` openssl pkcs12 -nokeys -in cert.p12 -out cert.pem ```
#### Using Google Play Signing Key When signing application in Google Play console(whenever you uploaded own key, or used one that was automatically generated by Google), please follow steps below: 1. Add .apk or .aab file in google play console. 2. Select "Let Google create and manage my app signing key (recommended)" and press Continue. [![google app sign key.png](https://developer.verestro.com/uploads/images/gallery/2022-11/scaled-1680-/google-app-sign-key.png)](https://developer.verestro.com/uploads/images/gallery/2022-11/google-app-sign-key.png) 3. In the application panel in the menu look for release management option. 4. Select app signing section. [![app_signing.png](https://developer.verestro.com/uploads/images/gallery/2022-11/scaled-1680-/app-signing.png)](https://developer.verestro.com/uploads/images/gallery/2022-11/app-signing.png) 5. Download the certificate from App signing certificate section. [![app sing cert.png](https://developer.verestro.com/uploads/images/gallery/2022-11/scaled-1680-/app-sing-cert.png)](https://developer.verestro.com/uploads/images/gallery/2022-11/app-sing-cert.png) 6. Convert downloaded certificate from der to pem format using following command:
``` openssl x509 -inform der -in deployment_cert.der -out certificate.pem ```
### Recommended MPA data protection mechanisms - Code obfuscation: Code obfuscation is basic, and one of the most efficient application protection mechanism. Obfuscating code saves your app from static code analysis, exploring your code in search of vulnerabilities, that can be used by hooking software. There are many tools used for obfuscation nowadays, the most popular are proguard and its successor - R8. If you are using Kotlin in your project, R8 is a better option for you. It is also important to keep app architecture supporting obfuscation, using obfuscation tools is as simple as your architecture is adjusted to it. - Disable logs & turning off debugging: It is very important to remember turning off logging data and disable debugging in your production application. Data printed in logs in development process should never be available in release application. It is recommended to manage printing it from one place, to not 'forget' removing every single of them. - Input data validation: Input data should be validated on every level of app structure, it reduces risk of processing some unwanted, or even harmful data. It is recommended to clean sensitive data that is no longer useful, we advise to not use string to keep it. String is immutable, data stored in it can later be accessed by dumping application memory. We recommend using **char\[\]**, and overwriting it when it is no longer useful. - Prevent taking screenshot: We recommend adding a mechanism that prevents taking screenshots, and recording your application. It protects you from harmful applications getting users inputted data. - Prevent copy/paste : Input taking sensitive data such as user password should not have the ability to copying and pasting in it. Storing it in clipboard expose it for copying, or modifying by harmful applications, even if it was initially encrypted it is plaintext when the user copies it. - Prevent screen overlay: It is recommended to protect MPA from applications that have the possibility to overlay it. Not securing it may result with recording user data. - Checking the installer: MPA should implement a mechanism that will check installer of application. It should check if the application is downloaded from Google Play, preventing it from possibility of tampering installation binary. - Checksum mechanism: Implementing checking checksum mechanism is a very efficient way to check if your application was not tampered. It should compare checksum of your application, prepared after generating app with data send by your app after installing it on device. It bases on the fact that every generated application have different checksum, comparing it can ensure you that your server is communicating with the app released by you. - Removal redundant permissions: It is important to keep in your app only used permissions. You should not give your application access to components, that it not requires. - Network security configuration: MPA should use network security configuration application customize their network security settings(for example protection application from usage of cleartext traffic) in declarative configuration file without modifying app code. ### Models #### LimitedResourceInfo
**Parameter****Type****Description**
xRateLimitLimitIntLimit of requests until resource will be locked
xRateLimitRemainingIntRemaining amount of requests
retryAfterIntSeconds until lock expires
xRateLimitResetLongLock expiration timestamp - epoch in seconds
### External libraries The SDK uses several external Apache 2.0 libraries: - com.nimbusds:nimbus-jose-jwt - commons-codec:commons-codec - com.fasterxml.jackson.core:jackson-core - com.fasterxml.jackson.core:jackson-annotations - com.fasterxml.jackson.core:jackson-databind - com.fasterxml.jackson.module:jackson-module-kotlin - io.insert-koin:koin-android - io.reactivex.rxjava2:rxjava - io.reactivex.rxjava2:rxandroid - com.squareup.retrofit2:adapter-rxjava2 - com.squareup.retrofit2:retrofit - com.squareup.retrofit2:converter - com.squareup.okhttp3:logging - com.squareup.okhttp3:okhttp ## MDC SDK Setup ### Setup

Asynchronous. Offline. Mobile DC initialization method. Contains all necessary data to configure SDK.

Should be called at very beginning of application lifecycle. For example in Android Application::onCreate method.

**Note:** Please be aware to use this method before usage of any MobileDC methods or another Verestro product.

#### Input Mobile DC different configuration options depending on SKD usage. Configuration is provided by builder in facade method named *setup*. All builder methods without *optional* keyword in method name are required. **Available configurations methods:** - setup(MobileDcCoreConfiguration) - setup(MobileDcApiConfiguration)

**SDK Event Listeners - errors catching**

The application should prevent throwing exceptions in MDC SDK Event Listeners described below as it could cause breaking process in SDK.

In case of error in application event listener implementation SDK runs this code in try-catch block.

**MobileDcCoreConfiguration** Used when usage of uPaid product doesn't require Verestro backend system (f.e. UCP with External Wallet Server).
**Method****Parameter****Description****Validation conditions**
withApplicationContextContextApplication contextNot empty
withWalletSecurityEventListenerWalletSecurityEventListener Global listener for security events Not empty
withOptionalLoggerEventsLoggerHandler for secure logging of sdk events
withOptionalDeveloperOptionsDeveloperOptions Additional options for developers
**MobileDcApiConfiguration** Used when applicaton use Mobile DC API for user data management.
**Method****Parameter****Description****Validation conditions**
withApplicationContextContextApplication contextNot null
withMobileDcConnection Configuration MobileDcConnection Configuration Mobile DC API connection configuration delivered by uPaid Not empty
withWalletSecurityEventListenerWalletSecurityEventListener Global listener for security events Not empty
withOptionalWalletPin ConfigurationMobileDcWalletPin ConfigurationWallet Pin configuration in SDK
withOptionalLoggerEventsLoggerHandler for secure logging of sdk events
withOptionalDeveloperOptionsDeveloperOptionsAdditional options for developers
withOptionalCloudMessaging Configuration MobileDcCloudMessaging Configuration Interface for providing cloud messaging configuration like actual registration token
**MobileDcConnectionConfiguration**
**Parameter****Type****Description****Validation conditions**
urlStringUrl for mobile DC environment in which SDK connect. Depending on the deployment model the Wallet Server can be deployed on the Customer infrastructure or provided by uPaid. Different for development and production environment. For more details please contact uPaid representative. Not empty
pinningCertificatesList<String>List of public key certificate in PEM associated with host server. Certificate is used for certificate pinning during connection to Wallet Server. Certificate is associated with the Wallet Server and like the url its value depends on the deployment model. When used services hosted on uPaid side please contact uPaid representative. Not empty
clientIdStringEach customer has a unique client id it's different for development and production environment. ClientId should be provided by uPaid representative. Not empty
**MobileDcWalletPinConfiguration**
**Parameter****Type****Description****Validation conditions**
pinFailCountIntNumber of possible fails in offline pin verification Greater then 0
**WalletSecurityEventListener**
**Method** **Parameters****Description**
onSecurityIssueAppearedEventSecurityIssueAppeared (tag: Int, code: Int, message:String) Information about security issue. Due to security requirements this message isn’t readable for user When using setup(MobileDcApiConfiguration) SDK reports event instantly to server (when internet is available). Could be also catched on application side and reported by client. Some error codes could be properly handled in application [Security processes overview](https://wiki.verestro.com/display/UCP/Security+processes+overview)
**EventsLogger**
**Method** **Parameters****Description**
onEventonEvent(eventId:Int)Callback to trace list of events that occured in SDK (those are secure aliases - event as Integer). You can collect 'em in ordered list and store to be accesible in case of errors/exceptions.
**DeveloperOptions**
**Parameter****Type****Description**
allowDebugBoolean Determine AndroidManifest *android:debuggable* state in *<application>*scope. When configured as true SDK verifies combination of SDK production(without -debug) version and *android:debuggable*=true.
enableAdditionalSecurityChecksBooleanEnables additional security checks in application required during EMV Security Evaluation. Enabling requires additional action on application side, refer to [Application Isolated Process](https://wiki.verestro.com/display/UCP/Application+Isolated+Process) to get more details. Added in version 2.4.3.
enableCodeObfuscationCheckBooleanEnable additional check if application obfuscates SDK facade classes. Default value is false.
**MobileDcCloudMessagingConfiguration**
**Parameter** **Type****Description**
cloudMessagingRegistrationTokenCloudMessagingRegistrationProviderProvides information abour Cloud Messaging registrationtoken like FCM
**Method** **Parameters****Description**
getRegistrationToken-Gets actual FCM registration token from application. Used to device registration in RNS and SSE service.
**CloudMessagingRegistrationToken**
**Parameter****Type****Description**
typeCloudMessagingType Mandatory. One of: \[FCM\]. FCM - Firebase Cloud Messaging
tokenStringRegistaration token for push notifications
**Sample** Initialization for MobileDcCoreConfiguration (without Wallet Server).
``` var eventsTrace = arrayListOf()//make use of this in case of error/failure/unexpected behaviour to retrace sdk internal processes val mobileDcCoreConfiguration = MobileDcCoreConfiguration.create( MobileDcCoreConfigurationBuilder() .withApplicationContext(this) .withWalletSecurityEventListener(object : WalletSecurityEventListener { override fun onSecurityIssueAppeared(event: EventSecurityIssueAppeared) { //eg. show security screen or toast with details from event object //all data collected by SDK will be removed //Clearing application data in context of SDK is recommended } }) .withOptionalLogger(object : EventsLogger { override fun onEvent(eventId: Int) { eventsTrace.add(eventId) } }) .withOptionalDeveloperOptions(DeveloperOptions().apply { allowDebug = false enableAdditionalSecurityChecks = true enableCodeObfuscationCheck = true }) ) MobileDcApiKotlin.setup(mobileDcCoreConfiguration) ```
Initialization for MobileDcApiConfiguration.
``` class MyAppMobileDcConnectionConfig : MobileDcConnectionConfiguration { override val clientId: String = "clientId" override val url: String = "https://subdomain.domain.com/endpoint" override val pinningCertificates: List = listOf(certificatePublicKeyInPemFormat) } class MyAppMobileDcWalletPinConfig : MobileDcWalletPinConfiguration { override val pinFailCount: Int = 3 } var eventsTrace = arrayListOf()//make use of this in case of error/failure/unexpected behaviuour to retrace sdk internal processes val mobileDcApiConfiguration = MobileDcApiConfiguration.create( MobileDcApiConfigurationBuilder() .withApplicationContext(this) .withMobileDcConnectionConfiguration(MyAppMobileDcConnectionConfig()) .withOptionalWalletPinConfiguration(MyAppMobileDcWalletPinConfig()) .withWalletSecurityEventListener(object : WalletSecurityEventListener { override fun onSecurityIssueAppeared(event: EventSecurityIssueAppeared) { //eg. show security screen or toast with details from event object //all data collected by SDK will be removed //Clearing application data in context of SDK is recommended } }) .withOptionalLogger(object : EventsLogger { override fun onEvent(eventId: Int) { eventsTrace.add(eventId) } }) .withOptionalDeveloperOptions(DeveloperOptions().apply { allowDebug = false enableAdditionalSecurityChecks = true enableCodeObfuscationCheck = true }) .withOptionalCloudMessagingConfiguration( object : MobileDcCloudMessagingConfiguration { override val cloudMessagingRegistrationTokenProvider = object : MobileDcCloudMessagingInfoProvider { override fun getRegistrationToken(): CloudMessagingRegistrationToken? { return CloudMessagingRegistrationToken( CloudMessagingType.FCM, getFCMToken() //implement blocking get FCM token ) } } }) ) MobileDcApiKotlin.setup(mobileDcApiConfiguration) ```
Additional isolated process check, read more: **Application Isolated Process**
``` class App : Application() { override fun onCreate() { super.onCreate() if (isIsolatedProcess()) { return } //call all required methods } } ```
## Address domain ### addAddress

Asynchronous. Online.

Adds new address with given parameters.

**Input** **AddAddress**
ParameterTypeDescriptionValidation conditions
streetCharArrayStreet -
numberCharArrayNumber -
apartmentCharArrayApartment -
cityCharArray City -
isBillingBooleanIs invoice address -
isShippingBooleanIs Shipping address -
zipCodeCharArrayZip code -
countryIdIntCountry identifier -
vatNoCharArrayVat number -
companyNameCharArrayCompany name -
firstNameCharArrayFirst name -
lastNameCharArrayLast name -
provinceCharArrayProvince -
districtCharArrayDistrict -
additionalCharArray(Optional) Additional field -
**Output**

Success with Long value as addressId / failure callback.

**Sample**
``` fun addAdress(addAddress: AddAddress) { mobileDcApi .addressesService .addAddress(addAddress, { addressId -> // Address added }, { // Something went wrong // Check exceptions described in Error handling chapter }) } ```
### getAll

Asynchronous. Online.

Gets all addresses for the current user.

**Input**

No input parameters.

**Output**

Success callback with list of user addresses.

**Parameter****Type****Description**
addressesList <Address>List of user addresses
**Address**
**Parameter****Type****Description**
idIntId of the address
streetCharArrayStreet
numberCharArrayNumber
apartmentCharArrayApartment
cityCharArray City
isBillingBooleanIs invoice address
isShippingBooleanIs Shipping address
zipCodeCharArrayZip code
countryCountryCountry
vatNoCharArrayVat number
companyNameCharArrayCompany name
firstNameCharArrayFirst name
lastNameCharArrayLast name
provinceCharArrayProvince
districtCharArrayDistrict
additionalCharArrayAdditional field
**Country**
**Parameter** **Type** **Description**
id Int Id of the country
code CharArray Country code
currency CharArray Currency code
currencyNumeric CharArray Numeric currency code
prefix CharArray Prefix telephone number for a given country
regexp CharArray The phone number validation rule for a given country
name CharArray The currency's name
currencyName CharArray Country
language CharArray Official language
**Sample**
``` fun getAll() { mobileDcApi .addressesService .getAll({ // List of addresses }, { throwable -> // Something went wrong // Check exceptions described in Error handling chapter }) } ```
### updateAddress

Asynchronous. Online.

Update address for the current id.

**Input**
**Parameter****Type****Description**
updateAddressUpdateAddressAn object containing address data to update
**UpdateAddress**
**Parameter****Type****Description**
addressIdLongId of the address
streetCharArrayStreet
numberCharArrayNumber
apartmentCharArrayApartment
cityCharArrayCity
isBilling BooleanIs invoice address
isShippingBooleanIs shipping address
zipCodeCharArrayZip code
countryIdIntCountry identifier
vatNoCharArrayVat number
companyNameCharArrayCompany Name
firstNameCharArrayFirst name
lastNameCharArrayLast name
provinceCharArrayProvince
districtCharArrayDistrict
additionalFieldCharArrayAdditional filed
**Output**

Success / Failure callback.

**Sample**
``` private fun updateAddress(updateAddress: UpdateAddress) { mobileDcApi .addressesService .updateAddress(updateAddress, { //address updated successfully }, { throwable -> // Something went wrong, maybe user data was incorrect // Check exceptions described in Error handling chapter }) } ```
### deleteAddress

Method for delete user address with given address id.

**Input**
**Parameter****Type****Description**
addressIdLong(Required) Unique address id
**Output**

Success callback/ Failure callback.

**Sample**
``` fun deleteAddress(addressId: Long) { mobileDcApi .addressesService .deleteAddress(addressId, { //Success, address deleted }, { //Something went wrong //Check exceptions described in Error handling chapter }) } ```
### ## User domain ### addUser

Asynchronous. Online.

Creates new user wallet account with given parameters.

**Input** NewUser model is required, but most of it's fields are optional. Fields requirement depends on product integration process.
**Parameter**
**Type**
**Description**
**Validation coditions**
newUserNewUserAn object containing user data(Required)
NewUser object contains following fields:
**Parameter**
**Type**
**Description**
**Validation conditions**
phoneCharArrayUser's phone number Phone with country prefix. For pl: 48500500500
emailCharArrayUser's email addressEmail format if any value passed
firstNameCharArrayUser's first name
lastNameCharArrayUser's last name
walletPinCharArrayUser's wallet pin4 to 8 digits if passed
passwordCharArrayUser's passwordPassword should be composed of at least 8 characters and include at least 3 out of the following 4 categories: upper-case letter, lower-case letter, special character and digit
acceptedMarketingBooleanTrue if user accepted marketing agreement, false otherwise-
invitationCodeCharArrayInvitation code used in a specific server configuration(Conditional/Optional) - depends on specific server configuration
nipStringTaxpayer identification numberNot empty if passed
**Output**

Success / failure callback.

**Sample**
`fun addUser(newUser: NewUser) {`
`    ``mobileDcApi`
`        ``.userService`
`        ``.addUser(newUser, {`
`            ``//new user is added successfully`
`        ``}, { throwable ->`
`            ``// Something went wrong, maybe user data was incorrect`
`            ``// Check exceptions described in Error handling chapter`
`        ``})`
`}`
### addUser (deprecated)

Asynchronous. Online.

Creates new user wallet account with given parameters.

**Input** Most of fields are optional. Fields requirement depends on product integration process.
**Parameter****Type****Description****Validation conditions**
phoneCharArrayUser's phone number Phone with country prefix. For pl: 48500500500
emailCharArrayUser's email addressEmail format if any value passed
firstNameCharArrayUser's first name
lastNameCharArrayUser's last name
walletPinCharArrayUser's wallet pin4 to 8 digits if passed
passwordCharArrayUser's passwordPassword should be composed of at least 8 characters and include at least 3 out of the following 4 categories: upper-case letter, lower-case letter, special character and digit
acceptedMarketingBooleanTrue if user accepted marketing agreement, false otherwise-
**Output**

Success / failure callback.

### addUserWithIban

Asynchronous. Online.

Creates new user wallet account if not exist with IBAN in Mobile DC backend.

When user already exist calling this method will be also finished with success.

**Input**
**Parameter****Type****Description****Validation conditions**
signedAccountInfoStringSigned AccountInfo per RFC 7519 generated on Client server side Instruction how to sign data with JWT can be found in *[Data signing and encryption](https://wiki.verestro.com/display/UCP/Data+signing+and+encryption)* chapter Not empty
**AccountInfo**
**Parameter****Type****Description****Validation conditions**
userIdStringExternal user id given by the client Not empty
ibanStringBank Account NumberNot empty
countryCodeStringThe country of the financial account Expressed as a 3-letter (alpha-3 country code as defined in ISO 3166-1 Not empty
**Output**

Success callback. Called when new user is created or already exist with passed input data.

**Parameter****Type****Description**
ibanIdStringHash (sha256) of provided IBAN

Failure callback.

**Sample**
``` class SignedAccountInfo { fun generate() { val claims = JWTClaimsSet.Builder() .claim("userId", "externalUserId") .claim("iban", "IN15HIND23467433866365") .claim("countryCode", "IND") .build() val signedAccountInfo = JwtGenerator.generate(claims, certificates, privateKey) // ... } } ```
``` private fun addUserWithIban() { val signedAccountInfo: String = getSignedAccountInfo() mobileDcApi .userService .addUserWithIban(signedAccountInfo, { ibanId -> //user already exist or was added with selected iban }, { //failure, check exceptions, maybe signedAccountInfo is wrong? }) } ```
### updateUser

Asynchronous. Online.

Update user wallet account with given parameters.

Most of it's fields are optional. Fields requirement depends on product integration process.

**Input**
**Parameter****Type****Description****Validation coditions**
updateUserUpdateUserAn object containing user data to update(Required)
**UpdateUser**
**Parameter****Type****Description**
firstNameCharArrayUser's first name
lastNameCharArrayUser's last name
acceptedMarketingBooleanTrue if user accepted marketing agreement, false otherwise
acceptedRegulationsBooleanAccepted regulations agreement
acceptedMarketingReceivingBooleanAccepted marketing consent
**Output**

Success / failure callback.

**Sample**
``` fun updateUser(updateUser: UpdateUser) { mobileDcApi .userService .updateUser(updateUser, { //user updated successfully }, { throwable -> // Something went wrong, maybe user data was incorrect // Check exceptions described in Error handling chapter }) } ```
### getUser

Asynchronous. Online.

Get data of current user.

**Input**

No input parameters.

**Output**

Success callback with User model.

**Parameter****Type****Description**
userUserUser data
User contains following fields:
**Parameter****Type****Description**
userIdLongId of registered user
firstNameCharArrayFirst name of the user (required depending on server configuration)
lastNameCharArrayLast name of the user (required depending on server configuration)
phoneCharArrayPhone with country prefix. For pl: 48500500500 (required depending on server configuration)
emailCharArrayEmail of the user (required depending on server configuration)
birthDateCharArrayBirth date in format yyyy-MM-dd
genderCharArrayGender: \[M, F\]
acceptTosCharArrayDate when user accepted regulations in format yyyy-MM-dd hh:mm:ss
acceptMarketingCharArrayDate when user accepted marketing info in format yyyy-MM-dd hh:mm:ss
isLockedBooleanTrue if user is locked, false otherwise
deactivatedBooleanTrue if user is deactivated, false otherwise
statusCharArrayUser status: \[ACTIVE, LOCKED, DEACTIVATED\]
verifiedBooleanTrue if user is verified, false otherwise
kycCharArrayUser’s KYC verification status, one of: \[SUCCESS, REJECTED, IN\_PROGRESS\]
createdCharArrayDate of creation user in DB
failCountIntNumber of failed authentication attempts
hasSetPasswordBooleanTrue if user has password set, false otherwise
lastPasswordChangeCharArrayLast password change in format yyyy-MM-dd
lockToCharArrayTime for which user is locked in format Y-m-d H:i:s
lastActivityCharArrayData of user last activity in format yyyy-MM-dd hh:mm:ss
countryCountryCountry object
acceptMarketingReceivingCharArrayDate when user accepted marketing consent in format yyyy-MM-dd hh:mm:ss
Country contains following fields.
**Field****Type****Description**
idLongCountry identifier
codeCharArrayCountry code in accordance with the ISO 3166-2 standard
prefixCharArrayPrefix telephone number for a given country
nameCharArrayCountry name

Failure callback.

**Sample**
``` fun getUser() { mobileDcApi.userService .getUser({ user -> // Getting user went successfully showUser(user) }, { throwable -> // Something went wrong // Check exceptions described in error handling chapter }) } ```
### finalizeUserRegistration

Asynchronous. Online.

Activate user account by finalizing registration process with SMS code sent to the phone number provided during new user wallet account creation.

**Input**
**Parameter****Type****Description****Validation conditions**
otpCharArrayOne time password (sent via SMS as a result of successful new user wallet account creation)Not empty
**Output**

Success / failure callback.

**Sample**
``` fun finalizeUserRegistration(otp: CharArray) { mobileDcApi .userService .finalizeUserRegistration(otp, { // User wallet account was successfully activated }, { throwable -> // Something went wrong. // Check exceptions described in error handling chapter }) } ```
### authenticateByPin

Asynchronous. Offline.

Authenticates user locally after providing correct pin.

Provide method to verify user without connection into Mobile DC.

**Input**
**Parameter****Type****Description****Validation conditions**
pinCharArrayWallet Pin created during user registration process associated with user account. (see: [addUser (deprecated)](https://wiki.verestro.com/pages/viewpage.action?pageId=67340747)) Not empty.
**Output**

Success / failure callback.

**Sample**
``` fun authenticateByPin(mobileDcApi: MobileDcApiKotlin, pin: CharArray) { //Wallet Pin created during user registration process associated with user account mobileDcApi .userService .authenticateByPin(pin, { //user is verified }, { throwable -> // Something went wrong, maybe pin is incorrect? // Check exceptions described in Error handling chapter }) } ```
### isBiometricAuthenticationEnabled

Asynchronous. Offline.

Method that check if biometric authentication is enabled.

**Note:** Authentication could be disabled by system when Android Keystore state changed (eg. User disabled screen lock or add new authentication method).

State of biometrics should be checked before every biometrics authentication usage.

**Input** No input parameters **Output**

Success callback with status of authentication or failure callback.

**Sample**
``` fun isBiometricAuthenticationEnabled() { mobileDcApi .userService .isBiometricAuthenticationEnabled({ isBiometricEnabled -> if (isBiometricEnabled) { // Biometric authentication is enabled, process startBiometricAuthentication method } else { // Biometric authentication is disabled, use enableBiometricAuthentication } }, { throwable -> // Something went wrong // Check exceptions }) } ```
### enableBiometricAuthentication

Asynchronous. Online.

Method for enabling device level authentication and updating biometric public key.

To perform this method device must have set PIN, pattern or password. To check these use KeyguardManager.

**Input**
**Parameter****Type****Description****Validation conditions**
userNameCharArrayCurrent usernameNot empty
passwordCharArrayCurrent passwordNot empty
biometricAuthTypeBiometricAuthType (BIOMETRIC\_ONLY, BIOMETRIC\_WITH\_ALTERNATIVE)Type of biometrics to enable during device pairing process.Not null
**Output**

Success / failure callback.

**Sample** ``` //KeyguardManager example keyguardManager = context.getSystemService(KEYGUARD_SERVICE) fun isDeviceSecure(): Boolean { return keyguardManager.isKeyguardSecure } //if isDeviceSecure return true device is safe and enableBiometricAuthentication method can be performed fun enableBiometricAuthentication(userName: CharArray, password: CharArray, biometricAuthType : BiometricAuthType) { mobileDcApi.userService .enableBiometricAuthentication(userName, password, biometricAuthType, { // Biometric authentication is enabled. Read startBiometricAuthentication description to authenticate user. }, { throwable -> // Something went wrong // Check exceptions described in Error handling chapter } ) } ``` ### disableBiometricAuthentication

Asynchronous. Offline.

Disable possibility to use biometric authentication.

**Input**
No input parameters.
**Output**
Success / failure callback.
**Sample**
``` fun disableBiometricAuthentication() { mobileDcApi .userService .disableBiometricAuthentication({ //Biometric authentication cannot be no longer used. Use enableBiometricAuthentication to enable it again }, { //Something went wrong //Check exceptions described in Error handling chapter }) } ```
### enableBiometricAuthenticationWithWalletPin

Asynchronous. Online.

Method for enabling device level authentication and updating biometric public key with Wallet Pin.

To perform this method device must have set PIN, pattern or password. To check these use KeyguardManager.

**Input**
**Parameter****Type****Description****Validation conditions**
walletPinCharArrayCurrent walletPinNot empty
biometricAuthTypeBiometricAuthType (BIOMETRIC\_ONLY, BIOMETRIC\_WITH\_ALTERNATIVE)Type of biometrics to enable during device pairing process.Not null
**Output**

Success / failure callback.

**Sample**
``` //KeyguardManager example keyguardManager = context.getSystemService(KEYGUARD_SERVICE) fun isDeviceSecure(): Boolean { return keyguardManager.isKeyguardSecure } //if isDeviceSecure return true device is safe and enableBiometricAuthenticationWithWalletPin method can be performed fun enableBiometricAuthenticationWithWalletPin(walletPin: CharArray, biometricAuthType : BiometricAuthType) { mobileDcApi.userService .enableBiometricAuthenticationWithWalletPin(walletPin, biometricAuthType, { // Biometric authentication is enabled. Read startBiometricAuthentication description to authenticate user. }, { throwable -> // Something went wrong // Check exceptions described in Error handling chapter } ) } ```
### startBiometricAuthentication

Asynchronous. Offline.

Create CryptoObject for biometric authentication.

Depends on usage of androidx/android support library an different CryptoObject can be provided by Android SDK.

**Input**
**Parameter****Type****Description****Validation conditions**
cryptoObjectTypeCryptoObjectTypeEnum that defines different types of CryptoObject BIOMETRIC\_PROMPT\_ANDROIDX - androidx/biometric/BiometricPrompt/CryptoObject, FINGERPRINT\_MANAGER\_COMPAT\_ANDROIDX - androidx/core/hardware/fingerprint/FingerprintManagerCompat/CryptoObject, FINGERPRINT\_MANAGER - android/hardware/fingerprint/FingerprintManager/CryptoObject, BIOMETRIC\_PROMPT - android/hardware/biometrics/BiometricPrompt/CryptoObject Not empty
**Output**

Success callback.

**Parameter****Type****Description**
resultBiometricAuthenticationData Object containing CryptoObject kept as Object.
BiometricAuthenticationData contains following field:
**Parameter****Type****Description**
cryptoObjectObjectWrapper class for crypto objects supported biometric authentication.

Failure callback.

**Sample** startBiometricAuthentication sample:
``` mobileDcApi .userService .startBiometricAuthentication(CryptoObjectType.BIOMETRIC_PROMPT_ANDROIDX) { // Creating Object for biometric authentication is done }, { // Something went wrong maybe: private key is not created or not authenticated // Check exceptions } ```
BiometricAuthenticationData should be used as parameter in [authenticateWithBiometric](https://wiki.verestro.com/display/UCP/authenticateWithBiometric) but application must cast cryptoObject parameter to CryptoObject. Cast to CryptoObject sample :
``` fun wrapToBiometricAuthenticationResult(biometricAuthenticationData: BiometricAuthenticationData): BiometricAuthenticationResult { val cryptoObject = biometricAuthenticationData.cryptoObject as CryptoObject //Casting to androidx/support version of CryptoObject return BiometricAuthenticationResult( cryptoObject.signature, cryptoObject.cipher, cryptoObject.mac ) } ```
Complete flow of authentication with biometric methods: Create your own custom view, which require to authenticate with biometric.
``` customViewForBiometricAuthentication = BiometricPrompt fun startAuthentication(){ mobileDcApi .userService .startBiometricAuthentication(CryptoObjectType.BIOMETRIC_PROMPT_ANDROIDX) { biometricAuthenticationData -> verifyAuthentication(wrapToBiometricAuthenticationResult(biometricAuthenticationData)) }, { // Something went wrong maybe: private key is not created or not authenticated // Check exceptions } } fun verifyAuthentication(biometricAuthenticationResult:BiometricAuthenticationResult){ mobileDcApi .userService .authenticateWithBiometric(biometricAuthenticationResult) { // success authentication is done }, { throwable -> // Something went wrong maybe private key is not authenticated? // Check exceptions } ) }  val biometricPrompt: BiometricPrompt = BiometricPrompt(activityFragment, executor, object : BiometricPrompt.AuthenticationCallback() { override fun onAuthenticationError( errorCode: Int, errString: CharSequence ) { super.onAuthenticationError(errorCode, errString) Toast.makeText(context,"Authentication error", Toast.LENGTH_SHORT).show() } override fun onAuthenticationSucceeded( result: BiometricPrompt.AuthenticationResult ) { super.onAuthenticationSucceeded(result) Toast.makeText( context, "Authentication succeeded!", Toast.LENGTH_SHORT).show() startAuthentication() } override fun onAuthenticationFailed() { super.onAuthenticationFailed() Toast.makeText( context, "Authentication failed", Toast.LENGTH_SHORT).show() } }) ```
### authenticateWithBiometric

Asynchronous. Offline.

Starts system biometric authentication.

After invoke system waits for a biometric authentication.

Method can throw BiometricVerificationException.

**Input**
**Parameter****Type****Description****Validation conditions**
biometricAuthenticationResultBiometricAuthenticationResultClass wrapper for biometric authentication result (Signature, Cipher, Mac) created in startBiometricAuthentication Not empty
**Output**

Success callback.

**Parameter****Type****Description**
resultAuthorizationResultObject containing verification details.
AuthorizationResult contains following fields:
ParameterTypeDescription
timestampLongInternal information for SDK.
signedTimestampByteArrayInternal information for SDK
errorMessageStringInternal information for SDK

Failure callback.

**Sample**
``` fun authenticateWithBiometrics(biometricAuthenticationResult: BiometricAuthenticationResult) { mobileDcApi .userService .authenticateWithBiometric(biometricAuthenticationResult, { authorizationResult -> // authentication with biometric is finished with success, use authorizationResult to loginBySignature }, { throwable -> // Something went wrong, was authentication passed? // Check exceptions }) } ```
### loginByTrustedIdentity

Asynchronous. Online.

Authenticates user in Mobile DC backend after providing trusted identity.

Creates / refreshes user session.

**Input**
ParameterTypeDescriptionValidation conditions
trustedIdentityStringTrusted identity generated by client Not empty
**TrustedIdentity**
ParameterTypeDescriptionValidation conditions
userIdStringExternal user id given by the client Not empty
**Output**

Success / failure callback.

**Sample** Sample code for *trustedIdentity* generation (see also *Data signing and encryption* chapter):
``` class TrustedIdentity { fun generate() { val claims = JWTClaimsSet.Builder() .claim("userId", "externalUserId") .build(); val trustedIdentity = JwtGenerator.generate(claims, certificates, privateKey); // ... } } ```
Usage of trustedIdentity in application:
``` fun loginByTrustedIdentity(mobileDcApi: MobileDcApiKotlin, trustedIdentity: String) { //where trustedIdentity should be generated by server and passed to mobile application mobileDcApi .userService .loginByTrustedIdentity(trustedIdentity, { //user is logged }, { throwable -> // Something went wrong, maybe trustedIdentity is wrong? // Check exceptions described in Error handling chapter }) } ```
### loginByPin

Asynchronous. Online.

Authenticates user in Mobile DC backend after providing correct pin.

Creates / refreshes user session.

**Input**
**Parameter****Type****Description****Validation conditions**
pinCharArrayWallet Pin created during user registration process associated with user account. (see: [addUser](https://wiki.upaid.pl/display/UCP/addUser)) Not empty.
**Output**

Success / failure callback.

**Sample**
``` fun loginByPin(mobileDcApi: MobileDcApiKotlin, pin: CharArray) { //Wallet Pin created during user registration process associated with user account mobileDcApi .userService .loginByPin(pin, { //user is logged }, { throwable -> // Something went wrong, maybe pin is incorrect? // Check exceptions described in Error handling chapter }) } ```
### loginBySignature

Asynchronous. Online.

Authenticates user in Mobile DC backend after local biometric authentication (startBiometricAuthentication and authenticateWithBiometric methods).

Creates / refreshes user session.

**Input**

**AuthorizationResult** provided in success callback from authenticateWithBiometric method.

**Output**

Success / failure callback.

**Sample**
``` fun loginBySignature(authorizationResult: AuthorizationResult) { mobileDcApi .userService .loginBySignature(authorizationResult, { // User is authenticated }, { throwable -> // Something went wrong // Check exceptions }) } ```
### changeWalletPin

Asynchronous. Online.

Changes user's wallet PIN with given parameters.

**Input**
**Parameter** **Type** **Description** **Validation conditions**
walletPinCharArrayCurrent wallet PIN. Has 4 or 8 digits.
newWalletPinCharArrayNew wallet PIN.Has 4 or 8 digits.
**Output**

Success / failure callback.

**Sample**
``` fun changeWalletPin(walletPin:CharArray, newWalletPin:CharArray) { mobileDcApi .userService .changeWalletPin(walletPin, newWalletPin, { //user's Wallet PIN is changed }, { throwable -> // Something went wrong, maybe current PIN is wrong? // Check exceptions described in Error handling chapter }) } ```
### resetWalletPin

Asynchronous. Online.

Resets wallet pin with given parameters.

**Input**
**Parameter****Type****Description****Validation conditions**
userLoginType UserTypeUser identifier type. One of: \[PHONE, EMAIL\] Not empty
userLoginCharArrayUser identifier. Depends on user identifier type (EMAIL or PHONE)Depends on user identifier type. For a phone number it's phone number with country prefix. For pl: 48500500500. For email it's a valid email
newWalletPinCharArrayNew user wallet pinOnly numbers with 4 to 8 digits
passwordCharArrayCurrent user password The password should be composed of at least 8 characters and include at least 3 out of the following 4 categories: upper-case letter, lower-case letter, special character and digit
**Output**

Success / failure callback.

**Sample**
``` fun resetWalletPin(userLogin: CharArray, loginType: UserType, newPin: CharArray, password: CharArray) { mobileDcApi .userService .resetWalletPin(userLogin, loginType, newPin, password, { //user's pin is changed }, { throwable -> // Something went wrong, maybe password is wrong? // Check exceptions described in Error handling chapter }) } ```
### changePassword

Asynchronous. Online.

Changes user's password with given parameters.

**Input**
**Parameter****Type****Description****Validation conditions**
passwordCharArrayCurrent user password The password should be composed of at least 8 characters and include at least 3 out of the following 4 categories: upper-case letter, lower-case letter, special character and digit
newPasswordCharArrayNew user passwordThe password should be composed of at least 8 characters and include at least 3 out of the following 4 categories: upper-case letter, lower-case letter, special character and digit
**Output**

Success / failure callback.

**Sample**
``` fun changePassword(password:CharArray, newPassword:CharArray) { mobileDcApi .userService .changePassword(password, newPassword, { //user's password is changed }, { throwable -> // Something went wrong, maybe current password is wrong? // Check exceptions described in Error handling chapter }) } ```
### initializeResetUserPassword (deprecated)

Asynchronous. Online.

Reset user's password with given parameters.

**Input**
**Parameter****Type****Description****Validation conditions**
userLoginTypeUserType User identifier type. One of: \[PHONE, EMAIL, INTERNAL\_ID, EXTERNAL\_ID\] Not empty
userLoginCharArrayUser identifier. Depends on user identifier typeNot empty, valid email address or phone with country prefix. For pl: 48500500500
**Output**

Success callback with key and optionally with LimitedResourceInfo.

**Parameter****Type****Description**
keyCharArray(Required) Initialization key that will be required for finalize reser user password process
limitedResourceInfoLimitedRedourceInfo?Additional paremeter which shows information about rate of APIs limits.

Failure callback.

**Sample**
``` fun initializeResetUserPassword(userLoginType: UserType, userLogin: CharArray) { mobileDcApi .userService .initializeResetUserPassword(userLoginType, userLogin, { response -> val key = response // key is necessary to call the finalizeResetUserPassword method. }, { throwable -> // Something went wrong. // Check exceptions described in Error handling chapter }) } ```
### initializeResetUserPassword

Asynchronous. Online.

Reset user's password with given parameters.

**Input**
**Parameter****Type****Description****Validation conditions**
initializeResetUserPasswordInitializeResetUserPasswordAn object containing user login type and user login Not empty
**InitializeResetUserPassword** model:
ParameterTypeDescription
userLoginTypeUserTypeUser identifier type. One of: \[PHONE, EMAIL, INTERNAL\_ID, EXTERNAL\_ID\]
userLoginCharArrayUser identifier. Depends on user identifier type
**Output**

Success callback with key.

ParameterTypeDescription
keyCharArray(Required) Initialization key that will be required for finalize reser user password process
limitedResourceInfoLimitedResourceInfoAdditional paremeter which shows information about rate limited APIs.

Failure callback.

**Sample**
``` fun initializeResetUserPassword(initializeResetUserPassword: InitializeResetUserPassword) { mobileDcApi .userService .initializeResetUserPassword(initializeResetUserPassword, { response -> val key = response.key // key is necessary to call the finalizeResetUserPassword method. val limitedResourceInfo = response.limitedResourceInfo // limitedResourceInfo contains information about // rate limited APIs, all parameters are nullable }, { throwable -> // Something went wrong. // Check exceptions described in Error handling chapter }) } ```
### finalizeResetUserPassword

Asynchronous. Online.

Set new user password with given parameters.

**Input**
**Parameter****Type****Description****Validation conditions**
userLoginTypeUserType User identifier type. One of: \[PHONE, EMAIL, INTERNAL\_ID, EXTERNAL\_ID\] Not empty
userLoginCharArrayUser identifier. Depends on user identifier typeNot empty, valid email address or phone with country prefix. For pl: 48500500500
keyCharArrayKey from initialize reset user password methodNot empty
otpCharArrayOne time password (sent via email during initialize password reset process)Not empty
newPasswordCharArrayNew user passwordThe password should be composed of at least 8 characters and include at least 3 out of the following 4 categories: upper-case letter, lower-case letter, special character and digit
**Output**

Success / failure callback.

**Sample**
``` fun finalizeResetUserPassword(userLoginType: UserType, userLogin: CharArray, key: CharArray, otp: CharArray, newPassword: CharArray) { mobileDcApi .userService .finalizeResetUserPassword(userLoginType, userLogin, key, otp, newPassword, { // The OTP has been sent }, { throwable -> // Something went wrong. // Check exceptions described in Error handling chapter }) } ```
### initializeEmailUpdate

Asynchronous. Online.

Change the user's email address to a new one. After confirming the change of the email, the one-time password ( OTP) will be sent to this address.

**Input**
**Parameter****Type****Description****Validation conditions**
emailCharArrayNew email (an OTP will be sent to that address) Email format
**Output**

Success callback with key.

**Parameter****Type****Description**
keyCharArrayInitialization key that will be required for finalize reset user password process

Failure callback.

**Sample**
``` fun initializeEmailUpdate(email: CharArray) { mobileDcApi .userService .initializeEmailUpdate(email, { response -> val key = response // key is necessary to call the finalizeChangeEmail method. }, { throwable -> // Something went wrong. // Check exceptions described in Error handling chapter }) } ```
### finalizeEmailUpdate

Asynchronous. Online.

Set new user email.

**Input**
**Parameter****Type****Description****Validation conditions**
keyCharArrayKey from initialize change email methodNot empty
otpCharArrayOne time password (sent via email during initialize change email process)Not empty
**Output**

Success / failure callback.

**Sample**
``` fun finalizeEmailUpdate(key: CharArray, otp: CharArray) { mobileDcApi .userService .finalizeEmailUpdate( key, otp, { // The user's email has been changed }, { throwable -> // Something went wrong. // Check exceptions described in Error handling chapter }) } ```
### resendOtp

Asynchronous. Online.

Method for resend OTP.

**Input**
**Parameter****Type****Description****Validation conditions**
userLoginTypeUserTypeUser identifier type. One of: \[PHONE, EMAIL, INTERNAL\_ID, EXTERNAL\_ID\]Not empty
userLoginUser identifier. Depends on user identifier typeUser identifier. Depends on user identifier typeNot empty, valid email address or phone with country prefix. For pl: 48500500500
**Output**

Success / failure callback.

**Sample**
``` fun resendOtp(userLoginType: UserType, userLogin: CharArray) { mobileDcApi .userService .resendOtp( userLoginType, userLogin, { // OTP has been sent }, { throwable -> // Something went wrong. // Check exceptions described in Error handling chapter }) } ```
### logout

Asynchronous. Offline.

Cancels user session.

**Input**

No input parameters.

**Output**

Success / failure callback.

**Sample**
``` fun logout() { mobileDcApi .userService .logout({ //User session has been canceled. Refresh user session to restore it. }, { //Something went wrong //Check exceptions described in Error handling chapter }) } ```
### deleteUser

Asynchronous. Online.

Delete data of current user and reset SDK state when success. The user can be hard or soft deleted depending on project’s configuration. Hard - method used to delete user with deleting data connected to the user (eg. card). Soft - method used to delete user without deleting data connected to the user (eg. card)

Usage of this method causes clearing all data related to selected user.

**Input**

No input parameters.

**Output**

Success/failure callback.

**Sample**
``` fun deleteUser() { mobileDcApi .userService .deleteUser({ //user is deleted, all data related to user, device cards etc is cleared. SDK is restarted. }, { throwable -> // Something went wrong // Check exceptions described in Error handling chapter }) } ```
## Cards domain ### addCard

Asynchronous. Online.

Adds new payment card with given parameters.

**Input**
**Parameter****Type****Description**
addCardAddCardCard information data.
**AddCard**
**Parameter****Type****Description****Validation conditions**
cardNumberCharArrayCard number Field cannot be empty, it must contain only digits, a length of exactly 16 digits and the checksum of the digits must be valid
expirationDateCharArrayCard expiration dateField may not be empty and must have a format MM/YY
descriptionCharArrayCard description Not empty
cardHolderCardHolder Card holder dataNot empty
isDefaultBooleanIs default card for user-
currencyCharArrayCurrency of card (ISO 4217, three letter code)-
visualIdCharArrayVisual identifier-
**CardHolder**
**Parameter****Type****Description****Validation conditions**
firstNameCharArrayFirst name of card holder Not empty
lastNameCharArrayLast name of card holderNot empty
**Output**

Success callback with cardId.

**Parameter****Type****Description**
cardIdLongId of added card
**Sample**
``` fun addCard(addCard: AddCard){ mobileDcApi .cardsService .addCard(addCard, { cardId -> // Card added }, { throwable -> // Something went wrong, maybe any field is wrong? // Check exceptions described in Error handling chapter }) } ```
### addCard (deprecated)

Asynchronous. Online.

Adds new payment card with given parameters.

**Input**
**Parameter****Type****Description****Validation conditions**
cardNumberCharArrayCard numberField cannot be empty, it must contain only digits, a length of exactly 16 digits and the checksum of the digits must be valid
expirationDateCharArrayCard expiration dateField may not be empty and must have a format MM/YY
descriptionCharArrayCard description Not empty
firstNameCharArray Card holder first nameNot empty
lastNameCharArrayCard holder last nameNot empty
**Output**

Success callback with cardId.

**Parameter****Type****Description**
cardIdLongId of added card
**Sample**
``` fun addCard(cardNumber:CharArray, expirationDate:CharArray, description:CharArray, firstName:CharArray, lastName:CharArray){ mobileDcApi .cardsService .addCard(cardNumber, expirationDate, description, firstName, lastName, { cardId -> // Card added }, { throwable -> // Something went wrong, maybe any field is wrong? // Check exceptions described in Error handling chapter }) } ```
### getAll

Asynchronous. Online.

Provides user cards from Mobile DC backend.

**Input**

No input parameters.

**Output**

Success callback with list of user cards.

**Parameter****Type****Description**
cardsList <Card>List of user cards
**Card**
**Field****Type****Description**
cardIdLongCard main identifier. Also used as paymentInstrumentId
lastFourDigitsStringLast four digits of user card
expirationDateStringCard expiration date
isVerifiedBooleanFlag informing about card verification
cardHolderCardHolderCard holder details
visualPathStringPath to visual of card
descriptionStringCard description
cardTypeCardType (MASTERCARD, VISA, OTHER, UNKNOWN)Type of card
isDefaultBooleanIndicates if card is default user’s card
sourceStringFrom which source card has been added
currencyStringCurrency code (ISO 4217, three letter code)
visualIdStringVisual id
externalIdStringCard external id
isLockedBooleanFlag which informs if card is locked
**CardHolder**
**Field****Type****Description**
firstNameStringCard holder first name
lastNameStringCard holder last name

Failure callback.

**Sample**
``` fun getCards() { mobileDcApi .cardsService .getAll({ cards -> showCardList(cards) }, { // Something went wrong // Check exceptions described in Error handling chapter }) } ```
### deleteCard

Asynchronous. Online.

Delete card with given card id.

**Input**
**Parameter****Type****Description****Validation conditions**
cardIdLongId of deleting cardField cannot be empty.
**Output**

Success / failure callback.

**Sample**
``` fun deleteCard(cardId: Long) { mobileDcApi .cardsService .deleteCard(cardId, { //Success }, { //Something went wrong //Check exceptions described in Error handling chapter }) } ```
### initialize3ds

Asynchronous. Online.

Card verification- initialize 3D Secure. Provides the data needed for the 3D Secure verification process.

**Input**
ParameterTypeDescriptionValidation conditions
cardIdLongId of added cardNot empty
**Output**

Success callback with Initialize3dsResult.

**Parameter****Type****Description**
initialize3dsResultInitialize3dsResultContains necessary data for 3DS verification
**Initialize3dsResult**
**Field****Type****Description**
paymentIdCharArrayInternal transaction id
pageContentCharArrayContent of webpage to be shown in browser created in application
**Sample**
``` fun initialize3ds(mobileDcApi: MobileDcApiKotlin, cardId: Long) { mobileDcApi .cardsService .initialize3ds(cardId, { result -> val paymentId = result.paymentId val pageContent = result.pageContent // Check is pageContent not null if (pageContent != null) { // Necessary convert from CharArray to ByteArray val pageContentToByteArray = pageContent.toByteArray() openWebView(paymentId, pageContentToByteArray) } else { // Card verification error } }, { throwable -> // Something went wrong, maybe cardId is invalid? // Check exceptions described in Error handling chapter }) } fun openWebView(paymentId: CharArray, pageContent: ByteArray) { //Bind your webView val myWebView = findViewById(R.id.myWebView) //JavaScript is disabled in a WebView by default. You can enable it through the WebSettings //attached to your WebView. You can retrieve WebSettings with getSettings(), then enable JavaScript //with setJavaScriptEnabled(). val webSettings: WebSettings = myWebView.getSettings() webSettings.javaScriptEnabled = true //Necessary bind this class to the JavaScript that runs in your WebView with addJavascriptInterface() //and name the interface Android. myWebView.addJavascriptInterface(WebAppInterface(), "Android") // Decode pageContent from initialize3ds response val viewPageContent = String(Base64.decode(pageContent, Base64.DEFAULT)) // Load page in vebWiew myWebView.loadData(viewPageContent, "text/html; charset=UTF-8", "utf-8") } //To bind a new interface between your JavaScript and Android code, call addJavascriptInterface(), //passing it a class instance to bind to your JavaScript and an interface name that your JavaScript //can call to access the class, like below example class WebAppInterface { // Get the pares parameter from the web page @JavascriptInterface fun setData(pares: String?) { // onPares interface method provides the pares parameter after interaction with webView. //Parameter pares is needed to perform finalize3ds // Necessary convert from String to CharArray val paresToCharArray = pares?.toCharArray() // close webView // Then you need to properly handle the parameter pares to be able to call finalize3ds //with the parameter pares and paymentId. } } ```
### finalize3ds

Asynchronous. Online.

Card verification - finalize 3D Secure. Verifies the payment card by the 3D Secure.

**Input**
**Parameter****Type****Description****Validation conditions**
cardIdLongId of added cardNot empty
cvcCharArrayCard verification code Field cannot be empty, it must contain only digits, a length of exactly 3 digits
paresCharArrayReceived after successful interaction with webView Not empty
paymentIdCharArrayReceived after a valid query to Initialize3ds Not empty
**Output**

Success callback with Finalize3dsResult.

**Parameter****Type****Description**
finalize3dsResultFinalize3dsResultContains data on the needed to carry out the amount verification and the verification value of the cardholder authentication
**Finalize3dsResult**
**Field****Type****Description**
amountValidationBooleanInform if random quotation should be used to complete card verification
cavvCharArrayCardholder authentication verification value
**Sample**
``` fun finalize3ds(mobileDcApi: MobileDcApiKotlin, cardId: Long, cvc: CharArray, pares: CharArray, paymentId: CharArray) { mobileDcApi .cardsService .finalize3ds(cardId, cvc, pares, paymentId, { result -> val amountValidation = result.amountValidation val cavv = result.cavv }, { throwable -> // Something went wrong, maybe any field is invalid? // Check exceptions described in Error handling chapter }) } ```
### initialize3DSv2

Asynchronous. Online.

Card verification - initialize 3D Secure. Provides the data needed for the 3D Secure verification process.

**Input**
**Parameter****Type****Description****Validation conditions**
initialize3DSv2Initialize3DSv2An object containing data for secure verification process.Not empty
**Initialize3DSv2**
**Parameter****Type****Description****Validation conditaions**
cardIdLongId of the cardNot empty
challengeUrlStringCallback url to handle redirect during Challenge (status CHALLENGE\_REQUIRED from response). Check sample implementation below. Not empty
browserDetailsBrowserDetailsObject with properties described belowNot empty
**BrowserDetails**
**Parameter****Type****Description****Validation conditions**
timezoneOffsetStringTimezone offset - numericNot empty
userAgentStringUser AgentNot empty
acceptHeaderStringAccept HeaderNot empty
screenWidthStringScreen Width - numericNot empty
screenHeightStringScreen HeightNot empty
languageStringLanguage - IETF BCP 47Not empty
browserIpStringBrowser IPNot empty
screenColorDepthStringScreen Color Depth - numericNot empty
**Output**
**Success callback with Initialize3DSv2Result**
**Parameter****Type****Description**
initialize3DSv2ResultInitialize3DSv2ResultContains necessary data for 3DS verification
**Initialize3DSv2Result**
**Field****Type****Description**
statusStringStatus returned of operation. Status could be SUCCESS or CHALLENGE\_REQUIRED. For SUCCESS the Card is already verified and no more action is required. For CHALLENGE\_REQUIRED application should show WebView with content from *challengeHtmlFromBase64.*
authenticationIdStringCard authentication id, used in finalize3DSv2 method.
acsUrlStringACS (Access Control Server) url. Required for CHALLENGE\_REQUIRED.
challengeHtmlFormBase64String64BASED html code provided ACQ/ASC. This should be displayed to Application User. Required for CHALLENGE\_REQUIRED.
**Sample**
``` fun initialize3DSv2(mobileDcApi : MobileDcApiKotlin){ mobileDcApi .cardsService .initialize3DSv2(initialize3DSv2, { initialize3DSv2Result -> when (initialize3DSv2Result.status) { "SUCCESS" -> { //3DS success, no more action is required } "CHALLENGE_REQUIRED" -> { showWebView(initialize3DSv2Result.challengeHtmlFormBase64, challengeUrl) } else -> //failure } }, { throwable -> // Something went wrong // Check exceptions described in Error handling chapter }) } //WebView implementation fun showWebView(challengeHtmlFormBase64: String, challengeUrl : String) { val viewPageContent = String(Base64.decode(challengeHtmlFormBase64, Base64.DEFAULT)) val webViewUrlDetectionClient = WebViewUrlDetectionClient(challengeUrl) with(webView) { webViewClient = webViewUrlDetectionClient settings.javaScriptEnabled = true visibility = View.VISIBLE loadData( viewPageContent, "text/html; charset=UTF-8", "utf-8" ) } } //sample WebViewClient implementation for handing redirect on challangeUrl class WebViewUrlDetectionClient(private val challengeUrl: String): WebViewClient() { override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) { super.onPageStarted(view, url, favicon) if (url.equals(challengeUrl, true)) { //call finalize3DSv2(cardId, initialize3DSv2Result.authenticationId) } } } ```
### finalize3DSv2

Asynchronous. Online.

Card verification - finalize 3D Secure. Verifies the payment card by the 3D Secure.

**Input**
**Parameter****Type****Description****Validation conditions**
finalize3DSv2Finalize3DSv2An object containing data for secure finalization process.Not empty
#### **Finalize3DSv2**
**Parameter****Type****Description****Validation conditions**
cardIdLongId of the card.Not empty
authenticationIdStringIdentifier of verification process from Initialize3DSv2ResultNot empty
**Output**

Success callback/ Failure callback.

**Sample**
``` fun finalize3DS(mobileDcApi : MobileDcApiKotlin) { val finalize3DSv2Input = Finalize3DSv2(cardId, authenticationId) mobileDcApi .cardsService .finalize3DSv2( finalize3DSv2Input, { //3DS finished with success }, { throwable -> // Something went wrong // Check exceptions described in Error handling chapter } ) } ```
### updateCard

Method for updating payment card data.

**Input**
**Parameter****Type****Description**
updateCardUpdateCardAn object containing card data to update
**UpdateCard**
**Parameter****Type****Description**
cardIdLongUnique card id
descriptionCharArrayCard description
currencyCharArryCard currency (ISO 4217, three letter code format)
isDefaultBooleanIs this card default
visualIdCharArrayCard visual identifier
firstNameCharArrayCard holder first name - send only when lastName is not blank
lastNameCharArrayCard holder last name - send only when firstName is not blank
**Output**

Success callback/ Failure callback.

**Sample**
``` fun updateCard(cardId: Long, description: CharArray?, isDefault: Boolean?, firstName: CharArray?, lastName: CharArray?){ val updateCard = UpdateCard(cardId).apply { this.description = description this.firstName = firstName this.lastName = lastName this.isDefault = isDefault } mobileDcApi .cardsService .updateCard(updateCard) { // Card updated }, { throwable -> // Something went wrong, maybe any field is wrong? // Check exceptions described in Error handling chapter }) } ```
### verifyCard

Asynchronous. Online.

Card verification - verify card after 3ds.

**Input**
**Parameter****Type****Description**
verifyCardVerifyCardAn object containing card data to verify.
**VerifyCard**
**Parameter****Type****Description**
cardIdLongUnique card id
amountCharArrayIf finalize3ds returns amountValidation set to false should be null otherwise value is amount freezed on the user account during card verification (value between 100 and 200 pennies).
**Output**

Success callback/ Failure callback.

**Sample**
``` fun verifyCard(cardId: Long, amount: CharArray?, amountValidation: Boolean) { val verifyCard: VerifyCard = VerifyCard(cardId).apply { this.amount = if (amountValidation) amount else null } mobileDcApi .cardsService .verifyCard(verifyCard, { //handle success }, { throwable -> //handle failure }) } ```
## Device domain ### pairByPassword (deprecated in 2.14.3)

Asynchronous. Online.

Pairs device using given password and user identifier.

Deprecated, use pairByPassword(PairByPassword)

**Input**
**Parameter****Type****Description****Validation conditions**
userLoginTypeUserTypeUser identifier type. One of: \[PHONE, EMAIL, INTERNAL\_ID, EXTERNAL\_ID\] Not empty
userLoginCharArrayUser identifier. Depends on user identifier typeEmail or Phone with country prefix
userPasswordCharArrayUser passwordPassword should be composed of at least 8 characters and include at least 3 out of the following 4 categories: upper-case letter, lower-case letter, special character and digit
fcmTokenCharArrayToken for push notificationsNot empty
biometricAuthTypeBiometricAuthTypeOptional. One of: \[BIOMETRIC\_ONLY, BIOMETRIC\_WITH\_ALTERNATIVE\]. BIOMETRIC\_ONLY - enable only biometric authentication BIOMETRIC\_WITH\_ALTERNATIVE - enable device level authentication If not set any of above don't be enable.
**Output**

Success / failure callback.

**Sample**
``` fun pairByPassword( email: CharArray, //user email password: CharArray, //user password fcmToken: CharArray // saved FCM token from Firebase service ) { mobileDcApi .deviceService .pairByPassword(UserType.EMAIL, email, password, fcmToken, { //device is paired, now you can use this device to manage Mobile DC resources }, { throwable -> // Something went wrong, maybe any field is wrong? // Check exceptions described in Error handling chapter } ) } ```
### pairByPassword

Asynchronous. Online.

Pairs device using given password and user identifier.

**Input**
**Parameter****Type****Description****Validation conditions**
pairByPasswordPairByPasswordAn object containing user information to pair device. Not empty
**PairByPassword**
**Parameter****Type****Description****Validation conditions**
userLoginTypeUserTypeUser identifier type. One of: \[PHONE, EMAIL, INTERNAL\_ID, EXTERNAL\_ID\] Not empty
userLoginCharArrayUser identifier. Depends on user identifier typeEmail or Phone with country prefix
userPasswordCharArrayUser passwordPassword should be composed of at least 8 characters and include at least 3 out of the following 4 categories: upper-case letter, lower-case letter, special character and digit
cloudMessagingRegistrationTokenCloudMessagingRegistrationTokenAn object containing cloud messaging registration token information.Not empty
biometricAuthTypeBiometricAuthTypeOptional. One of: \[BIOMETRIC\_ONLY, BIOMETRIC\_WITH\_ALTERNATIVE\]. BIOMETRIC\_ONLY - enable only biometric authentication BIOMETRIC\_WITH\_ALTERNATIVE - enable device level authentication If not set any of above don't be enable.
externalDeviceIdString?External device id
**CloudMessagingRegistrationToken**
**Parameter****Type****Description****Validation conditions**
typeCloudMessagingTypeMandatory. One of: \[FCM\]. FCM - Firebase Cloud Messaging Not empty
tokenStringToken for push notifications Not empty
**Output**

Success / failure callback.

**Sample**
``` val cloudMessagingRegistrationToken: CloudMessagingRegistrationToken = CloudMessagingRegistrationToken( type: CloudMessagingType, //messaging token type token: String // saved cloud messaging token ) val pairByPassword: PairByPassword = PairByPassword( userLoginType: UserType, //user identifier type userLogin: CharArray, //user identifier password: CharArray, //user password cloudMessagingRegistrationToken: CloudMessagingRegistrationToken, //cloud messaging registration token information biometricAuthType: BiometricAuthType?, //Optional biometric authentication type externalDeviceId: String? //Optional external device id ) fun pairByPassword(pairByPassword: PairByPassword) { mobileDcApi .deviceService .pairByPassword(pairByPassword, { //device is paired, now you can use this device to manage Mobile DC resources }, { throwable -> // Something went wrong, maybe any field is wrong? // Check exceptions described in Error handling chapter } ) } ```
### pairByTrustedIdentity (deprecared in 2.14.3)

Asynchronous. Online.

Binds device to user in Mobile DC backend with Trusted Identity genetated by client server.

Deprecated, use pairByTrustedIdentity(PairByTrustedIdentity).

**Input**
**Parameter****Type****Description****Validation conditions**
trustedIdentityStringJSON Web Token containing registration data Not empty
fcmRegistrationTokenCharArrayFCM Cloud messaging registration token Not empty
**TrustedIdentity**
ParameterTypeDescriptionValidation conditions
userIdStringExternal user id given by the client Not empty
**Output**

Success / failure callback.

**Sample** Sample code for *trustedIdentity* generation (see also *[Data signing and encryption](https://wiki.verestro.com/display/UCP/Data+signing+and+encryption)* chapter):
``` class TrustedIdentity { fun generate() { val claims = JWTClaimsSet.Builder() .claim("userId", "externalUserId") .build(); val trustedIdentity = JwtGenerator.generate(claims, certificates, privateKey); // ... } } ```
Usage of trustedIdentity in application:
``` fun pairDeviceByTrustedIdentity( mobileDcApi: MobileDcApiKotlin, trustedIdentity: String ) { val fcmToken = getFcmRegistartionToken() // get saved FCM token from FirebaseMessagingService, or from //FirebaseInsanceId::getToken() mobileDcApi .deviceService .pairByTrustedIdentity( trustedIdentity, fcmToken, { //device is paired, now you can use this device to manage Mobile DC resources }, { throwable -> //some error occured, check exception }) } ```
### pairByTrustedIdentity

Asynchronous. Online.

Binds device to user in Mobile DC backend with Trusted Identity genetated by client server.

**Input**
**Parameter****Type****Description****Validation conditions**
pairByTrustedIdentityPairByTrustedIdentityAn object containing user information to pair device. Not empty
**PairByTrustedIdentity**
**Parameter****Type****Description****Validation conditions**
trustedIdentityStringJSON Web Token containing registration data Not empty
cloudMessagingRegistrationTokenCloudMessagingRegistrationTokenAn object containing cloud messaging registration token information. Not empty
externalDeviceIdString External device id
**TrustedIdentity**
**Parameter****Type****Description****Validation conditions**
userIdStringExternal user id given by the client Not empty
**CloudMessagingRegistrationToken**
**Parameter****Type****Description****Validation conditions**
typeCloudMessagingTypeMandatory. One of: \[FCM\]. FCM - Firebase Cloud Messaging Not empty
tokenStringToken for push notifications Not empty
**Output**

Success / failure callback.

**Sample** Sample code for *trustedIdentity* generation (see also *[Data signing and encryption](https://wiki.verestro.com/display/UCP/Data+signing+and+encryption)* chapter):
``` class TrustedIdentity { fun generate() { val claims = JWTClaimsSet.Builder() .claim("userId", "externalUserId") .build(); val trustedIdentity = JwtGenerator.generate(claims, certificates, privateKey); // ... } } ```
Usage of trustedIdentity in application:
``` val cloudMessagingRegistrationToken: CloudMessagingRegistrationToken = CloudMessagingRegistrationToken( type: CloudMessagingType, //messaging token type token: String // saved cloud messaging token ) val pairByTrustedIdentity: PairByTrustedIdentity = PairByTrustedIdentity( trustedIdentity: String, //JSON Web Token containing registration data cloudMessagingRegistrationToken: CloudMessagingRegistrationToken, //cloud messaging registration token information externalDeviceId: String? //Optional external device id ) fun pairByTrustedIdentity(pairByTrustedIdentity: PairByTrustedIdentity) { mobileDcApi .deviceService .pairByTrustedIdentity(pairByTrustedIdentity, { //device is paired, now you can use this device to manage Mobile DC resources }, { throwable -> // Something went wrong, maybe any field is wrong? // Check exceptions described in Error handling chapter } ) } ```
### ### pairByExternalCredentials (deprecated in 2.14.3)

Asynchronous. Online.

Binds device to user in Mobile DC backend using username and password.

Deprecated, use pairByTrustedIdentity(PairByExternalCredentials).

**Input**
**Parameter****Type****Description****Validation conditions**
usernameStringUser identifier Not empty
passwordCharArrayUser passwordNot empty
fcmRegistrationTokenCharArrayFCM Cloud messaging registration token Not empty
biometricAuthTypeBiometricAuthTypeOptional. One of: \[BIOMETRIC\_ONLY, BIOMETRIC\_WITH\_ALTERNATIVE\]. BIOMETRIC\_ONLY - enable only biometric authentication BIOMETRIC\_WITH\_ALTERNATIVE - enable device level authentication If not set any of above don't be enable.
**Output**

Success / failure callback.

**Sample**
``` fun pairByExternalCredentials() { val username: CharArray = getCharArrayFromInput() //get username provided by user val password: CharArray = getCharArrayFromInput() //get password provided by user val fcmToken = getFcmToken() // get saved FCM token from Firebase service mobileDcApi .deviceService .pairByExternalCredentials( username, password, fcmToken, { //device is paired, now you can use this device to manage Mobile DC resources }, { throwable -> //some error occured, check exception }) } ```
### pairByExternalCredentials

Asynchronous. Online.

Binds device to user in Mobile DC backend using username and password.

**Input**
**Parameter****Type****Description****Validation conditions**
pairByExternalCredentialsPairByExternalCredentialsAn object containing user information to pair device. Not empty
**PairByExternalCredentials**
**Parameter****Type****Description****Validation conditions**
usernameStringUser identifier Not empty
passwordCharArrayUser passwordNot empty
cloudMessagingRegistrationTokenCloudMessagingRegistrationTokenFCM Cloud messaging registration token Not empty
biometricAuthTypeBiometricAuthTypeOptional. One of: \[BIOMETRIC\_ONLY, BIOMETRIC\_WITH\_ALTERNATIVE\]. BIOMETRIC\_ONLY - enable only biometric authentication BIOMETRIC\_WITH\_ALTERNATIVE - enable device level authentication If not set any of above don't be enable.
deviceExternalIdString External device id
**CloudMessagingRegistrationToken**
**Parameter****Type****Description****Validation conditions**
typeCloudMessagingTypeMandatory. One of: \[FCM\]. FCM - Firebase Cloud Messaging Not empty
tokenStringToken for push notifications Not empty
**Output**

Success / failure callback.

**Sample**
``` val cloudMessagingRegistrationToken: CloudMessagingRegistrationToken = CloudMessagingRegistrationToken( type: CloudMessagingType, //messaging token type token: String //saved cloud messaging token ) val pairByExternalCredentials: PairByExternalCredentials = PairByExternalCredentials( userName: CharrArray, //username provided by user password: CharrArray, //password provided by user cloudMessagingRegistratinoToken: CloudMessagingRegistrationToken, //cloud messaging registration token information biometricAuthType: BiometricAuthType?, //Optional biometric authentication type externalDevice: String? //Optional external device id ) fun pairByExternalCredentials(pairByExternalCredentials: PairByExternalCredentials) { mobileDcApi .deviceService .pairByExternalCredentials(pairByExternalCredentials, { //device is paired, now you can use this device to manage Mobile DC resources }, { throwable -> // Something went wrong, maybe any field is wrong? // Check exceptions described in Error handling chapter } ) } ```
### isDevicePaired

Asynchronous. Offline.

Method allow to check is Device already paired with MDC Backend.

**Input**

No input parameters.

**Output**

Success / failure callback.

**Sample**
``` fun isDevicePaired() { mobileDcApi .deviceService .isDevicePaired() { // return is device paired state }, {throwable -> // some error occurred, check exception } } ```
### unPairDevice

Asynchronous. Online.

Removes all data collected by SDK and binding between user and device in Mobile DC backend.

Pairing device to user can be made by <<pairBy...>> methods.

**Input**

No input parameters.

**Output**

Success / failure callback.

**Sample**
``` fun unPairDevice() { mobileDcApi .deviceService .unPairDevice({ //device is unPaired, SDK cannot be not longer used //application can remove all data in context of sDKDefaultBackoffStrategy //for use SDK again call pairBy.. method }, { throwable -> //some error occured, check exception }) } ```
## Cloud messaging domain ### process

Asynchronous. Offline.

Processes data sent by backend (push notification data). Application should check Verestro senderId in RemoteMessage object (RemoteMessage::from method) to verify sender. Method can throw InvalidPushException in case of invalid push content passed to it.

**Input**
**Parameter****Type****Description****Validation conditions**
pushDataMap<String, String>Data received from notification service in *RemoteMessage*object Not empty
**Output**

Success/failure callback.

**Sample**
``` //FirebaseMessagingService class from Firebase override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) val senderId: String? = remoteMessage.from val pushData = remoteMessage.data //check push source only when push source is Verestro sender Id if (isVerestroSenderId(senderId)) { mobileDcApi .cloudMessagingService .process(pushData, { //push sent to SDK }, { //some error }) } else { //proceed push from another source } } ```
### getSource (Deprecated in 2.14.3)

Asynchronous. Offline.

Checks Verestro Backend service source of push content.

Application should check senderId in RemoteMessage object (RemoteMessage::from method) before passing data to this method.

Deprecated in 2.14.3, no longer required to use.

**Input**
**Parameter****Type****Description****Validation conditions**
pushDataMap<String, String>Data received from notification service in *RemoteMessage*object Not empty
**Output**

Success callback with *source* of push.

**Parameter****Type****Description**
sourceStringSource of push content, where push data should be passed. Possible values: UCP

Failure callback.

**Sample**
``` //FirebaseMessagingService class from Firebase override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) val senderId: String? = remoteMessage.from val pushData = remoteMessage.data //check push source only when push source is uPaid sender Id if (isUpaidSenderId(senderId)) { //checking push source and passing to proper uPaid module mobileDcApi .cloudMessagingService .getSource(pushData, { source -> when (source) { "UCP" -> processUcpPush(pushData) } }, { //some error }) } else { //proceed push from another source } } private fun processUcpPush(pushData: Map) { ucpApi .cloudMessagingService .process(pushData, { //push processed in UCP }, { //some error }) } ```
### updateRegistrationToken

Asynchronous. Online.

Updates FCM Cloud Messaging registation token.

Method should be called when application receive new registration token from FCM service.

When updated application should still receive push notifications from Verestro Backend.

Application should always retry update FCM Registration token if method failed.

**Input**
**Parameter****Type****Description****Validation conditions**
cloudMessagingRegistrationTokenCloudMessagingRegistrationTokenAn object containing user information to update registration token.Not empty
CloudMessagingRegistrationToken
**Parameter****Type****Description****Validation conditions**
typeCloudMessagingTypeMandatory. One of: \[FCM\]. FCM - Firebase Cloud Messaging Not empty
token String Registration token Not empty
**Output**

Success / failure callback.

**Sample**
``` //application should listen for FCM token changes in FirebaseMessagingService::onNewToken method val cloudMessagingRegistrationToken: CloudMessagingRegistrationToken = CloudMessagingRegistrationToken( type: CloudMessagingType, //messaging token type token: String //saved cloud messaging token ) fun updateRegistrationToken(cloudMessagingRegistrationToken: CloudMessagingRegistrationToken) { mobileDcApi .deviceService .isDevicePaired({ isPaired -> //token update is required only if device is already paired if (isPaired) { mobileDcApi .cloudMessagingService .updateRegistrationToken(cloudMessagingRegistrationToken, { //token updated }, { //some error, always retry action until success //when internet or server connection is not reachable try again later }) } }, { //some error }) } ```
### updateFcmRegistrationToken (deprecated in 2.14.3)

Asynchronous. Online.

Updates Cloud Messaging registation token for selected token type (FCM).

Method should be called when application receive new registration token from FCM service.

When updated application should still receive push notifications from Verestro Backend.

Application should always retry update FCM Registration token if method failed.

Deprecated in 2.14.3, use updateRegistrationToken.

**Input**
**Parameter****Type****Description****Validation conditions**
fcmTokenStringRegistration token received from FCM service Not empty
**Output**

Success / failure callback.

**Sample** ``` //application should listen for FCM token changes in FirebaseMessagingService::onNewToken method private fun updateFcmToken(newFcmToken: String) { mobileDcApi .deviceService .isDevicePaired({ isPaired -> //token update is required only if device is already paired if (isPaired) { mobileDcApi .cloudMessagingService .updateFcmRegistrationToken(newFcmToken, { //token updated }, { //some error, always retry action until success //when internet or server connection is not reachable try again later }) } }, { //some error }) ``` ## TransactionsHistory domain ### getTransactionsHistory

Asynchronous. Online.

Provides transaction history from Mobile DC backend with selected transactions filters.

**Input**
**Parameter****Type****Description****Validation conditions**
filtersTransactionsFiltersFilters for transactions history. Leave null to get all user's transactions with limit equals 10
nextPageTransactionsNextPageIndicates starting point of downloaded transaction history Pass null for first request or pass object from getTransactionHistory result
**TransactionsFilters**
**Parameter****Type****Description****Validation conditions**
cardIdStringSelected card id or null
ibanIdStringSelected iban id or null
paymentTokenIdStringSelected paymentTokenId or null Field is available in PaymentInstrument object in UCP module
areaStringArea of transaction, specific per project (e.g. "UCP"). Could be null in order to avoid filtering by area of transaction.
timestampFromStringThe date/time (in ISO 8601 extended format) indicating the timestamp from which transactions would be filtered (e.g. "2020-10-10T00:59:00.000000+02:00"). Could be null in order to avoid filtering by indicating the earliest date of transactions.
timestampToStringThe date/time (in ISO 8601 extended format) indicating the timestamp to which transactions would be filtered (e.g. "2020-10-10T00:59:00.000000+02:00"). Could be null in order to avoid filtering by indicating the latest date of transactions.
amountMinorMinLongThe transaction minimum monetary amount (inclusive) in terms of the minor units of the currency. For example, for EUR 2.35 client should pass 235, and for BHD -1.345 should pass 1345. Absolute value is taken into consideration.
amountMinorMaxLongThe transaction maximum monetary amount (inclusive) in terms of the minor units of the currency. For example, for EUR 2.35 client should pass 235, and for BHD -1.345 should pass 1345. Absolute value is taken into consideration.
amountTypeAmountTypeTransaction amount type. One of POSITIVE, NEGATIVE
limitIntLimit of transactions to get. When not changed default value is 10
**TransactionsNextPage**
**Parameter****Type****Description****Validation conditions**
seekIdStringSeek id of next transaction
seekTimestampStringSeek timestamp of next transaction
**Output**

Success callback with list of transactions history.

**Parameter****Type****Description**
transactionHistoryTransactionHistoryAn object containing list of TransactionDetails and TransactionNextPage to show transaction history
**Parameter****Type****Description**
transactionsList<TransactionDetails>List of transactions history
nextPageTransactionsNextPageObject for getting next transactions history items
**TransactionDetails**
**Field****Type****Description**
idLongInternal transaction id
clientTransactionIdStringClient id of transaction
amountMinorLongThe transaction monetary count in terms of the minor units of the currency
currencyStringCurrency of the transaction amount. 3-digits ISO 4217 currency code
typeStringTransaction type. One of: PURCHASE, REFUND, PAYMENT, ATM\_WITHDRAWAL, CASH\_DISBURSEMENT, ATM\_DEPOSIT, ATM\_TRANSFER
statusStringTransaction status. One of: DECLINED, CLEARED, AUTHORIZED, REVERSED
timestampStringThe date/time when the transaction occurred. In ISO8601 extended format
descriptionStringDescription of transaction
cardIdLongCard id of transaction
paymentTokenIdStringId of payment token
cardLastFourDigitsStringLast four digits of card
merchantNameStringThe merchant name
merchantPostalCodeStringThe postal code of the merchant
transactionCountryCodeStringThe country in which the transaction was performed. Expressed as a 3-letter country code as defined in ISO 3166-1
comboCardAccountTypeStringIndicator if Credit or Debit was chosen for a tokenized combo card at the time of the transaction. One of: CREDIT, DEBIT
issuerResponseInformationStringAdditional information provided by the issuer for declined transaction. One of: INVALID\_CARD\_NUMBER, FORMAT\_ERROR, MAX\_AMOUNT\_EXCEEDED, EXPIRED\_CARD, PIN\_AUTHORIZATION\_FAILED, TRANSACTION\_NOT\_PERMITTED, WITHDRAWL\_AMOUNT\_EXCEEDED, RESTRICTED\_CARD, WITHDRAWL\_COUNT\_EXCEEDED, PIN\_TRIES\_NUMBER\_EXCEEDED, INCORRECT\_PIN, DUPLICATE\_TRANSMISSION
transactionChannelStringInformation about transaction channel. One of: CONTACTLESS, CLOUD, MONEYSEND
ibanIdStringId of iban as *sha256Hex*
mccString4 digits merchant category code
mccCategoryStringCategory of merchant category code
originalAmountMinorLongThe transaction monetary amount in terms of the minor units of the original currency. For example, EUR 2.35 will return 235, and BHD -1.345 will return -1345. Negative amounts indicate a refund or payment
originalCurrencyString 3-character ISO 4217 original currency code of the transaction
exchangeRateDouble Exchange rate of the original currency into the base currency
balanceMinorValueAfterTransactionLong Account balance value after transaction in terms of the minor units
commissionMinorValueLong Commission value in terms of the minor units
clearingTimestampString The date/time when the transaction changed status on CLEARED. In ISO 8601 extended format
parentIdLong Id of base transaction
attachmentStatusString Attachment status of transaction. One of: \[EMPTY, INCORRECT, TO\_APPROVE, APPROVED\]
incorrectAttachmentStatusReasonString Reason of INCORRECT attachment status. Required only for this status. One of: \[ATTACHMENT\_UNREADABLE, ATTACHMENT\_INCORRECT, OTHER\]
**TransactionsNextPage**
**Parameter****Type****Description****Validation conditions**
seekIdStringSeek id of next transaction
seekTimestampStringSeek timestamp of next transaction
**Sample**
``` //sample filters val lastFiveTransactionForCard = TransactionsFilters() lastFiveTransactionForCard.cardId = "1" lastFiveTransactionForCard.limit = 5 //when not set default is 10 //another sample filters val allTransactionsForUser: TransactionsFilters? = null //another sample filters val lastThreeTransactionsForUser = TransactionsFilters() lastThreeTransactionsForUser.limit = 3 //indicates starting point of transaction history //can be used while loading more history or for paging var nextPage: TransactionsNextPage? = null fun getTransactionsHistory(filters: TransactionsFilters?) { mobileDcApi .transactionsHistoryService .getTransactionsHistory(filters, nextPage, { transactionsHistory -> val transactions = transactionsHistory.transactions showTransactions(transactions) //save nextPage for getting next items nextPage = transactionsHistory.nextPage }, { //something went wrong, check exception }) } ```
### getTransactionDetails

Asynchronous. Online.

Provides transaction details from Mobile DC backend for selected transactionId.

**Input**
**Parameter****Type****Description****Validation conditions**
getTransactionDetailsGetTransactionDetailsContains id for requested transactionIdtransactionId greater than 0 and not null
**GetTransactionDetails**
**Parameter****Type****Description****Validation conditions**
transactionIdLongSelected id of transactionGreater than 0 and not null
**Output**

Success callback with transaction details.

**Parameter****Type****Description**
getTransactionDetailsResultGetTransactionDetailsResultAn object containing details for requested transaction
**GetTransactionDetailsResult**
**Field****Type****Description**
idLongInternal transaction id
clientTransactionIdStringClient id of transaction
amountMinorLongThe transaction monetary count in terms of the minor units of the currency
currencyStringCurrency of the transaction amount. 3-digits ISO 4217 currency code
typeStringTransaction type. One of: PURCHASE, REFUND, PAYMENT, ATM\_WITHDRAWAL, CASH\_DISBURSEMENT, ATM\_DEPOSIT, ATM\_TRANSFER
statusStringTransaction status. One of: DECLINED, CLEARED, AUTHORIZED, REVERSED
timestampStringThe date/time when the transaction occurred. In ISO8601 extended format
descriptionStringDescription of transaction
cardIdLongCard id of transaction
paymentTokenIdStringId of payment token
cardLastFourDigitsStringLast four digits of card
merchantNameStringThe merchant name
merchantPostalCodeStringThe postal code of the merchant
transactionCountryCodeStringThe country in which the transaction was performed. Expressed as a 3-letter country code as defined in ISO 3166-1
comboCardAccountTypeStringIndicator if Credit or Debit was chosen for a tokenized combo card at the time of the transaction. One of: CREDIT, DEBIT
issuerResponseInformationStringAdditional information provided by the issuer for declined transaction. One of: INVALID\_CARD\_NUMBER, FORMAT\_ERROR, MAX\_AMOUNT\_EXCEEDED, EXPIRED\_CARD, PIN\_AUTHORIZATION\_FAILED, TRANSACTION\_NOT\_PERMITTED, WITHDRAWL\_AMOUNT\_EXCEEDED, RESTRICTED\_CARD, WITHDRAWL\_COUNT\_EXCEEDED, PIN\_TRIES\_NUMBER\_EXCEEDED, INCORRECT\_PIN, DUPLICATE\_TRANSMISSION
transactionChannelStringInformation about transaction channel. One of: CONTACTLESS, CLOUD, MONEYSEND
ibanIdStringId of iban as *sha256Hex*
mccString4 digits merchant category code
mccCategoryStringCategory of merchant category code
originalAmountMinorLongThe transaction monetary amount in terms of the minor units of the original currency. For example, EUR 2.35 will return 235, and BHD -1.345 will return -1345. Negative amounts indicate a refund or payment
originalCurrencyString 3-character ISO 4217 original currency code of the transaction
exchangeRateDouble Exchange rate of the original currency into the base currency
balanceMinorValueAfterTransactionLong Account balance value after transaction in terms of the minor units
commissionMinorValueLong Commission value in terms of the minor units
clearingTimestampString The date/time when the transaction changed status on CLEARED. In ISO 8601 extended format
parentIdLong Id of base transaction
attachmentStatusString Attachment status of transaction. One of: \[EMPTY, INCORRECT, TO\_APPROVE, APPROVED\]
incorrectAttachmentStatusReasonString Reason of INCORRECT attachment status. Required only for this status. One of: \[ATTACHMENT\_UNREADABLE, ATTACHMENT\_INCORRECT, OTHER\]
attachments List<TransactionDetailsAttachment> Transaction attachments list
**TransactionDetailsAttachment**
ParameterTypeDescription
idStringAttachment id
nameStringFile name
mimeTypeStringMime type
linkStringUrl address valid by default 10 minutes. If link expires then API to generate link should be used. Mostly in this case minio will return 403 Forbidden
linkExpirationDateStringUrl expiration date for given link in ISO 8601 extended format. Given link will be valid only short period of time
**Sample**
``` //sample entry data val getTransactionDetails = GetTransactionDetails(1210L) fun getTransactionDetails(getTransactionDetails: GetTransactionDetails) { mobileDcApi .transactionsHistoryService .getTransactionDetails(getTransactionDetails, { getTransactionDetailsResult -> //succes }, { //something went wrong, check exception }) } ```
### storeAttachment

Asynchronous. Online.

Stores attachment file in Mobile DC backend for selected transactionId.

**Input**
**Parameter****Type****Description**
transactionAttachmentTransactionAttachmentContains all data required to save attachment
**TransactionAttachment**
**Parameter****Type****Description****Validation conditions**
transactionIdLongSelected id of transactionnot null and greater or equal 0
attachmentInputStreamInputStreamStream of file datanot null
mimeTypeStringMIME type of file. For example image/jpeg image/pngIs not empty
fileNameStringName of file. If null or blank then it is generated randomly with unique name. File extension is optional.
**Output**

Success callback.

**Sample**
``` //sample entry data val inputStream = contentResolver.openInputStream(uri) val mimeType = contentResolver.getType(uri) val transactionAttachment = TransactionAttachment( transactionId = 10023L, attachment = inputStream, mimeType = "image/jpeg" ) //transaction attachment with optional file name val transactionAttachment = TransactionAttachment( transactionId = 10023L, attachment = inputStream, mimeType = "image/png" fileName = "picture.png" ) val transactionAttachment = TransactionAttachment( transactionId = 10023L, attachment = inputStream, mimeType = "image/png" fileName = "1636362847509" ) fun storeAttachment(transactionAttachment: TransactionAttachment) { mobileDcApi .transactionsHistoryService .storeAttachment(transactionAttachment, { //succes }, { //something went wrong, check exception }) } ```
### generateAttachmentLink

Asynchronous. Online.

Provides new link to load attachment when existing one fails with 403 HTTP status.

**Input**
**Parameter****Type****Description**
generateAttachmentLink GenerateAttachmentLink Contains transactionId and attachmentId
**GenerateAttachmentLink**
ParameterTypeDescriptionValidation conditions
transactionIdLongSelected id of transactionnot null and greater or equal 0
attachmentIdStringSelected attachment IDis not empty
**Output**

Success callback with new attachment link and expiration date.

**Parameter****Type****Description**
generateAttachmentLinkResultGenerateAttachmentLinkResultAn object containing new link and link expiry date
**GenerateAttachmentLinkResult**
**Field****Type****Description**
linkStringUrl address
linkExpirationDateStringUrl expiration date for given link in ISO 8601 extended format. Given link will be valid only short period of time
**Sample**
``` //sample entry data val generateAttachmentLink = GenerateAttachmentLink(1210L, "2145") fun generateAttachmentLink(generateAttachmentLink: GenerateAttachmentLink) { mobileDcApi .transactionsHistoryService .generateAttachmentLink(generateAttachmentLink, { generateAttachmentLinkResult -> //succes }, { //something went wrong, check exception }) } //sample usage when loading link from getTransactionDetails returns 403 HTTP status fun getTransactionDetails() { mobileDcApi .transactionHistoryService .getTransactionDetails(GetTransactionDetails(transactionId), { getTransactionDetailsResult -> loadAttachmentsImages(getTransactionDetailsResult) }, { //something went wrong, check exception } ) } private fun loadAttachmentsImages(getTransactionDetailsResult: GetTransactionDetailsResult) { val attachments: List = getTransactionDetailsResult.attachments attachments.forEach { transactionDetailAttachment -> loadImage(getTransactionDetailsResult.id, transactionDetailAttachment) } } private fun loadImage(attachment: TransactionDetailsAttachment, transactionId: Long) { //downloading file may differ in your project. This is only example in synchronised code val request = Request.Builder().url(attachment.link).build() val response = OkHttpClient().newCall(request).execute() val httpCode = response.code() when (httpCode) { 403 -> { refreshAttachment(transactionId, attachment.id) } 200 -> { //convert stream to bitmap and load into image view } else -> { //check other status } } } private fun refreshAttachment(transactionId: Long, attachmentId: String) { mobileDcApi .transactionsHistoryService .generateAttachmentLink( GenerateAttachmentLink(transactionId, attachmentId), { generateAttachmentLinkResult -> //sample with Glide library usage Glide.with(context).asBitmap() .load(generateAttachmentLinkResult.link) .into(nextImageView) }, { //something went wrong, check exception }) } ```
### deleteAttachment

Asynchronous. Online.

Delete attachment associated with provided transaction.

**Input**
**Parameter****Type****Description****Validation conditions**
deleteAttachmentDeleteAttachmentPlain object of DeleteAttachment Not empty
**DeleteAttachment** object contains following fields.
**Parameter****Type****Description****Validation conditions**
transactionIdLongIdentifier of selected transaction. Id can be taken from GetTransactionDetailsResult object, check [getTransactionDetails](https://wiki.verestro.com/display/UCP/getTransactionDetails) method Not empty
attachmentIdStringIdentifier of selected attachment. Id can be taken from TransactionDetailsAttachment, check [getTransactionDetails](https://wiki.verestro.com/display/UCP/getTransactionDetails) method Not empty
**Output**

Success callback/ Failure callback.

**Sample**
``` val transactionDetailsResult: GetTransactionDetailsResult = GetTransactionDetails(1L) val deleteAttachment: DeleteAttachment = DeleteAttachment(transactionDetailsResult.id, transactionDetailsResult.transactionDetailsAttachment.id) private fun deleteAttachment(deleteAttachment) { mobileDcApi.transactionService .deleteAttachment(deleteAttachment, { //Deletion of attachment went succesfully }, { throwable -> //Something went wrong, check exception with documentation }) } ```
### updateSingleTransactionData

Asynchronous. Online.

Updates single transaction data in Mobile DC backend by transactionId.

**Input**
**Parameter****Type****Description****Validation conditions**
updateSingleTransactionData UpdateSingleTransactionData Transaction data to be updatedNot empty
**UpdateSingleTransactionData**
**Parameter****Type****Description****Validation conditions**
transactionId Long Transaction IDNot empty
description String Description of transaction
**Output**

Success callback/ Failure callback.

**Sample** ``` fun updateSingleTransactionData(updateSingleTransactionData: UpdateSingleTransactionData) { mobileDcApi .transactionsHistoryService .updateSingleTransactionData(updateSingleTransactionData, { //Transaction updated successfully }, { //Something went wrong, check exception with documentation }) } ``` ## DOCUMENT CHANGELOG Version 1.0.1 - Created. Version 2.0.0 - Changed approach to SDK setup. - Removed methods used to fingerprint authentication. - Added NetworkConnection exception and CoreSdkException. - Added new reason codes to existing exceptions. - New methods in user domain: addUser, loginByTrustedIdentity, changePassword. - New methods in device domain: pairByPassword, pairByExternalCredentials, unPairDevice. - New methods in cards domain: getAll. - New domains: ibans, transactionsHistory. Version 2.1.0 - Added new methods in User domain (authenticateByPin, loginByPin, changeWalletPin, resetWalletPin, initializeResetUserPassword, finilizeResetUserPassword). - Added new methods in Cards domain (addCard, initialize3ds, finalize3ds, deleteCard). Version 2.1.1 - Added information about SDK size. - Added information about SDK ingetration on lower Android API level. Version 2.2.0 - Improved Mobile DC SDK startup time. Version 2.3.1 - Added new methods in user domain (isBiometricAuthenticationEnabled, enableBiometricAuthentication, startBiometricAuthentication, authenticateByBiometric, loginBySignature). - Fixed security reports sending. - Consumer proguard rules update. Version 2.4.0 - Added optional log handler to MobileDcCoreConfigurationBuilder. - Added disableBiometricAuthentication method. - Added BiometricTypeAuth paramter to pairing methods. Version 2.5.0 - Added getUser method. Version 2.6.0 - Added addUser method. Version 2.6.1 - Disabled sending native checksum in pairDevice process. Version 2.7.0 - Added addresses service to facade. Version 2.8.0 - Added addresses service to facade. - Fixed checksum sending. - Added apk certificate description. - Added updateUser method to User domain. Version 2.9.0 - Security issue codes are more precisely and give us more information about issue. - Marked addAddress as deprecated. - Added new one addAddress method which returning addressId of added address. Version 2.9.3 - Device un-pairing device with *unPaidDevice* is now avaliable for not logged in users. - Un-pair process (*unPaidDevice* method) requires application restart if UCP SDK is used and card was already digitized for another user. - Login methods now clearing SDK data when device is removed from server When any login method fails with *BackendException* and *CANT\_FIND\_DEVICE* reason application should proceed with device pairing again. Version 2.10.0 - Added new method for adding address with NewAddress model. Previous method is deprecated now. - Added new method in Cards service: updateCard. - Added new methods in Addresses servive: updateAddress, deleteAddres. Version 2.10.1 - Removed false-positive security rules. - Improved security reports sent to Wallet Server. Version 2.11.2 - Added DeveloperOptions configuration in setup. - Added logout method. Version 2.11.3 - Updated security libraries. Version 2.11.5 - Added new optional to DeveloperOptions, introducing new security checks. - Added method verifyCard to verify card after 3DS. Card domain. - Extended TransactionsFilters in getTransactionHistory. Transaction history domain. - Added new method to addCard with AddCard model. The old method was marked as deprecated. Card domain. - Added new response parameter to getAll method. Card domain. - Added new request parameter to updateCard method. Card domain. - Added new permission: QUERY\_ALL\_PACKAGES for security checks. Version 2.11.6 - Minor fixes in user session. Version 2.11.8 - Added new method for initializing reset user password with InitializeResetUserPassword model. Previous method is deprecated now. Version 2.11.10 - Added new chapter Firebase Cloud Messaging configuration. - Updated Security processes overview with Error codes handling in application. - Introduced new approach to handling security issue. To provide better experience new status was added CoreSdkException with reason SECURITY\_EVENT\_OCCURRED. Error could be provided in every SDK methods if security issue was detected. Change doesn't impact on onSecurityIssue callback. Version 2.11.12 - Added more protections for Android Keystore issues related to access by retrying and adding multi-thread synchronization. Version 2.12.0 - IMPORTANT Updated security tools after EMV Security Evaluation. Please refer to [setup.](https://wiki.verestro.com/pages/viewpage.action?pageId=67340696) and [Application Isolated Process](https://wiki.verestro.com/display/UCP/Application+Isolated+Process). - added new security checks which which requires additional action on application side, - added new fields in DeveloperOptions object - allowDebug and enableAdditionalSecurityChecks. - Updated Gradle and R8 tools. - Added new methods related to transaction history and attachment in TransactionsHistoryService: - getTransactionDetails, - storeAttachment, - generateAttachmentLink, - deleteAttachment. - Added new fields related to MCC (mcc, mccCategory) in methods getTransactionHistory and getTransactionDetails. Version 2.12.1 - Fixed aggressive security process check from MDC SDK 2.12.0. Version 2.13.2 - Updated documentation for Application Isolated Process with Magisk information. - Updated recommended configuration and documentation for *extractNativeLibs* flag configuration, native libs should be in uncompressed form. Read more in Basic configuration section. - Isolated security process mechanism improvements (related to *enableAdditionalSecurityChecks* configuration flag). - Update Kotlin version to Kotlin version to 1.5.31 and Koin to 2.1.6. - Updated Jackson dependency to 2.13.2 (with jackson-databind 1.13.2.2 security patch). - Added new methods: - initialize3DSv2 in Cards domain, - finalize3DSv2 in Cards domain, - deleteUser in User domain. - Added new field "nip" in AddUser model. - Added logs for all facade methods (available in SDK debug version). Version 2.13.3 - **IMPORTANT** Removed security check for disabling permission QUERY\_ALL\_PACKAGES i application AndroidManifest file. Read more in Basic configuration : Android permission chapter. Version 2.13.5 - Added new value in additional DeveloperOptions, responsible for verification SDK code obfuscation. - Added information about using SDK on Android API 31+ in [Basic Configuration](https://wiki.verestro.com/pages/viewpage.action?pageId=67340661) chapter. - Wraped in try-catch block callbacks from setup method to prevent process breaking in SDK. Version 2.13.6 - Added new returned fields to methods: *getTransactionsHistory* and *getTransactionDetails.* Version 2.14.5 - **Important!** Introduced Play Integrity API instead Safetynet Attestation API - could require additional configuration. Read more in *Security processes overview* chapter*.* Enabling *r*equires Google API console changes. - **Important!** Added optional configuration method - *MobileDcCloudMessagingConfiguration.* Interface allows to register not-paired devices in SSE service provided by Verestro. Significally optimizes RNS message delivery, usage is strongly recommended. - Added method *updateSingleTransactionData* in transactions history service. - Added new methods for device pairing - old methods became deprecated. - Added new fileld optional to new *pair device* methods - *externalDeviceId.* - Introduced *RefreshSession* mechanism for user HTTP token management - extends a duration of session and allows to use SDK methods.