Skip to main content
A cross-platform Flutter SDK for seamless integration in Dart-based applications, providing native performance through platform channels.

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)

# pubspec.yaml
dependencies:
  didit_sdk: ^1.0.0
flutter pub get

Usage (Expected)

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)

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)

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 using webview_flutter. This provides full functionality today.

Installation

# pubspec.yaml
dependencies:
  webview_flutter: ^4.4.0
  webview_flutter_wkwebview: ^3.9.0  # iOS
  webview_flutter_android: ^3.12.0   # Android
flutter pub get

Quick Implementation

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

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'),
        ),
      ),
    );
  }
}
Full Flutter WebView Guide with complete implementation

Demo Available: Check out our Flutter demo repository for a complete working example.