In the meantime: Use WebView Integration to integrate Didit verification into your Flutter app today.
Expected Features
- Platform channel integration with native iOS and Android SDKs
- Dart-native API with full type safety
- Full feature parity with native SDKs
- Stream-based state management
- Customizable UI theming
- Support for both Material and Cupertino design
Expected API (Preview)
Installation (Expected)
Copy
# pubspec.yaml
dependencies:
didit_sdk: ^1.0.0
Copy
flutter pub get
Usage (Expected)
Copy
import 'package:didit_sdk/didit_sdk.dart';
class VerificationScreen extends StatefulWidget {
@override
State<VerificationScreen> createState() => _VerificationScreenState();
}
class _VerificationScreenState extends State<VerificationScreen> {
final _diditSdk = DiditSdk.instance;
VerificationResult? _result;
Future<void> _startVerification() async {
final config = DiditConfiguration(
primaryColor: Color(0xFF007AFF),
backgroundColor: Colors.white,
showIntroScreen: true,
loggingEnabled: kDebugMode,
);
try {
final result = await _diditSdk.startVerification(
token: 'your-session-token',
// Or use workflowId:
// workflowId: 'your-workflow-id',
// vendorData: 'user-123',
configuration: config,
);
setState(() => _result = result);
switch (result.status) {
case VerificationStatus.approved:
// Navigate to success
break;
case VerificationStatus.pending:
// Show pending UI
break;
case VerificationStatus.declined:
// Handle declined
break;
}
} on DiditException catch (e) {
// Handle error
print('Verification error: ${e.message}');
} on DiditCancelledException {
// User cancelled
print('User cancelled verification');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Identity Verification')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: _startVerification,
child: Text('Verify Identity'),
),
if (_result != null) ...[
SizedBox(height: 20),
Text('Status: ${_result!.status.name}'),
Text('Session: ${_result!.sessionId}'),
],
],
),
),
);
}
}
Stream-Based State (Expected)
Copy
import 'package:didit_sdk/didit_sdk.dart';
class VerificationProvider extends ChangeNotifier {
final _diditSdk = DiditSdk.instance;
DiditState _state = DiditState.idle;
DiditState get state => _state;
VerificationProvider() {
// Listen to SDK state changes
_diditSdk.stateStream.listen((state) {
_state = state;
notifyListeners();
});
}
Future<void> startVerification(String token) async {
await _diditSdk.startVerification(token: token);
}
}
// In your widget
Consumer<VerificationProvider>(
builder: (context, provider, child) {
switch (provider.state) {
case DiditState.idle:
return Text('Ready to verify');
case DiditState.loading:
return CircularProgressIndicator();
case DiditState.ready:
return Text('Verification in progress');
case DiditState.error:
return Text('Error occurred');
}
},
)
TypeDefs (Expected)
Copy
enum VerificationStatus {
approved,
pending,
declined,
}
class VerificationResult {
final String sessionId;
final VerificationStatus status;
final String? country;
final String? documentType;
}
class DiditConfiguration {
final Color? primaryColor;
final Color? backgroundColor;
final bool showIntroScreen;
final bool loggingEnabled;
final SupportedLanguage? languageLocale;
}
Current Solution: WebView Integration
While the native Flutter SDK is in development, you can integrate Didit verification usingwebview_flutter. This provides full functionality today.
Installation
Copy
# pubspec.yaml
dependencies:
webview_flutter: ^4.4.0
webview_flutter_wkwebview: ^3.9.0 # iOS
webview_flutter_android: ^3.12.0 # Android
Copy
flutter pub get
Quick Implementation
Copy
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
import 'package:webview_flutter_android/webview_flutter_android.dart';
class VerificationScreen extends StatefulWidget {
final String verificationUrl;
final Function(String sessionId, String status) onComplete;
final VoidCallback onCancel;
const VerificationScreen({
super.key,
required this.verificationUrl,
required this.onComplete,
required this.onCancel,
});
@override
State<VerificationScreen> createState() => _VerificationScreenState();
}
class _VerificationScreenState extends State<VerificationScreen> {
late final WebViewController _controller;
@override
void initState() {
super.initState();
_setupWebView();
}
void _setupWebView() {
// Platform-specific configuration
late final PlatformWebViewControllerCreationParams params;
if (WebViewPlatform.instance is WebKitWebViewPlatform) {
params = WebKitWebViewControllerCreationParams(
allowsInlineMediaPlayback: true,
mediaTypesRequiringUserAction: const {},
);
} else {
params = const PlatformWebViewControllerCreationParams();
}
_controller = WebViewController.fromPlatformCreationParams(params)
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setUserAgent(
'Mozilla/5.0 (Linux; Android 10; Mobile) AppleWebKit/537.36'
)
..setNavigationDelegate(
NavigationDelegate(
onNavigationRequest: (request) {
if (request.url.contains('yourapp.com/callback')) {
_handleCallback(request.url);
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
),
)
..loadRequest(Uri.parse(widget.verificationUrl));
// Handle permissions
_controller.platform.setOnPlatformPermissionRequest((request) {
request.grant();
});
// Android-specific
if (_controller.platform is AndroidWebViewController) {
(_controller.platform as AndroidWebViewController)
.setMediaPlaybackRequiresUserGesture(false);
}
}
void _handleCallback(String url) {
final uri = Uri.parse(url);
final sessionId = uri.queryParameters['verificationSessionId'];
final status = uri.queryParameters['status'];
if (sessionId != null && status != null) {
widget.onComplete(sessionId, status);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Identity Verification'),
leading: IconButton(
icon: const Icon(Icons.close),
onPressed: widget.onCancel,
),
),
body: WebViewWidget(controller: _controller),
);
}
}
Usage Example
Copy
class HomeScreen extends StatelessWidget {
Future<void> _startVerification(BuildContext context) async {
// Create session via your backend
final response = await http.post(
Uri.parse('https://your-backend.com/create-verification'),
body: jsonEncode({'userId': 'user-123'}),
headers: {'Content-Type': 'application/json'},
);
final data = jsonDecode(response.body);
final verificationUrl = data['verification_url'];
if (context.mounted) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => VerificationScreen(
verificationUrl: verificationUrl,
onComplete: (sessionId, status) {
Navigator.pop(context);
if (status == 'Approved') {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Identity verified!')),
);
}
},
onCancel: () => Navigator.pop(context),
),
),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () => _startVerification(context),
child: const Text('Verify Identity'),
),
),
);
}
}