Android - Core Module¶
The Core Module is the module that provides the basic structure and functionality for the use of all other modules. It hosts reusable components and infrastructure across the project. The Core Module must be added to the project before using all other modules.
Adding to the Project¶
After ensuring that Maven accesses are provided, follow these steps. (See Getting Started)
1. Add to libs.versions.toml file:¶
[versions]
...
enqualify-plus = "x.x.x.x"
[libraries]
...
enqualify-plus-core = {
group = "com.enqualify.plus",
name = "core",
version.ref = "enqualify-plus"
}
2. Add dependency to build.gradle.kts file:¶
3. Gradle Sync¶
Sync the Gradle files by clicking the "Sync Now" option.
ℹ️ The version number to be used will be communicated to you specifically. All modules must use the same version.
Permissions¶
To obtain detailed information about the network connection type (2G/3G/4.5G), the following permission must be manually obtained by the application:
⚠️ This permission is not automatically requested by the SDK. If permission is not granted, the mobile data type is only displayed as
"Mobile".
Data Models¶
BaseModel¶
This is the data model that contains the server (backoffice) connection address and SSL certificate information used in validation processes.
Signalling (Video Call) and MAPI certificates can be provided in both file format and Base64 format; it is not necessary to provide both formats together. Certificate files should be added to the res/raw folder inside the Android project, and the same file name should be provided as a parameter in this model. If the certificate is not provided, the SDK operates without SSL Pinning feature.
data class BaseModel(
var baseURL: String, // Required field
var signallingCertificateList: List<String>? = null,
var mapiCertificateList: List<String>? = null,
var signallingCertificateBase64List: List<String>? = null,
var mapiCertificateBase64List: List<String>? = null,
var mobileUser: String, // Required field
var countryCode: String? = null, // Default: "TUR"
var locale: String = "TR",
var useEmbeddedLocalSound: Boolean = false
)
Features¶
| Feature | Type | Required | Description |
|---|---|---|---|
baseURL | String | ✅ | The base server address used for API validation processes |
mobileUser | String | ✅ | The special keyword used during the token process |
signallingCertificateList | List<String?>? | — | An array of Signalling (VC) certificates in text format |
mapiCertificateList | List<String?>? | — | An array of MAPI certificates in text format |
signallingCertificateBase64List | List<String?>? | — | An array of Signalling certificates in Base64 format |
mapiCertificateBase64List | List<String?>? | — | An array of MAPI certificates in Base64 format |
countryCode | String | — | The country code of the identity to be read |
locale | String | — | The language of voice prompts and texts (default: "TR") |
useEmbeddedLocalSound | Boolean | — | Determines whether sounds will be used locally or from the service (default: false) |
Usage Example¶
val baseModel = BaseModel(
signallingCertificateList = listOf("AI_CERT_1", "AI_CERT_2"),
mapiCertificateList = listOf("MAPI_CERT_1", "MAPI_CERT_2"),
signallingCertificateBase64List = listOf("QUlDRVJU...", "Q0VSVF8y..."),
mapiCertificateBase64List = listOf("TU9SRSB...", "Q0VSVF8z..."),
baseURL = "API_SERVER_URL",
mobileUser = "mobile",
countryCode = "TUR",
locale = "TR",
useEmbeddedLocalSound = false
)
SessionModel¶
This is the data model that contains the user and identity information during a call session. It includes call type, user details, identity information, and additional parameters related to the session.
data class SessionModel(
var callType: String, // Required field
var reference: String, // Required field
var userName: String? = null,
var surname: String? = null,
var phone: String? = null,
var email: String? = null,
var identityType: String? = null,
var identityNo: String? = null,
var canAutoClose: Boolean = false,
var isContinue: Boolean = false, // isContinue due to 'continue' being reserved in Kotlin
var category: String? = null,
var taxNumber: String? = null,
var businessReference: String? = null,
var handicapped: Boolean? = false
)
Features¶
| Feature | Type | Required | Description |
|---|---|---|---|
callType | String | ✅ | Parameter indicating the type of call (e.g., "NewCustomer") |
reference | String | ✅ | Reference ID for the session |
userName | String? | — | User's first name |
surname | String? | — | User's last name |
phone | String? | — | User's phone number |
email | String? | — | User's email address |
identityType | String? | — | Identity type (e.g., "I", "P") |
identityNo | String? | — | User's identity number |
canAutoClose | Boolean | — | Determines whether the session can automatically close (default: false) |
isContinue | Boolean | — | Determines whether the session is an ongoing process (default: false) |
category | String? | — | The category to which the session belongs |
taxNumber | String? | — | Tax number belonging to the user |
businessReference | String? | — | Reference information related to the business |
handicapped | Boolean? | — | Flag indicating whether the user is handicapped (default: false) |
Usage Example¶
val session = SessionModel(
callType = "NewCustomer",
reference = UUID.randomUUID().toString(),
userName = "Enqura",
surname = "Information",
phone = "+905551234567",
email = "enqualifyplus@enqura.com",
identityType = "TC. Kimlik Kartı",
identityNo = "12345678901",
canAutoClose = true,
isContinue = false,
category = "category",
taxNumber = "9876543210",
businessReference = "COMPANY",
handicapped = false
)
CustomerIDDoc¶
This is the data model in which the data read from the identity document as a result of the OCR process is stored. It operates in a Singleton structure; data is accessed with CustomerIDDoc.getInstance().
For detailed information, see the OCR Module page.
class CustomerIDDoc {
var identityType: String = ""
var name: String = ""
var surname: String = ""
var identityNumber: String = ""
var issuingState: String = ""
var documentNumber: String = ""
var dateOfBirthDay: String = ""
var expiryDate: String = ""
var nationality: String = ""
var gender: String = ""
var frontImage: Bitmap? = null
var mrzImage: Bitmap? = null
var holoImage: Bitmap? = null
var face: Bitmap? = null
var frontIdentityNumber: String? = null
var frontExpiryDate: String? = null
var frontBirthDate: String? = null
var frontGender: String? = null
var frontDocumentNumber: String? = null
var optionalData1: String? = null
var optionalData2: String? = null
var mrzText: String? = null
val visualItems: MutableMap<String, VisualItem> = mutableMapOf()
var digitDocumentNumber: Char? = null
var digitDateOfBirth: Char? = null
var digitExpiryDate: Char? = null
var sumDigit: Char? = null
}
Features¶
| Feature | Type | Description |
|---|---|---|
identityType | String | Type of identity ("I" or "P") |
name | String | First name of the identity holder |
surname | String | Surname of the identity holder |
identityNumber | String | Identity number |
issuingState | String | Country/region code where the identity was issued |
documentNumber | String | Document number of the identity |
dateOfBirthDay | String | Date of birth of the identity holder |
expiryDate | String | Expiry date of the identity |
nationality | String | Country code of the identity holder's citizenship |
gender | String | Gender (M/F, K/F, etc.) |
frontImage | Bitmap? | Image of the front face of the identity (may be empty for identities with MRZ on the front) |
mrzImage | Bitmap? | Visual of the MRZ area |
holoImage | Bitmap? | Visual of the hologram area |
face | Bitmap? | Photo on the identity (may be empty for identities under 18 years) |
frontIdentityNumber | String? | Identity number taken from the front |
frontExpiryDate | String? | Expiry date taken from the front |
frontBirthDate | String? | Date of birth taken from the front |
frontGender | String? | Gender information taken from the front |
frontDocumentNumber | String? | Document number taken from the front |
optionalData1 | String? | Optional data 1 in the MRZ area |
optionalData2 | String? | Optional data 2 in the MRZ area |
mrzText | String? | Full text in the MRZ area |
visualItems | MutableMap<String, VisualItem> | Visuals of objects detected after visual analysis |
digitDocumentNumber | Char? | Validation digit of the document number in the MRZ |
digitDateOfBirth | Char? | Validation digit of the date of birth in the MRZ |
digitExpiryDate | Char? | Validation digit of the expiry date in the MRZ |
sumDigit | Char? | General validation digit of the MRZ area |
Usage Example¶
private lateinit var customerIdDoc: CustomerIDDoc
override fun init() {
customerIdDoc = CustomerIDDoc.getInstance()
initPage()
}
CustomerChip¶
This is the data model in which the data read from the identity chip as a result of the NFC reading process is stored. It also includes the results of NFC security protocols such as BAC, CA, HT, AA, and CS. It operates in a Singleton structure; data is accessed with CustomerChip.getInstance().
For detailed information, see the NFC Module page.
class CustomerChip {
var documentCode: DocumentCode = DocumentCode.I
var identityType: String? = null
var identityNo: String? = null
var documentNo: String? = null
var firstName: String? = null
var lastName: String? = null
var gender: String? = null
var birthDate: String? = null
var nationality: String? = null
var expiryDate: String? = null
var faceImage: Bitmap? = null
var nameOfHolder: String? = null
var surnameOfHolder: String? = null
var placeOfBirth: String? = null
var fullDateOfBirth: String? = null
var BAC: NFCFeatureWithResult<Boolean> = NFCFeatureWithResult()
var CA: NFCFeatureWithResult<EACCAResult> = NFCFeatureWithResult()
var HT: NFCFeatureWithResult<MutableMap<Int, HashMatchResult>?> = NFCFeatureWithResult()
var AA: NFCFeatureWithResult<AAResult> = NFCFeatureWithResult()
var CS: NFCFeatureWithResult<Boolean> = NFCFeatureWithResult()
}
Basic Features¶
| Feature | Type | Description |
|---|---|---|
documentCode | DocumentCode | Enum value indicating the type of document |
identityType | String? | Type of the identity document |
identityNo | String? | Identity document number |
documentNo | String? | Official document number |
firstName | String? | First name of the document holder |
lastName | String? | Surname of the document holder |
gender | String? | Gender information |
birthDate | String? | Date of birth |
nationality | String? | Country of citizenship |
expiryDate | String? | Expiry date of the document |
faceImage | Bitmap? | Biometric photo obtained from the chip (used for comparison with the Face module) |
nameOfHolder | String? | Local name of the document holder |
surnameOfHolder | String? | Local surname of the document holder |
placeOfBirth | String? | Place of birth |
fullDateOfBirth | String? | Full date of birth (day, month, year) |
NFC Security Protocol Results¶
| Feature | Type | Description |
|---|---|---|
BAC | NFCFeatureWithResult<Boolean> | Basic Access Control — result of the document reading security protocol (true: successful) |
CA | NFCFeatureWithResult<EACCAResult> | Chip Authentication — result of chip identity authentication |
HT | NFCFeatureWithResult<MutableMap<Int, HashMatchResult>?> | Hash Table — hash value verification results |
AA | NFCFeatureWithResult<AAResult> | Active Authentication — result of identity authentication with asymmetric encryption |
CS | NFCFeatureWithResult<Boolean> | Chip Signature — validity result of chip signature (true: valid) |
Usage Example¶
private lateinit var customerChip: CustomerChip
override fun init() {
customerChip = CustomerChip.getInstance()
initPage()
}
CustomerFace¶
This is the data model in which the data obtained from the face recognition and liveliness check processes is stored. It operates in a Singleton structure; data is accessed with CustomerFace.getInstance().
For detailed information, see the Face Module page.
Basic Features¶
| Feature | Type | Description |
|---|---|---|
faceDetectedImage | Bitmap? | Image of the face detected by the camera |
smilingDetectedImage | Bitmap? | Image obtained when a smile is detected |
possibilityOfSmiling | Float? | Probability of smiling (between 0 and 1) |
faceLeftDetectedImage | Bitmap? | Image obtained when the head is turned left |
faceRightDetectedImage | Bitmap? | Image obtained when the head is turned right |
faceUpDetectedImage | Bitmap? | Image obtained when the head is raised |
eyeCloseDetectedImage | Bitmap? | Image obtained when the eyes are closed |
antiSpoofing | Double? | Score for detecting spoofing |
antiSpoofingValidityLevel | Int? | Anti-spoofing validity level |
idDocConfidence | Int? | Confidence degree of the identity photo compared to the face |
idDocDistance | Double? | Distance between identity document and face |
chipConfidence | Int? | Confidence degree of the NFC chip biometric compared to the face |
chipDistance | Double? | Distance between the NFC chip and the face |
IntegrationModel¶
This is the data model used to send data through the SDK during the integration phase via the addIntegration function.
data class IntegrationModel(
val phone: String? = null,
val email: String? = null,
val formUrl: String? = null,
val idRegistration: IDRegistration? = null,
val addressRegistration: AddressRegistration? = null,
val data: String
)
Proguard Rules¶
In release packages (minifyEnabled = true, debuggable = false), add the following rules to the proguard-rules.pro file for the Core SDK to function correctly:
-keep interface com.enqualify.plus.core.CoreCallbacks { *; }
-keep public class com.enqualify.plus.core.** { *; }
-keepclassmembers class * { public static <methods>; }
-keep interface com.enqualify.plus.core.** { *; }
-keep class com.enqualify.plus.core.** { abstract *; }
-keep @androidx.annotation.Keep class * { *; }
-keepclassmembers,allowobfuscation class * { @androidx.annotation.Keep *; }
Root Certificate Trust (Sectigo R46)¶
The SSL certificates of Enqura servers are issued by the Sectigo certificate authority. Sectigo signs its certificates under the Sectigo Public Server Authentication Root R46 root certificate.
Why is this root certificate not found on some devices?¶
The trusted root certificate list on Android comes with the device and is not updated unless through a manufacturer update for devices prior to Android 14. Since R46 is a relatively new root published in 2021, it is not present in the list of many devices running Android 13 and below. These devices reject the connection when they cannot verify the server certificate with their own lists (Trust anchor for certification path not found).
SDK's Solution¶
The SDK considers the R46 root as trusted in addition to the device's system list for its own connections (API, signalling, and certificate checks). This allows the SDK flows to work smoothly even on older devices. This behavior has been present since v2.1.0.45 and v2.1.2.49.
ℹ️ This trust applies only to the SDK's own connections. The SDK does not change your application's network security configuration (
networkSecurityConfig) or theusesCleartextTrafficsetting. No additional action is required in the standard integration.
For Your Application's Own Connections¶
If your application connects to Enqura servers from your own code (WebView, your own HTTP client, etc.) outside the SDK and encounters certificate errors on older devices, you can add the R46 root certificate through the application manifest:
1. Download the R46 root certificate from Sectigo's official page and add it to your project as res/raw/sectigo_r46.cer.
2. Create the res/xml/network_security_config.xml file:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config>
<trust-anchors>
<certificates src="system" />
<certificates src="@raw/sectigo_r46" />
</trust-anchors>
</base-config>
</network-security-config>
3. Link the configuration to the <application> tag in AndroidManifest.xml:
⚠️ If you already have a
network_security_configin your application, do not create a new file; simply add the<certificates src="@raw/sectigo_r46" />line to the<trust-anchors>block in your existing file.⚠️ When a
networkSecurityConfigis defined, Android ignores theandroid:usesCleartextTrafficsetting and disables unencrypted (http) traffic. If you are using http connections in a development environment (e.g., React Native / Metro), place a copy of the same file starting with<base-config cleartextTrafficPermitted="true">undersrc/debug/res/xml/; your release build will not be affected.ℹ️ If you encounter certificate errors in SDK flows, please report them to our support team before making changes on the application side.
Next Steps¶
After completing the installation of the Core Module, you can proceed to the following modules according to your needs:
- OCR Module — Optical character recognition from identity documents
- NFC Module — NFC reading from identity chips
- Face Module — Face recognition and liveness detection
- VideoCall Module — Video call integration