digified_flutter_plugin 0.0.33 copy "digified_flutter_plugin: ^0.0.33" to clipboard
digified_flutter_plugin: ^0.0.33 copied to clipboard

Flutter plugin for Digified's Arabic eKYC and eContract SDKs. Provides native flows for identity verification and electronic contract signing with updated Android integration (FlutterActivity + Hilt) [...]

example/lib/main.dart

import 'dart:convert';

import 'package:digified_flutter_plugin/digified_flutter_plugin.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'testing_profiles/models/test_profile.dart';
import 'testing_profiles/storage/profile_store.dart';
import 'testing_profiles/ui/profile_management_page.dart';
import 'testing_profiles/ui/profile_picker_sheet.dart';

// This file keeps concise, customer-facing API examples.
// The tester tooling UI is implemented under lib/app and lib/testing_profiles.

class DigifiedApiExamples {
  const DigifiedApiExamples._();

  static Future<String?> presentEkyc({
    required String apiKey,
    required String baseUrl,
  }) async {
    try {
      return await DigifiedFlutterPlugin.presentEKYC(
        apiKey: apiKey,
        baseUrl: baseUrl,
      );
    } on PlatformException {
      rethrow;
    }
  }

  static Future<void> presentEcontract({
    required String apiKey,
    required String baseUrl,
    required String faceMatchingApiKey,
    required String faceMatchingBaseUrl,
    required String eKYCSessionID,
    required String templateVersionID,
    required Map<String, String> variables,
  }) async {
    try {
      await DigifiedFlutterPlugin.presentEContract(
        apiKey: apiKey,
        baseUrl: baseUrl,
        faceMatchingApiKey: faceMatchingApiKey,
        faceMatchingBaseUrl: faceMatchingBaseUrl,
        eKYCSessionID: eKYCSessionID,
        templateVersionID: templateVersionID,
        variables: variables,
      );
    } on PlatformException {
      rethrow;
    }
  }
}

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MainApp());
}

class MainApp extends StatefulWidget {
  const MainApp({super.key});

  @override
  State<MainApp> createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
  static const _languageKey = 'app_language';

  final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
  final GlobalKey<ScaffoldMessengerState> _scaffoldMessengerKey =
      GlobalKey<ScaffoldMessengerState>();

  Locale _locale = const Locale('en');
  ProfileStore? _store;

  String t(String en, String ar) => _locale.languageCode == 'ar' ? ar : en;

  @override
  void initState() {
    super.initState();
    _initialize();
  }

  Future<void> _initialize() async {
    await _loadStoreAndLanguage();
    await _initSdk();
  }

  Future<void> _loadStoreAndLanguage() async {
    final store = await ProfileStore.create();
    final prefs = await SharedPreferences.getInstance();
    final localeCode = prefs.getString(_languageKey) ?? 'en';

    try {
      await DigifiedFlutterPlugin.setLanguage(localeCode);
    } catch (_) {}

    if (!mounted) return;
    setState(() {
      _store = store;
      _locale = Locale(localeCode);
    });
  }

  Future<void> _initSdk() async {
    try {
      await DigifiedFlutterPlugin.setLoggingEnabled(true);
    } catch (_) {}
  }

  Future<void> _toggleLanguage() async {
    final newLang = _locale.languageCode == 'ar' ? 'en' : 'ar';
    try {
      await DigifiedFlutterPlugin.setLanguage(newLang);
      final prefs = await SharedPreferences.getInstance();
      await prefs.setString(_languageKey, newLang);
      if (!mounted) return;
      setState(() {
        _locale = Locale(newLang);
      });
    } catch (e) {
      _showMessage('Failed to set language: $e');
    }
  }

  Future<void> _launchEkyc() async {
    final profile = await _pickProfileForFlow(FlowType.ekyc);
    if (profile == null) return;
    if (!profile.hasEkyc) {
      _showMessage('Selected profile is not configured for eKYC.');
      return;
    }
    if (!_hasRequiredFields(
      profile.ekyc.fields,
      const ['apiKey', 'baseUrl'],
      flowName: 'eKYC',
    )) {
      return;
    }

    try {
      final ekycSessionId = await DigifiedFlutterPlugin.presentEKYC(
        apiKey: profile.ekyc.value('apiKey'),
        baseUrl: profile.ekyc.value('baseUrl'),
      );
      _showMessage('eKYC completed. Session ID: $ekycSessionId');
    } on PlatformException catch (e) {
      _showMessage('eKYC failed: ${e.message}');
    } catch (e) {
      _showMessage('eKYC error: $e');
    }
  }

  Future<void> _launchEcontract() async {
    final profile = await _pickProfileForFlow(FlowType.econtract);
    if (profile == null) return;
    if (!profile.hasEcontract) {
      _showMessage('Selected profile is not configured for eContract.');
      return;
    }
    if (!_hasRequiredFields(
      profile.econtract.fields,
      const [
        'apiKey',
        'baseUrl',
        'faceMatchingApiKey',
        'faceMatchingBaseUrl',
        'eKYCSessionID',
        'templateVersionID',
        'variables',
      ],
      flowName: 'eContract',
    )) {
      return;
    }

    final variables = _parseVariables(profile.econtract.value('variables'));
    if (variables == null) {
      _showMessage('Invalid eContract variables JSON. Use object format.');
      return;
    }

    try {
      await DigifiedFlutterPlugin.presentEContract(
        apiKey: profile.econtract.value('apiKey'),
        baseUrl: profile.econtract.value('baseUrl'),
        faceMatchingApiKey: profile.econtract.value('faceMatchingApiKey'),
        faceMatchingBaseUrl: profile.econtract.value('faceMatchingBaseUrl'),
        eKYCSessionID: profile.econtract.value('eKYCSessionID'),
        templateVersionID: profile.econtract.value('templateVersionID'),
        variables: variables,
      );
      _showMessage('eContract completed successfully');
    } on PlatformException catch (e) {
      _showMessage('eContract failed: ${e.message}');
    } catch (e) {
      _showMessage('eContract error: $e');
    }
  }

  Map<String, String>? _parseVariables(String input) {
    try {
      final decoded = jsonDecode(input);
      if (decoded is! Map) return null;
      return decoded.map(
        (key, value) => MapEntry(key.toString(), value?.toString() ?? ''),
      );
    } catch (_) {
      return null;
    }
  }

  bool _hasRequiredFields(
    Map<String, String> fields,
    List<String> requiredKeys, {
    required String flowName,
  }) {
    for (final key in requiredKeys) {
      if ((fields[key] ?? '').trim().isEmpty) {
        _showMessage('$flowName is missing required field: $key');
        return false;
      }
    }
    return true;
  }

  Future<TestProfile?> _pickProfileForFlow(FlowType flowType) async {
    final store = _store;
    if (store == null) return null;
    final navContext = _navigatorKey.currentContext;
    if (navContext == null) return null;

    var profiles = store.readProfiles();
    profiles = profiles.where((profile) {
      if (flowType == FlowType.ekyc) return profile.hasEkyc;
      return profile.hasEcontract;
    }).toList();

    if (profiles.isEmpty) {
      _showMessage(
        flowType == FlowType.ekyc
            ? 'No eKYC profiles configured. Use Manage to add one.'
            : 'No eContract profiles configured. Use Manage to add one.',
      );
      return null;
    }

    final result = await ProfilePickerSheet.show(
      navContext,
      flowType: flowType,
      profiles: profiles,
      defaultProfileId: store.getDefaultProfileId(flowType),
      onManageProfiles: () async {
        await _openProfileManagement();
        return store.readProfiles();
      },
    );

    if (result == null) return null;
    if (result.makeDefault) {
      await store.setDefaultProfileId(flowType, result.profile.id);
    }

    profiles = store.readProfiles();
    return profiles.firstWhere(
      (p) => p.id == result.profile.id,
      orElse: () => profiles.first,
    );
  }

  Future<void> _openProfileManagement() async {
    final store = _store;
    if (store == null) return;
    final navigator = _navigatorKey.currentState;
    if (navigator == null) return;

    await navigator.push(
      MaterialPageRoute(
        builder: (_) => ProfileManagementPage(store: store),
      ),
    );

    if (mounted) {
      setState(() {});
    }
  }

  void _showMessage(String message) {
    if (!mounted) return;
    _scaffoldMessengerKey.currentState?.showSnackBar(
      SnackBar(content: Text(message)),
    );
  }

  @override
  Widget build(BuildContext context) {
    final isReady = _store != null;

    return MaterialApp(
      navigatorKey: _navigatorKey,
      scaffoldMessengerKey: _scaffoldMessengerKey,
      locale: _locale,
      supportedLocales: const [Locale('en'), Locale('ar')],
      localizationsDelegates: const [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      localeResolutionCallback: (locale, supportedLocales) {
        if (locale == null) return supportedLocales.first;
        for (final supported in supportedLocales) {
          if (supported.languageCode == locale.languageCode) {
            return supported;
          }
        }
        return supportedLocales.first;
      },
      home: Scaffold(
        appBar: AppBar(
          title: Text(t('Digified Demo', 'عرض ديجيفايد')),
          actions: [
            IconButton(
              onPressed: isReady ? _openProfileManagement : null,
              tooltip: 'Manage test profiles',
              icon: const Icon(Icons.tune),
            ),
          ],
        ),
        body: Center(
          child: isReady
              ? Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    ElevatedButton(
                      onPressed: _launchEkyc,
                      child: Text(t('Launch eKYC', 'بدء التحقق')),
                    ),
                    const SizedBox(height: 20),
                    ElevatedButton(
                      onPressed: _launchEcontract,
                      child: Text(t('Launch eContract', 'بدء العقد الإلكتروني')),
                    ),
                    const SizedBox(height: 20),
                    ElevatedButton(
                      onPressed: _toggleLanguage,
                      child:
                          Text(t('Switch to Arabic', 'التبديل إلى الإنجليزية')),
                    ),
                    const SizedBox(height: 20),
                    ElevatedButton(
                      onPressed: () async {
                        try {
                          await DigifiedFlutterPlugin.openAppSettings();
                        } catch (e) {
                          _showMessage('Failed to open app settings: $e');
                        }
                      },
                      child: Text(t('Open App Settings', 'فتح إعدادات التطبيق')),
                    ),
                  ],
                )
              : const CircularProgressIndicator(),
        ),
      ),
    );
  }
}
1
likes
0
points
735
downloads

Documentation

Documentation

Publisher

unverified uploader

Weekly Downloads

Flutter plugin for Digified's Arabic eKYC and eContract SDKs. Provides native flows for identity verification and electronic contract signing with updated Android integration (FlutterActivity + Hilt) and iOS 15+ support.

Homepage
Repository
View/report issues

License

unknown (license)

Dependencies

flutter

More

Packages that depend on digified_flutter_plugin

Packages that implement digified_flutter_plugin