Digi-Locker Integration with Flutter: A Comprehensive Guide 2025

Yashesh

Oct 07, 2024

8 min readLast Updated Oct 07, 2024

DigiLocker is a document wallet from the Government of India. Citizens can use it to store digital versions of various documents which include Aadhaar card, driving license, marks sheets, ration card and a lot more.

Documents are fetched into DigiLocker directly from source of the issuer and are deemed to be at par with original physical documents as per Rule 9A of the Information Technology Rules, 2016. Documents can also be uploaded by citizens, for storage on DigiLocker.Read more about DigiLocker and the various documents supported here.

DigiLocker: What can it do?

Fetch documents of your users instantly and directly from the issuing authority, with user consent. Use the fetched documents to perform KYC without any delay.

DigiLocker has a wide variety of documents—covering a large number of government organisations, educational institutions, banks etc. that can be leveraged to ease the onboarding and verification journeys for your customers.

Use Case: Why Integrate DigiLocker?

Many businesses and government services require users to submit and verify identity documents during registration. Traditional KYC (Know Your Customer) processes are often manual and time-consuming, requiring users to upload physical documents or scanned copies. DigiLocker integration solves this by allowing applications to:

  • Instantly fetch verified documents like Aadhaar, driving licenses, and academic records directly from the issuing authority.
  • Automate the KYC process, reducing the time taken to onboard new users.
  • Eliminate the risk of document fraud, as all documents are certified by the respective government agencies.
  • Improve the user experience by avoiding manual uploads and making the process more efficient.

DigiLocker Integration

Setu DigiLocker APIs can be used to fetch your users' documents instantly—with their consent.

Here's a quick run-through of the APIs

  • Create a DigiLocker request—Create a request to start the user journey, with which you can get user consent and then fetch the document from user’s digilocker. You get an id in response, which you can use to track this request throughout the journey.
  • Get DigiLocker request status—Check status of a request that was created by passing the request id, at any point in the journey.
  • Get list of all docs available—Get a global list of all documents that DigiLocker lets you fetch and the identifiers required to fetch a particular document.
  • Fetch a document—Get the document that the user has consented to share with you, made available as a file URL to download. All docs other than Aadhaar, can be fetched with this API.
  • Fetch Aadhaar data—Fetch Aadhaar document data in JSON format as well as an XML file. The API response is consistent with OKYC APIs, which aids in replacing OKYC with DigiLocker, for carrying out Aadhaar KYC.Revoke access token—Revoke the OAuth user token, once necessary user documents are fetched.

Additionally, here are the URLs you would need for these APIs

  • Sandbox — https://dg-sandbox.setu.co
  • Production — https://dg.setu.coHeaders — Contact Setu for providing the credentials required to successfully call Setu APIs. This contains:
x-client-id
x-client-secret
x-product-instance-id

Create a DigiLocker Request

Call this API to create a new DigiLocker request. Pass the redirectUrl in the request body.

Note: A DigiLocker account is not mandatory for a user to start this flow. If the user does not have a DigiLocker account, DigiLocker will automatically create an account during the consent journey. User has to sign up by providing their Aadhaar number and authenticate with the OTP sent to Aadhaar registered mobile number.

To sign up for DigiLocker, user should have linked their mobile number with Aadhaar.

Usage of the redirect URL

You have to provide a redirect Url in the request, which has to be a valid publicly hosted URL—the user gets redirected to this URL after going through DigiLocker Sign in / Sign up and consent screens.

It will also be used by Setu to send back relevant information about a request. By default Setu includes the success flag of the user consent and DigiLocker request id.

  • For a failed user consent, we will send back - <redirectUrl>?success={false}&id={Digilocker_request.id}&errCode={code}&errMessage={message}
  • For a successful signature - <redirect_url>?success={true}&id={Digilocker_request.id}
Note:You can also add custom query params such as session id from your end. You would append this to the provided URL, like so—(redirectUrl)?sessionId=XYZ

Request

POST /api/digilocker/ 
 
{ 
    "redirectUrl": "https://setu.co" 
} 

CURL :

curl --request POST \
  --url https://dg-sandbox.setu.co/api/digilocker \
  --header 'content-type: application/json' \
  --header 'x-client-id: test-client' \
  --header 'x-client-secret: 891707ee-d6cd-4744-a28d-058829e30f12' \
  --header 'x-product-instance-id: 891707ee-d6cd-4744-a28d-058829e30f10' \
  --data '{
    "redirectUrl": "https://setu.co"
}'

Response

You will get the following details—

  • Unique DigiLocker request id which can be used to manage this request.
  • The status will be unauthenticated for requests that do not have user consent yet and will change to authenticated once the user has provided their consent. You can check the status of a request at any point of time, using the Get DigiLocker request status API.
  • The url from the response should be used to redirect your user to Sign in / Sign up and provide consent to access their DigiLocker.Validity of this request in ISO 8601 format timestamp, after which the request is expired and deleted.
{ 
    "id": "ea31e1e6-96eb-4e56-a355-7bc51de94d24", 
    "status": "unauthenticated", //ENUM values—unauthenticated | authenticated |     revoked 
    "url": "User login url", 
    "validUpto": "2021-10-05T19:06:28+05:30"  
} 

Get a list of all docs avaiable

Call this API to get a global list of all documents that DigiLocker lets you fetch and the corresponding meta data for each document.

This list can be very huge and the response can take a few minutes. It is recommended that you store this list on your end for usage in your application.

Consider updating this list of documents only once every month or as needed, as it does not change very often.

Request

GET /api/digilocker/documents

CURL :

curl --request GET \

--url https://dg-sandbox.setu.co/api/digilocker/documents \
--header 'x-client-id: test-client' \
--header 'x-client-secret: 891707ee-d6cd-4744-a28d-058829e30f12' \
--header 'x-product-instance-id: 891707ee-d6cd-4744-a28d-058829e30f10'

Response

Each document in the response has the following details -

  • availableFormats is an array that specifies the formats in which the document is made available through DigiLocker.
  • description specifies the name of the document, as given by the document issuer.
  • docType is a short code that identifies the type of the document.
  • orgId is the code of the document issuer.orgName is the name of the document issuer
Note: To uniquely identify a document, both docType and orgId are necessary. Multiple issuers, with their unique orgId, can issue documents which can be of the same docType. A quick example would be driving license being issued by different states—the docType is same whereas the orgId differs.

parameters is an array that contains key-value pairs, which specifies the user-specific identifiers required to fetch the document. You can use the description to aid your user, to input information on your UI.

A document can require more than one parameter, as specified by the document issuer.description key-value pair in parameters array, is only for your information and should not to be passed as an identifier to fetch that document

{ 
    "documents": [ 
        { 
            "availableFormats": [ 
                "pdf" 
            ], 
            "description": "Pension Certificate", 
            "docType": "PECER", 
            "orgId": "002317", 
            "orgName": "Accountants General, Tripura", 
            "parameters": [ 
                { 
                    "description": "Account No./PPO No.", 
                    "name": "AC_NO" 
                } 
            ] 
        }, 
        { 
            "availableFormats": [ 
                "pdf" 
            ], 
            "description": "Provident Fund Member Passbook", 
            "docType": "PRFND", 
            "orgId": "002317", 
            "orgName": "Accountants General, Tripura", 
            "parameters": [ 
                { 
                    "description": "Account No./PPO No.", 
                    "name": "AC_NO" 
                }, 
                { 
                    "description": "Name of the member", 
                    "name": "MemberName" 
                } 
            ] 
        } 
    ] 
} 

Flutter Integration for DigiLocker

Now that we have a basic understanding of how DigiLocker works and the APIs required for integration, let's dive into the Flutter implementation. This part of the guide will walk you through setting up a simple Flutter application that interacts with the DigiLocker APIs using HTTP requests.

Step 1: Setting Up Your Flutter Project

  1. Create a New Flutter Project: If you haven't already, create a new Flutter project using the following command
flutter create digilocker_integration

Navigate to the project directory

cd digilocker_integration

2. Add Dependencies: To interact with the DigiLocker API, we'll need the http package to make network requests. Open your pubspec.yaml file and add the following dependency:

dependencies:

flutter:

sdk: flutter

http: ^0.13.4

3. Project Structure: We'll keep the project strucutre simple. Create the following directories and files

lib/
├── main.dart
└── services/
└── digilocker_service.dart

Step 2: Implementing DigiLocker API Calls

  1. Create the DigiLocker Services

    In the services/digilocker_service.dart file, create a class that handles the API calls to DigiLocker:
import 'dart:convert';
import 'package:http/http.dart' as http;


class DigiLockerService {
  final String baseUrl = "https://dg-sandbox.setu.co";
  final String clientId = "YOUR_CLIENT_ID"; // Replace with your client ID
  final String clientSecret = "YOUR_CLIENT_SECRET"; // Replace with your client     secret
  final String productInstanceId = "891707ee-d6cd-4744-a28d-058829e30f10"; // Replace with your product instance ID


  Future<Map<String, dynamic>> createDigiLockerRequest(String redirectUrl) async {
    final url = Uri.parse('$baseUrl/api/digilocker');
    final headers = {
      'Content-Type': 'application/json',
      'x-client-id': clientId,
      'x-client-secret': clientSecret,
      'x-product-instance-id': productInstanceId,
    };
    final body = jsonEncode({
      'redirectUrl': redirectUrl,
    });


    final response = await http.post(url, headers: headers, body: body);
    if (response.statusCode == 200) {
      return jsonDecode(response.body);
    } else {
      throw Exception('Failed to create DigiLocker request');
    }
  }


  Future<Map<String, dynamic>> getDigiLockerDocuments() async {
    final url = Uri.parse('$baseUrl/api/digilocker/documents');
    final headers = {
      'x-client-id': clientId,
      'x-client-secret': clientSecret,
      'x-product-instance-id': productInstanceId,
    };


    final response = await http.get(url, headers: headers);
    if (response.statusCode == 200) {
      return jsonDecode(response.body);
    } else {
      throw Exception('Failed to fetch DigiLocker documents');
    }
  }
}

2.  Handle API Responses

In the service class, we've created two methods: one to initiate a DigiLocker request and another to fetch the list of available documents. You can expand this service class with more methods as needed for other DigiLocker APIs, like fetching a document, revoking the access token, etc.

Step 3: Integrating DigiLocker in the Flutter UI/

  1. Create the Home Screen

In the lib/main.dart file, create a simple UI that allows users to initiate a DigiLocker request:

import 'package:flutter/material.dart';
import 'package:digilocker_integration/services/digilocker_service.dart';


void main() {
  runApp(MyApp());
}


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'DigiLocker Integration',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: DigiLockerScreen(),
    );
  }
}


class DigiLockerScreen extends StatefulWidget {
  @override
  _DigiLockerScreenState createState() => _DigiLockerScreenState();
}


class _DigiLockerScreenState extends State<DigiLockerScreen> {
  final DigiLockerService _digilockerService = DigiLockerService();
  String _digilockerUrl = '';
  String _status = '';


  void _createDigiLockerRequest() async {
    try {
      final result = await _digilockerService.createDigiLockerRequest('https://your-redirect-url.com');
      setState(() {
        _digilockerUrl = result['url'] ?? '';
        _status = result['status'] ?? 'unauthenticated';
      });
    } catch (e) {
      setState(() {
        _status = 'Error: ${e.toString()}';
      });
    }
  }


  void _fetchDocuments() async {
    try {
      final documents = await _digilockerService.getDigiLockerDocuments();
      print(documents); // You can display this on UI or process further
    } catch (e) {
      print('Error fetching documents: ${e.toString()}');
    }
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('DigiLocker Integration'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('DigiLocker Status: $_status'),
            SizedBox(height: 20),
            _digilockerUrl.isNotEmpty
                ? ElevatedButton(
                    onPressed: () {
                      // Navigate to DigiLocker URL
                      print('Navigate to $_digilockerUrl');
                    },
                    child: Text('Continue to DigiLocker'),
                  )
                : Container(),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _createDigiLockerRequest,
              child: Text('Start DigiLocker Request'),
            ),
            ElevatedButton(
              onPressed: _fetchDocuments,
              child: Text('Fetch Documents'),
            ),
          ],
        ),
      ),
    );
  }
}

2. Testing the Integration

  • Run your Flutter application on a emulator or device.
  • Press the "Start DigiLocker Request" button to initiate a request.
  • Upon successful initiation, you'll get a URL that you can use to navigate the user to DigiLocker for authentication and consent.
  • Use the "Fetch Documents" button to retrieve the list of available documents from DigiLocker.
  • Ensure you handle all possible errors gracefully, including network issues, API errors, and user cancellations.

Conclusion


By following this guide, you should be able to successfully integrate DigiLocker into your Flutter application, allowing your users to share their documents with your app securely. For more detailed information and advanced configurations, you can refer to the DigiLocker API documentation.

Projects Completed till now.

Discover how we can help your business grow.

"Third Rock Techkno's work integrates complex frameworks and features to offer everything researchers need. They are open-minded and worked smoothly with the academic subject matter."

- Dr Daniel T. Michaels, NINS

Related Resources

You May Also Like

Our Services

Related Resources

Our Services

You May Also Like