flutter_meon_digilocker 1.1.3
flutter_meon_digilocker: ^1.1.3 copied to clipboard
Flutter package for integrating Meon DigiLocker APIs with dynamic form fields and validation
Meon DigiLocker SDK for Flutter #
A Flutter package for integrating Meon DigiLocker APIs with dynamic form fields and validation. Includes searchable document dropdowns, complete document verification flow with WebView integration, and comprehensive error handling.
Features #
- ✅ 6 Complete API integrations with DigiLocker services
- ✅ Dynamic form fields based on document selection
- ✅ Searchable document dropdown for easy issuer and document discovery
- ✅ Comprehensive validation for all inputs
- ✅ Complete document verification flow with WebView integration
- ✅ All API calls handled internally - no need to manage complex API sequences
- ✅ Dynamic client credentials support for different environments
- ✅ TypeScript-inspired Dart models with proper serialization
- ✅ Material Design 3 compatible widgets
- ✅ Error handling with descriptive messages
- ✅ Customizable theming and styling
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
meon_digilocker_sdk: ^2.1.0
Or for local development:
dependencies:
meon_digilocker_sdk:
path: ../path/to/meon_digilocker_sdk
Then run:
flutter pub get
Platform Setup #
Android
Add internet permission to android/app/src/main/AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- ... other permissions ... -->
</manifest>
iOS
Add the following to ios/Runner/Info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>io.flutter.embedded_views_preview</key>
<true/>
Quick Start #
Simple Usage (Recommended) #
The easiest way to use this SDK is with the DigilockerForm widget. All API calls and logic are handled internally:
import 'package:flutter/material.dart';
import 'package:meon_digilocker_sdk/meon_digilocker_sdk.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: DigilockerForm(
companyName: 'your-company-name',
secretToken: 'your-secret-token',
onSuccess: (data) {
print('Document verification successful!');
// Handle the verified document data here
// data contains all the document information like:
// - aadhar_no, pan_number, name, dob, etc.
},
onError: (error) {
print('Error: $error');
// Handle errors here
},
),
);
}
}
That's it! The DigilockerForm component handles:
- Loading issuers
- Loading documents
- Loading form fields
- Form submission
- WebView handling
- Final data retrieval
Advanced Usage (SDK Methods) #
If you need more control, you can use the SDK methods directly:
import 'package:meon_digilocker_sdk/meon_digilocker_sdk.dart';
// Initialize SDK with your credentials
final sdk = MeonDigilockerSDK(
companyName: 'democapital',
secretToken: 'cy7Kw2rWqdzVo2KPxlU0ymd9uRQKPSsb',
);
// Get access token
final tokenResponse = await sdk.getAccessToken();
print(tokenResponse.clientToken);
// Search for issuers
final issuersResponse = await sdk.getListOfIssuersInDetail(
GetListOfIssuersInDetailParams(
clientToken: tokenResponse.clientToken,
state: tokenResponse.state,
search: 'insurance',
),
);
// Generate DigiLocker URL
final urlResponse = await sdk.generateDigiUrl(
GenerateDigiUrlParams(
clientToken: tokenResponse.clientToken,
redirectUrl: 'https://your-app.com/callback',
companyName: 'your-company-name',
otherDocuments: [
{
'doctype': 'PAN',
'orgid': 'ORG001',
'consent': 'Y',
'pan_number': 'ABCDE1234F',
}
],
),
);
// Get final verification data
final finalData = await sdk.sendEntireData(
SendEntireDataParams(
clientToken: tokenResponse.clientToken,
state: tokenResponse.state,
status: true,
),
);
Using Individual Components #
You can also use the individual Flutter widgets:
import 'package:flutter/material.dart';
import 'package:meon_digilocker_sdk/meon_digilocker_sdk.dart';
class CustomDigilockerForm extends StatefulWidget {
@override
_CustomDigilockerFormState createState() => _CustomDigilockerFormState();
}
class _CustomDigilockerFormState extends State<CustomDigilockerForm> {
final sdk = MeonDigilockerSDK(
companyName: 'democapital',
secretToken: 'cy7Kw2rWqdzVo2KPxlU0ymd9uRQKPSsb',
);
List<IssuerDetail> issuers = [];
IssuerDetail? selectedIssuer;
DocumentInfo? selectedDocument;
List<DocumentField> fields = [];
Map<String, String> fieldValues = {};
@override
void initState() {
super.initState();
_loadIssuers();
}
Future<void> _loadIssuers() async {
try {
final tokenResponse = await sdk.getAccessToken();
final response = await sdk.getListOfIssuersInDetail(
GetListOfIssuersInDetailParams(
clientToken: tokenResponse.clientToken,
state: tokenResponse.state,
search: 'insurance',
),
);
setState(() {
issuers = response.results;
});
} catch (e) {
print('Error loading issuers: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Custom DigiLocker Form')),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
// Issuer Selection
if (issuers.isNotEmpty)
DropdownButtonFormField<IssuerDetail>(
value: selectedIssuer,
hint: Text('Select Issuer'),
items: issuers.map((issuer) {
return DropdownMenuItem(
value: issuer,
child: Text(issuer.name),
);
}).toList(),
onChanged: (issuer) {
setState(() {
selectedIssuer = issuer;
selectedDocument = null;
fields = [];
fieldValues = {};
});
},
),
// Document Selection
if (selectedIssuer != null)
DocumentDropdown(
documents: selectedIssuer!.documentsInfo,
onSelect: (document) {
setState(() {
selectedDocument = document;
fields = document!.requiredParameters;
fieldValues = {};
});
// Initialize field values
document!.requiredParameters.forEach((field) {
fieldValues[field.paramname] = '';
});
},
placeholder: 'Select a document...',
),
// Dynamic Form Fields
if (selectedDocument != null && fields.isNotEmpty)
DynamicFormFields(
fields: fields,
values: fieldValues,
onChanged: (values) {
setState(() {
fieldValues = values;
});
},
),
// Submit Button
if (selectedDocument != null && fields.isNotEmpty)
ElevatedButton(
onPressed: () async {
// Handle form submission
print('Submitting with values: $fieldValues');
},
child: Text('Submit & Verify'),
),
],
),
),
);
}
}
API Reference #
MeonDigilockerSDK #
Main SDK class for Meon DigiLocker integration.
Constructor
MeonDigilockerSDK({
required String companyName,
required String secretToken,
Duration timeout = const Duration(seconds: 30),
});
companyName(required): Your company namesecretToken(required): Your secret tokentimeout: Request timeout duration (default: 30 seconds)
Methods
getAccessToken()
Get access token and state for authentication.
GetAccessTokenResponse response = await sdk.getAccessToken();
// Returns: { clientToken, state, status }
getListOfIssuersInDetail(params)
Search for available document issuers.
GetListOfIssuersInDetailResponse response = await sdk.getListOfIssuersInDetail(
GetListOfIssuersInDetailParams(
clientToken: 'token',
state: 'state',
search: 'insurance',
page: 1,
),
);
generateDigiUrl(params)
Create URL for DigiLocker document verification flow.
GenerateDigiUrlResponse response = await sdk.generateDigiUrl(
GenerateDigiUrlParams(
clientToken: 'token',
redirectUrl: 'https://your-app.com/callback',
companyName: 'company',
otherDocuments: [...],
),
);
sendEntireData(params)
Retrieve final document data after verification.
SendEntireDataResponse response = await sdk.sendEntireData(
SendEntireDataParams(
clientToken: 'token',
state: 'state',
status: true,
),
);
Flutter Widgets #
DigilockerForm
Complete form component that handles the entire document verification flow.
Props:
companyName(required): Your company namesecretToken(required): Your secret tokenredirectUrl: Redirect URL after verificationonSuccess: Callback when verification succeedsonError: Callback when an error occursprimaryColor: Primary color for themingbackgroundColor: Background colorloadingColor: Loading indicator color
DocumentDropdown
Searchable dropdown for selecting documents.
Props:
documents(required): List of documents to displayonSelect: Callback when document is selectedplaceholder: Placeholder textdisabled: Whether the dropdown is disabledprimaryColor: Primary color for theming
DynamicFormFields
Dynamic form fields based on document selection.
Props:
fields(required): List of field definitionsvalues(required): Current field valuesonChanged(required): Callback when values changeshowLabels: Whether to show field labels (default: true)primaryColor: Primary color for theming
Data Models #
DocumentField #
Represents a form field for document input.
DocumentInfo #
Contains document information including required parameters.
IssuerDetail #
Contains issuer information and available documents.
SendEntireDataResponse #
Contains the final verification data including Aadhaar, PAN, and other document details.
Validation #
The SDK includes comprehensive validation:
- Company name and secret token validation
- Client token and state validation
- Document field validation
- API response validation
All methods throw descriptive Exception objects if validation fails.
Error Handling #
All API methods throw exceptions that can be caught:
try {
final response = await sdk.getAccessToken();
} catch (e) {
print('Error: $e');
// Handle the error appropriately
}
Example App #
Check out the example/ directory for a complete Flutter app demonstrating all features of the SDK.
Run the example:
cd example
flutter run
License #
MIT License - see LICENSE file for details.
Support #
For issues and questions, please contact support or create an issue on GitHub.