Android Integration
The Embedded Flow for Android is a flexible module designed to integrate seamlessly into your mobile application. It enables users to complete their verification process directly within the app, without disrupting their experience or requiring them to leave the application. This method ensures that user onboarding is conducted smoothly and securely, delivering a consistent and uninterrupted experience throughout the process.
Step-by-Step Integration
STEP 1
Initialise Transaction: When a consumer initiates the ID verification process, the business must trigger the identity exchange transaction from the backend service.
Follow this initialise transaction API guide to Initialise transaction
STEP 2
Launch Identity Gateway
Once the transaction is initialised, the Equal ID Gateway can be opened from the client using the below procedure:
- Add the following to the Project (top-level) build.gradle
allprojects {
repositories {
google()
mavenCentral()
maven {
url "https://android-gateway-plugin.s3.ap-south-1.amazonaws.com"
}
}
}
- Add the following dependancy to the app/build.gradle file
android {
...
buildFeatures {
viewBinding true
...
}
...
}
...
dependencies{
...
implementation group: 'com.equal.gatewaysdk', name: 'gatewaysdk', version: '1.2.3', ext: 'aar', classifier: 'release'
...
}
- To launch SDK.
EPlugin.getInstance().registerHandler(new EPluginParametersHandler() {
@Override
public void onEPluginHandler(EPluginParameters ePluginParameters) {
switch (ePluginParameters.getEventType()) {
case CLOSED_SDK:
//User closes the SDK. reason will be in the ePluginParameters.getMessage()
break;
case SUCCESS_SUBMIT:
//Submitted transaction id will be available with ePluginParameters.getTransactionId();
break;
}
}
@Override
public void onError(EPluginException e) {
}});
EPluginReq ePluginReq = new EPluginReq();
ePluginReq.setClientId("<Client ID shared by Equal>");
ePluginReq.setIdempotencyId("<Idempotency ID passed in the init API of step1>");
ePluginReq.setToken("<Token generated from the init API in step 1>");
//Mobile Number is Optional
ePluginReq.setMobileNumber("<Mobile number without country code>");
EPlugin.getInstance().launchSdk(MainActivity.this, ePluginReq);
EPlugin.getInstance().registerHandler(object : EPluginParametersHandler {
override fun onEPluginHandler(ePluginParameters: EPluginParameters) {
ePluginParameters.eventType?.let {
when (it) {
EventType.CLOSED_SDK -> {}
EventType.SUCCESS_SUBMIT -> {}
}
}
}
override fun onError(e: EPluginException) {}
})
val ePluginReq = EPluginReq()
ePluginReq.clientId = "<Client ID shared by Equal>"
ePluginReq.idempotencyId = "<Idempotency ID passed in the init API of step1>"
ePluginReq.token = "<Token generated from the init API in step 1>"
ePluginReq.mobileNumber = "<Mobile number without country code>";
EPlugin.getInstance().launchSdk(this@MainActivity, ePluginReq)
- Invoke the client SDK
- The details of the input parameters that the Equal SDK allows during invocation
SDK Parameter | Optional/ Mandatory | Description |
---|---|---|
client_id | Mandatory | Shared by Equal during onboarding |
idempotency_id | Mandatory | Created by your system during the Initialise Transaction API as part of Step 1 |
token | Mandatory | Generated and shared in response from Step 1 |
mobile | Optional | For better-connected user experience pass the 10-digit mobile of your user. This mobile number will be pre-filled with Equal Gateway when launched. |
SDK Callback Methods
openGateway method of EqualSDK accepts the following callbacks:
- onErrorCallback is invoked:
- When there are any failures in opening Gateway.
- When the Gateway was opened successfully but the user closed it without submitting the transaction.
- onSubmitCallback is invoked when the Gateway is successfully opened and user was able to submit the transaction.
Frontend status codes
onSubmitCallback will get the following status:
- TRANSACTION_PREVIOUSLY_SUBMITTED will be invoked when the transaction is previously submitted and in this transaction, the user would see "Data shared successfully" and the user would have closed the Gateway.
- onErrorCallback will be invoked when there are any failures in opening the gateway, or the consumer exited the gateway without submitting.
STEP 3
Data Sharing
- After the consumer completes the transaction, the Identity Data will be transmitted to the business via the callback URL.
- If a callback URL is provided in the initial request (Step 1), it will be used exclusively for this transaction.
- The callback includes Equal's digital signature to ensure data integrity. Businesses should securely store this signature for future verification purposes.
If the callback is not within the whitelisted domains registered with Equal (as part of business onboarding), the data will not be shared.
**Equal Digital Signature **
- After receiving the data callback at the configured URL, businesses are strongly encouraged to validate the eq-signature provided in the request headers.
- The eq-signature is generated by Equal based on the complete request body and the client secret used in the integration.
eq-signature : HMAC(callback_request_body_bytes, client_secret)
Note: SHA256 is the hashing algorithm used to calculate Hmac. The digest is represented as a HexString
An example JAVA code to calculate and verify HMAC
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class EqualCallBackSignatureVerificationHandler {
private static String calculateHmac(byte[] data, String key)
throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(secretKeySpec);
return bytesToHex(mac.doFinal(data));
}
private static String bytesToHex(byte[] bytes) {
final char[] hexArray = "0123456789abcdef".toCharArray();
char[] hexChars = new char[bytes.length * 2];
for (int j = 0, v; j < bytes.length; j++) {
v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
public static void main(String[] args) {
String message = "Request body in bytes";
String key = "client_secret";
String eq_signature = "68dc74f4cd540a3b9c57403d8bd4ad2c4411e64c3d2a60669b3398e2823eede2";
try {
String computedHmac = calculateHmac(message.getBytes(), key);
System.out.println("Computed Hmac = " + computedHmac);
System.out.println("EQ Signature from Callback Request Headers = "+ eq_signature);
} catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
If the business during signature validation generates the same signature from the request body and client secret, it guarantees the business that
- Data available in callback is intended for them.
- Data integrity is not compromised.
Businesses after validation of eq-signature must also ensure that the timestamp from the response is in the acceptable window as per their business requirement. Doing this step can increase the security of the business application by preventing any Replay Attacks.
Example Identity Data
Headers
eq-signature : <HMAC Digital signature with the client secret shared as key>
Payload
{
"status": "SUCCESS",
"message": "Callback payload preparation success",
"timestamp": 1675778341067,
"data": {
"timestamp": 1675778340931,
"version": 1,
"consumer_information": {
"consumer_id": "<Unique consumer ID>",
"mobile": "<Mobile number consumer used to login>"
},
"transaction_id": "<Unique ID corresponding to this transaction>",
"idempotency_id": "<Same idempotency_id passed part of initialise API>",
"response_metadata": {
"partner_id": "<The same partner_id sent as part of initialise API>"
},
"id_verification_report": "<S3 URL of IDV Report>",
"key_details": {
"AADHAAR": {
"key_name": "AADHAAR",
"key_status": "<VERIFIED | CHECKED>",
"key_data": [
{
"gender": "Male",
"address": "S/O,Satyamurthy Flat 10, Lake view apartment Somajiguda Beside Ramalayam Hyderabad Telangana 500001",
"address_street": "Lake view apartment",
"address_landmark": "Beside Ramalayam",
"address_house": "Flat 10",
"address_area": "Somajiguda",
"address_district": "Hyderabad",
"address_state": "Telangana",
"address_country": "India",
"address_pincode": "500001",
"key_id": "xxxxxxxx1234",
"dob": "13-08-1990",
"name": "Suresh Gudivada",
"photo": "<S3 URL of the photo if verified from digital data providers>",
"liveness_photo": "<S3 URL of the captured face photo if verified from user upload and face verification>",
"ocr_image": "<S3 URL of the user provided Aadhaar card photo if verified from user upload and face verification>"
}
]
},
"VOTER_ID": {
"key_name": "VOTER_ID",
"key_status": "<VERIFIED | CHECKED>",
"key_data": [
{
"name": "Suresh Gudivada",
"gender": "Male",
"age": "27",
"epic_number": "IDY1231231",
"key_id": "IDY1231231",
"family_member_name": "Satyamurthy Gudivada",
"family_member_relation": "FATHER",
"address_district": "Visakhapatnam",
"address_state": "Andhra Pradesh",
"assembly_constituency": "Visakhapatnam East",
"parliamentary_constituency": "Visakhapatnam",
"liveness_photo": "<S3 URL of the captured face photo if verified from user upload and face verification>",
"ocr_image": "<S3 URL of the user provided VoterID photo if verified from user upload and face verification>",
"key_source": "Election Commission Of INDIA",
"issuer_name": "Election Commission Of INDIA",
"key_name": "VOTER_ID",
"key_fetched_at": "<UTC time at which key was fetched>",
"verification_type": "<OCR if the verification is from user upload>"
}
]
},
"DRIVING_LICENSE": {
"key_name": "DRIVING_LICENSE",
"key_status": "<VERIFIED | CHECKED>",
"key_data": [
{
"name": "SURESH GUDIVADA",
"dl_number": "123123123123",
"dob": "13-08-1990",
"father_husband_name": "Naresh G",
"address": "Flat 10, Lake view apartment Somajiguda",
"photo": "<S3 Signed URL valid for 15 mins>",
"issued_date": "11-10-2020",
"expiry_date": "11-10-2030",
"authorized_to_drive": {
"abbreviation": "<TBD: Will update soon>",
"description": "<TBD: Will update soon>"
},
"liveness_photo": "<S3 URL of the captured face photo if verified from user upload and face verification>",
"ocr_image": "<S3 URL of the user provided Driving Licence photo if verified from user upload and face verification>"
}
]
},
"PAN": {
"key_name": "PAN",
"key_status": "VERIFIED",
"key_data": [
{
"gender": "Male",
"key_id": "ABCDE1234F",
"dob": "13-08-1990",
"name": "SURESH GUDIVADA"
}
]
},
"BANK_ACCOUNT": {
"key_name": "BANK_ACCOUNT",
"key_status": "VERIFIED",
"key_data": [
{
"name": "SURESH GUDIVADA",
"account_number": "123123123123",
"ifsc": "ICIC00000123",
"bank_name": "ICICI",
"branch_name": "Madhapur"
}
]
},
"BANK_STATEMENT": {
"keyName": "BANK_STATEMENT",
"keyStatus": "CHECKED",
"keyData": [
{
"account_number": "000000201220132014",
"account_type": "savings",
"key_id": "000000201220132014",
"key_report": "<S3 SIGNED URL of User Uploaded Documents. Valid for 60 mins>",
"transaction_list": "<S3 SIGNED URL of Row Level Transactions. Valid for 60 mins>",
"bank_statement_end_date": "30-06-2023",
"bank_statement_start_date": "02-01-2023",
"closing_balance": 787224.66,
"bank_name": "State Bank of India",
"name": "Mr SANDEEP KUMAR SAHU",
"opening_balance": 60912.66,
"is_tampered": "<true/false/null>",
"month_wise_analysis": [
{
"month_name": "JAN",
"no_of_debit_transactions": 41,
"no_of_credit_transactions": 7,
"total_credit_amount": 1468540,
"year": null,
"total_debit_amount": 1376611.5099999995,
"average_eod_balance": 95185.22
},
{
"month_name": "FEB",
"no_of_debit_transactions": 56,
"no_of_credit_transactions": 10,
"total_credit_amount": 209391,
"year": null,
"total_debit_amount": 231930.26999999996,
"average_eod_balance": 135913.81
}
]
}
]
},
"PF_PASSBOOK": {
"key_name": "PF_PASSBOOK",
"key_status": "VERIFIED",
"key_data": [
{
"registered_office": "(RO)HYDERABAD",
"net_balance": "0.0",
"uan": "100111405895",
"key_id": "APHYD15883880000010115",
"father_name": "NARESH G",
"dob": "13-08-1990",
"company_name": "INFOLABS SOLUTIONS PRIVATE LIMITED",
"name": "SURESH GUDIVADA",
"date_of_joining": "22-06-2018"
},
{
"registered_office": "(RO)BANGALORE",
"net_balance": "1234.0",
"uan": "100111405895",
"key_id": "BGBNG00423570000028912",
"father_name": "NARESH G",
"dob": "13-08-1986",
"company_name": "TESLA INDIA PRIVATE LIMITED",
"name": "SURESH GUDIVADA",
"date_of_joining": "09-06-2011"
},
{
"registered_office": "(RO)HYDERABAD",
"net_balance": "2520.0",
"uan": "100111405895",
"key_id": "APHYD00825270000011855",
"father_name": "NARESH G",
"dob": "13-08-1986",
"company_name": "INFY DEVELOPMENT PVT LTD",
"name": "SURESH GUDIVADA",
"date_of_joining": "24-02-2020"
}
]
},
"BUSINESS_DETAILS": {
"keyName": "BUSINESS_DETAILS",
"keyStatus": "VERIFIED",
"keyData": [
{
"business_name": "EQUAL IDENTITY PRIVATE LIMITED",
"key_id": "EQUAL IDENTITY PRIVATE LIMITED",
"gst_details": {
"business_name": "EQUAL IDENTITY PRIVATE LIMITED",
"gst_details_list": [
{
"taxpayer_type": "Regular",
"nature_of_business_list": [
"Supplier of Services"
],
"registration_date": "xx-xx-xxxx",
"registered_address": "2ND FLOOR, THE SKY VIEW, SY NO.83/1, SKKY VIEW 10, RAIDURG, HYDERABAD, Hyderabad, Telangana, 500081",
"business_constitution": "Private Limited Company",
"gst_state": "TELANGANA",
"gstin_active_status": "Active",
"contact_information": {
"name": "KESHAV GUNUPATI VENKAT REDDY",
"mobile_number": "770xxxxxxx",
"email": "[email protected]"
},
"legal_name": "EQUAL IDENTITY PRIVATE LIMITED",
"gstin": "36AAGCI4807C1ZU",
"trade_name": "EQUAL IDENTITY PRIVATE LIMITED"
}
]
},
"business_owners": {
"business_name": "EQUAL IDENTITY PRIVATE LIMITED",
"owners_list": [
{
"mca_signatory": {
"dsc_expiry_date": "xx-xx-xxxx",
"full_name": "RAJEEV RANJAN",
"din": "0952xxxx",
"designation": "Director",
"date_of_appointment": "xx-xx-xxxx"
},
"pan_details": {
"gender": "Male",
"dob": "xx-xx-xxxx",
"name": "RAJEEV RANJAN",
"pan": "AJNPRxxxxx"
},
"nationality": "IN",
"is_mca_signatory": true,
"verification_type": "DIGITAL",
"doc_type": "PAN"
}
]
},
"issuer_name": "MCA",
"key_name": "BUSINESS_DETAILS",
"business_details": {
"company_category": "Company limited by Shares",
"email_id": "[email protected]",
"class_of_company": "Private",
"company_sub_category": "Non-govt company",
"registered_address": "2nd Floor Skyview 10 the Skyview Sy No. 83/1 Raidurg Hyderabad Hyderabad TG 500081 IN ",
"active_compliance": "",
"registration_number": " 158xxx",
"name_as_per_mca": "EQUAL IDENTITY PRIVATE LIMITED",
"cin": "U72900TG202xxxxxxxxxx",
"authorised_capital": "300xxx",
"gst_list": [
{
"gst_state": "TELANGANA",
"gstin_active_status": "Active",
"gstin": "36AAGCI4807C1ZU"
}
],
"paid_up_capital": "19230760",
"roc_code": "RoC-Hyderabad",
"business_pan": "AAGCI4807C",
"date_of_incorporation": "xx-xx-xxxx",
"alternative_address": "-",
"mca_signatories": [
{
"dsc_expiry_date": "27-12-2023",
"full_name": "RAJEEV RANJAN",
"din": "09527564",
"designation": "Director",
"date_of_appointment": "04-05-2022"
}
],
"name_as_per_business_pan": "EQUAL IDENTITY PRIVATE LIMITED",
"company_status": "Active",
"is_company_listed": false
},
"business_type": "PRIVATE_LIMITED",
"key_source": "MCA",
"key_fetched_at": "2023-06-17T19:07:04.488+05:30"
}
]
}
},
"insights": {
"PERSONAL_DETAILS": {
"last_name": {
"value": "Suresh"
},
"middle_name": {
"value": ""
},
"first_name": {
"value": "Gudivada"
}
},
"DUPLICATE_CHECK": {
"repeat_status": "<true | false>",
"time_frame_from": "<Start date from which the duplicate check is processed>",
"time_frame_to": "<end date till which the duplicate check is processed>",
"current_transaction_date": "Transaction date of latest IDG",
"key_type": "<Key Type - AADHAAR>",
"key_id": "<Key ID in format xxxx-xxxx-xxxx>",
"name": "<Name as per the Key>",
"dob": "<DOB as the per Key>",
"gender": "<Gender as per the Key>",
"previous_transaction_details": [
{
"transaction_id_used": "<Previous transaction ID>",
"transaction_date": "<Previous transaction date>",
"elapsed_time": "<Elapsed duration from current transaction in millis>",
"consumer_id": "<Unique consumer ID used in the previous transaction>"
}
]
},
"BANK_STATEMENT_TRANSACTIONS_INSIGHT": {
"insight_attributes": {
"transaction_count_gt_5000": 10
}
}
}
}
}
Status Codes
Scenario | HTTP Status Code | Status | Message |
---|---|---|---|
When the request is successful and details are available. | 200 | SUCCESS | Callback payload preparation success |
Client ID/ Client Secret is wrong. | 400 | FAILURE | Invalid credentials |
When the request is in the wrong format. | 400 | FAILURE | Invalid request body |
Too many requests | 429 | No object will be sent, throttling happens at the gateway level. | |
Any unhandled error from Equal end | 500 | FAILURE | Something went wrong, please try again. |
Key Status
Status | Description |
---|---|
VERIFIED | Data is retrieved from the source of truth. |
CHECKED | Data is derived or obtained from third parties. |
IN_PROGRESS | Currently verifying data with the official source or third parties. |
FAILED | User-shared data is invalid or incorrect. |
UNVERIFIED | User-shared data without confirmation from official sources. |
USER_DONT_HAVE | User states they lack the specified ID. |
If the business need to fetch the identity data from Equal at a later point in time, then please follow Data Fetch API Document to retrieve data.
Updated 3 months ago