flutter_digilocker_aadhar_pan 1.0.0 copy "flutter_digilocker_aadhar_pan: ^1.0.0" to clipboard
flutter_digilocker_aadhar_pan: ^1.0.0 copied to clipboard

Flutter plugin for seamless DigiLocker Aadhar and PAN verification integration.

flutter_digilocker_aadhar_pan #

Flutter plugin for seamless DigiLocker Aadhar and PAN verification integration.

Features #

  • ✅ Easy integration with DigiLocker API
  • ✅ Automatic token management and state handling
  • ✅ WebView-based secure verification flow
  • ✅ Support for Aadhar and PAN verification
  • ✅ Optional PAN pre-fill functionality
  • ✅ Customizable document selection
  • ✅ Loading indicators and error handling
  • ✅ Clean modal-based UI
  • ✅ Type-safe response handling

Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  flutter_digilocker_aadhar_pan: ^1.0.0

Then run:

flutter pub get

Platform Setup #

Android

Add internet permission in your android/app/src/main/AndroidManifest.xml:

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

iOS

Add the following to your ios/Runner/Info.plist:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

Usage #

Basic Example #

import 'package:flutter/material.dart';
import 'package:flutter_digilocker_aadhar_pan/flutter_digilocker_aadhar_pan.dart';

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _showDigiLocker = false;

  final config = const DigiLockerConfig(
    companyName: 'your-company-name',
    secretToken: 'your-secret-token',
    redirectUrl: 'https://your-redirect-url.com',
    documents: 'aadhaar,pan', // Optional: default is 'aadhaar,pan'
    panName: '',               // Optional: PAN card holder name
    panNo: '',                 // Optional: PAN number
  );

  void _handleSuccess(DigiLockerResponse response) {
    print('DigiLocker Success: ${response.toJson()}');
    
    // Access user data
    print('Name: ${response.data?.name}');
    print('Aadhar: ${response.data?.aadharNo}');
    print('PAN: ${response.data?.panNumber}');
  }

  void _handleError(String error) {
    print('DigiLocker Error: $error');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            setState(() {
              _showDigiLocker = true;
            });
          },
          child: Text('Verify with DigiLocker'),
        ),
      ),
      // Show DigiLocker widget when needed
      body: Stack(
        children: [
          // Your main content here
          if (_showDigiLocker)
            DigiLockerWidget(
              config: config,
              onSuccess: _handleSuccess,
              onError: _handleError,
              onClose: () {
                setState(() {
                  _showDigiLocker = false;
                });
              },
            ),
        ],
      ),
    );
  }
}

Configuration #

DigiLockerConfig #

Property Type Required Default Description
companyName String Yes - Your company name registered with DigiLocker API
secretToken String Yes - Your secret token for API authentication
redirectUrl String Yes - URL to redirect after verification completion
documents String No 'aadhaar,pan' Comma-separated list of documents to fetch
panName String No '' PAN card holder name (leave empty to skip)
panNo String No '' PAN number (leave empty to skip)

DigiLockerWidget Props #

Prop Type Required Description
config DigiLockerConfig Yes Configuration object containing API credentials and options
onSuccess Function(DigiLockerResponse) Yes Callback function called when verification is successful
onError Function(String) Yes Callback function called when an error occurs
onClose VoidCallback Yes Callback function to close the widget

Response Data Structure #

The onSuccess callback receives a DigiLockerResponse object with the following structure:

DigiLockerResponse {
  int code;              // 200 for success
  bool success;          // true/false
  String status;         // "success" or "error"
  String msg;            // Response message
  DigiLockerData? data;  // User verification data
}

DigiLockerData {
  String? name;
  String? aadharNo;
  String? aadharAddress;
  String? aadharFilename;
  String? aadharImgFilename;
  String? aadharXml;
  String? adharimg;
  String? dob;
  String? gender;
  String? fathername;
  String? house;
  String? locality;
  String? dist;
  String? state;
  String? country;
  String? pincode;
  String? panNumber;
  String? nameOnPan;
  String? panImagePath;
  String? dateTime;
  Map<String, dynamic>? otherDocumentsFiles;
}

Advanced Examples #

With PAN Details Pre-filled #

final config = const DigiLockerConfig(
  companyName: 'democompany',
  secretToken: 'your-secret-token',
  redirectUrl: 'https://digilocker.meon.co.in/digilocker/thank-you-page',
  documents: 'aadhaar,pan',
  panName: 'JOHN DOE',        // Pre-fill PAN name
  panNo: 'ABCDE1234F',         // Pre-fill PAN number
);

Fetch Only Aadhar #

final config = const DigiLockerConfig(
  companyName: 'democompany',
  secretToken: 'your-secret-token',
  redirectUrl: 'https://your-redirect-url.com',
  documents: 'aadhaar',        // Only fetch Aadhar
);

Full Integration Example #

import 'package:flutter/material.dart';
import 'package:flutter_digilocker_aadhar_pan/flutter_digilocker_aadhar_pan.dart';

class VerificationScreen extends StatefulWidget {
  @override
  _VerificationScreenState createState() => _VerificationScreenState();
}

class _VerificationScreenState extends State<VerificationScreen> {
  bool _showDigiLocker = false;
  DigiLockerResponse? _response;

  final config = const DigiLockerConfig(
    companyName: 'your-company-name',
    secretToken: 'your-secret-token',
    redirectUrl: 'https://your-redirect-url.com',
  );

  void _handleSuccess(DigiLockerResponse response) {
    setState(() {
      _response = response;
      _showDigiLocker = false;
    });

    // Show success message
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text('Verification Successful!'),
        backgroundColor: Colors.green,
      ),
    );

    // Navigate to next screen or save data
    // Navigator.push(...);
  }

  void _handleError(String error) {
    setState(() {
      _showDigiLocker = false;
    });

    // Show error message
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text('Error: $error'),
        backgroundColor: Colors.red,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('KYC Verification'),
      ),
      body: Stack(
        children: [
          Padding(
            padding: EdgeInsets.all(20),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                if (_response != null) ...[
                  Card(
                    child: Padding(
                      padding: EdgeInsets.all(16),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text('Name: ${_response!.data?.name ?? 'N/A'}'),
                          SizedBox(height: 8),
                          Text('Aadhar: ${_response!.data?.aadharNo ?? 'N/A'}'),
                          SizedBox(height: 8),
                          Text('PAN: ${_response!.data?.panNumber ?? 'N/A'}'),
                        ],
                      ),
                    ),
                  ),
                  SizedBox(height: 20),
                ],
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _showDigiLocker = true;
                    });
                  },
                  child: Text('Start Verification'),
                ),
              ],
            ),
          ),
          if (_showDigiLocker)
            DigiLockerWidget(
              config: config,
              onSuccess: _handleSuccess,
              onError: _handleError,
              onClose: () {
                setState(() {
                  _showDigiLocker = false;
                });
              },
            ),
        ],
      ),
    );
  }
}

Requirements #

  • Flutter >= 3.3.0
  • Dart >= 3.6.2
  • Android: minSdkVersion 19
  • iOS: iOS 11.0+

Notes #

  • The panName and panNo fields are optional. If you don't provide them, they will default to empty strings
  • Users can provide their own PAN details through your app UI before opening DigiLocker
  • The plugin automatically manages API tokens and state internally
  • All API calls are handled securely within the plugin
  • Make sure to handle errors appropriately in production apps
  • Test thoroughly with your DigiLocker API credentials before deploying

API Endpoints #

This plugin uses the following DigiLocker API endpoints:

  1. Get Access Token: POST /get_access_token
  2. Get DigiLocker URL: POST /digi_url
  3. Send Entire Data: POST /v2/send_entire_data

Base URL: https://digilocker.meon.co.in

Troubleshooting #

WebView not loading #

Make sure you have added the required permissions for Android and iOS as mentioned in the Platform Setup section.

API errors #

Verify that your companyName and secretToken are correct and active.

Network errors #

Ensure your device/emulator has internet connectivity and can access the DigiLocker API endpoints.

Security #

  • Never commit your secretToken to version control
  • Store API credentials securely (use environment variables or secure storage)
  • Always use HTTPS for redirect URLs in production
  • Implement proper error handling and logging

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

License #

This project is licensed under the MIT License - see the LICENSE file for details.

Support #

For issues and feature requests, please visit our GitHub repository.

Author #

Dhananjay Singh - dhananjay@meon.co.in

Changelog #

See CHANGELOG.md for a list of changes.

Acknowledgments #

  • DigiLocker API by Government of India
  • Flutter team for the amazing framework