Flutter Integration

Integration guide for integration Equal ID Gateway in Flutter Application

The Embedded Flow for Flutter is a flexible module designed to integrate seamlessly into your flutter application. This module enables users to complete their verification process directly within the app, ensuring a consistent, uninterrupted onboarding experience.

Step-by-Step Integration

Step 1:

When a consumer initiates the ID verification process, you backend service must trigger the initialisation of identity exchange transaction.
Follow the Initialize Transaction API guide to integrate with the API in your backend server.

Step 2:

Add the following dependency to your pubspec.yaml file:

# Add the Equal SDK dependency
  dependencies:
    equal_sdk:
      git:
        url: https://github.com/inifity-tech/equal_flutter_sdk.git

Run the following command to fetch the dependency:

flutter pub get

Step 3: Launch Identity Gateway

Once the transaction is initialized, the Equal ID Gateway can be opened from the client. Follow these steps to integrate and launch Equal Gateway through the Flutter SDK.

Modify AndroidManifest.xml

Add the following to the android/src/main/AndroidManifest.xml file:

<provider
android:name="com.pichillilorenzo.flutter_inappwebview_android.InAppWebViewFileProvider"
  android:authorities="${applicationId}.flutter_inappwebview_android.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths" />
</provider>

Launch the SDK

import 'package:equal_sdk_flutter/equal_sdk_flutter.dart';
import 'package:equal_sdk_flutter/model/equal_sdk_params.dart';


void launchEqualSDK(BuildContext context) {
 EqualSDK.instance.launchSDK(
   context: context,
   equalSdkConfig: EqualSDKConfig(
     clientId: "#clientID",
     idempotencyId: "# idempotencyId",
     token: "#token",
     mobile: "#mobile"
   ),
   onSubmit: (data) {
     // handle success response
   },
   onError: (data) {
     //handle error response
   },
 );

}

SDK Parameters

ParameterMandatory/OptionalDescription
clientIdMandatoryShared by Equal during onboarding.
idempotencyIdMandatoryCreated by your system during the Initialize Transaction API as part of Step 1.
tokenMandatoryGenerated and shared in response from Step 1.
mobileoptionalFor 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

The launchSDK method of EqualSDK accepts the following callbacks methods:

  • onError: this is Invoked by SDK when
    • There are failures in opening the Gateway.
    • The Gateway is opened successfully, but the user closes it without submitting the transaction.
  • onSubmit: Invoked when the Gateway is successfully opened and the user submits the transaction.

❗️

Handle async data sharing after submission.

After a transaction is submitted, the frontend will trigger onSubmitCallback. If the next user steps require this data, show a loading indicator and wait about 10 seconds (90th percentile) for the backend to retrieve the data from Equal. Periodically check the status for up to 30 seconds before either stopping the process or restarting customer verification.


If OCR required in your configuration:


SDK Required Camera Permission (Optional for Digital key verification):

Add Dependency in pubspec.yaml

dependencies:
  permission_handler:

Run the following command to fetch the dependency:

flutter pub get

Android

Add the following permissions to the AndroidManifest.xml file:

<uses-permission android:name="android.permission.CAMERA" />

Add the following keys to your Info.plist file:

<key>NSCameraUsageDescription</key>
<string>We need access to your camera to capture photos</string>

Request Permissions before invoking Equal.

import 'package:permission_handler/permission_handler.dart';

Future<void> requestCameraPermission() async {
  if (await Permission.camera.request().isGranted) {
    print("Camera permission granted");
  } else {
    print("Camera permission denied");
  }
}

Step 4: Data Fetching

  • After the consumer completes the transaction, the Identity Data will be transmitted to the business via the callback URL.
  • 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

ScenarioHTTP Status CodeStatusMessage
When the request is successful and details are available.200SUCCESSCallback payload preparation success
Client ID/ Client Secret is wrong.400FAILUREInvalid credentials
When the request is in the wrong format.400FAILUREInvalid request body
Too many requests429No object will be sent, throttling happens at the gateway level.
Any unhandled error from Equal end500FAILURESomething went wrong, please try again.

Key Status

StatusDescription
VERIFIEDData is retrieved from the source of truth.
CHECKEDData is derived or obtained from third parties.
IN_PROGRESSCurrently verifying data with the official source or third parties.
FAILEDUser-shared data is invalid or incorrect.
UNVERIFIEDUser-shared data without confirmation from official sources.
USER_DONT_HAVEUser 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.