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

Azakaw KYC onboarding for Flutter — runs the Azakaw compliance onboarding flow in a WebView, with region and environment selection matching the Azakaw web SDK.

example/lib/main.dart

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

void main() => runApp(const ExampleApp());

class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Azakaw KYC example',
      theme: ThemeData(colorSchemeSeed: Colors.indigo, useMaterial3: true),
      home: const HomePage(),
    );
  }
}

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

  @override
  State<HomePage> createState() => _HomePageState();
}

/// Prefills the session id so testing does not depend on the simulator or
/// emulator sharing the host clipboard:
///
///   `flutter run --dart-define=SESSION_ID=<uuid>`
const _presetSessionId = String.fromEnvironment('SESSION_ID');

/// Preselects region/environment the same way, e.g. `--dart-define=REGION=kuwait`.
const _presetRegion = String.fromEnvironment('REGION');
const _presetEnv = String.fromEnvironment('ENV');

class _HomePageState extends State<HomePage> {
  final _sessionIdController = TextEditingController(text: _presetSessionId);

  AzakawRegion _region = _presetRegion.isEmpty
      ? AzakawRegion.uae
      : AzakawRegion.values.byName(_presetRegion);
  AzakawEnvironment _environment = _presetEnv.isEmpty
      ? AzakawEnvironment.sandbox
      : AzakawEnvironment.values.byName(_presetEnv);
  AzakawLanguage? _language;
  bool _hideSidebar = false;
  bool _hideOnboardingSections = false;
  bool _isFullscreen = true;
  bool _resolveTenantHost = true;

  String? _outcome;

  @override
  void dispose() {
    _sessionIdController.dispose();
    super.dispose();
  }

  AzakawKycConfig? _buildConfig() {
    try {
      return AzakawKycConfig(
        sessionId: _sessionIdController.text,
        region: _region,
        environment: _environment,
        hideSidebar: _hideSidebar,
        hideOnboardingSections: _hideOnboardingSections,
        language: _language,
        isFullscreen: _isFullscreen,
        resolveTenantHost: _resolveTenantHost,
        // Logs the postMessage traffic, which is how you confirm the bridge
        // is alive: you should see an inbound IframeParametersRequest.
        enableLogging: true,
      );
    } on ArgumentError catch (error) {
      setState(() => _outcome = 'Invalid config: ${error.message}');
      return null;
    }
  }

  Future<void> _start() async {
    final config = _buildConfig();
    if (config == null) return;

    setState(() => _outcome = null);

    final result = await AzakawKyc.start(
      context: context,
      config: config,
      onError: (error) => debugPrint('example: onError $error'),
      onExternalUrl: (url) => debugPrint('example: external url $url'),
    );

    if (!mounted) return;
    setState(() {
      _outcome = switch (result.status) {
        AzakawKycStatus.completed => 'Completed',
        AzakawKycStatus.cancelled => 'Cancelled by the user',
        AzakawKycStatus.failed => 'Failed: ${result.error?.message}',
      };
    });
  }

  @override
  Widget build(BuildContext context) {
    final urls = resolveAzakawUrls(region: _region, environment: _environment);
    // Ask the SDK rather than re-deriving the rule: Kuwait has a sandbox,
    // KSA and Qatar do not.
    final unavailable = _region.subdomainFor(_environment) == null;

    return Scaffold(
      appBar: AppBar(title: const Text('Azakaw KYC example')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          TextField(
            controller: _sessionIdController,
            decoration: const InputDecoration(
              labelText: 'Session id',
              helperText: 'Obtained from the Azakaw backend',
              border: OutlineInputBorder(),
            ),
          ),
          const SizedBox(height: 16),
          DropdownButtonFormField<AzakawRegion>(
            initialValue: _region,
            decoration: const InputDecoration(
              labelText: 'Region',
              border: OutlineInputBorder(),
            ),
            items: [
              for (final region in AzakawRegion.values)
                DropdownMenuItem(
                  value: region,
                  child: Text('${region.wireName} — ${region.domain}'),
                ),
            ],
            onChanged: (value) => setState(() => _region = value!),
          ),
          const SizedBox(height: 16),
          DropdownButtonFormField<AzakawEnvironment>(
            initialValue: _environment,
            decoration: const InputDecoration(
              labelText: 'Environment',
              border: OutlineInputBorder(),
            ),
            items: [
              for (final environment in AzakawEnvironment.values)
                DropdownMenuItem(
                  value: environment,
                  child: Text(environment.wireName),
                ),
            ],
            onChanged: (value) => setState(() => _environment = value!),
          ),
          const SizedBox(height: 16),
          DropdownButtonFormField<AzakawLanguage?>(
            initialValue: _language,
            decoration: const InputDecoration(
              labelText: 'Language',
              border: OutlineInputBorder(),
            ),
            items: const [
              DropdownMenuItem(value: null, child: Text("Portal's default")),
              DropdownMenuItem(
                value: AzakawLanguage.en,
                child: Text('English'),
              ),
              DropdownMenuItem(
                value: AzakawLanguage.ar,
                child: Text('العربية (RTL)'),
              ),
            ],
            onChanged: (value) => setState(() => _language = value),
          ),
          SwitchListTile(
            title: const Text('Hide sidebar'),
            subtitle: const Text('Delivered over the handshake'),
            value: _hideSidebar,
            onChanged: (value) => setState(() => _hideSidebar = value),
          ),
          SwitchListTile(
            title: const Text('Hide onboarding sections'),
            subtitle: const Text('Start on the first form page'),
            value: _hideOnboardingSections,
            onChanged: (value) =>
                setState(() => _hideOnboardingSections = value),
          ),
          SwitchListTile(
            title: const Text('Fullscreen'),
            value: _isFullscreen,
            onChanged: (value) => setState(() => _isFullscreen = value),
          ),
          SwitchListTile(
            title: const Text('Resolve tenant host'),
            subtitle: const Text(
              'Open on the tenant domain from the token, instead of '
              'loading the generic host and redirecting',
            ),
            value: _resolveTenantHost,
            onChanged: (value) => setState(() => _resolveTenantHost = value),
          ),
          const SizedBox(height: 8),
          Card(
            child: Padding(
              padding: const EdgeInsets.all(12),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    'Resolved hosts',
                    style: Theme.of(context).textTheme.labelLarge,
                  ),
                  const SizedBox(height: 8),
                  SelectableText(
                    'base: ${urls.baseUrl}\n'
                    'api:  ${urls.apiUrl}\n'
                    'auth: ${urls.authUrl}',
                    style: const TextStyle(fontFamily: 'monospace'),
                  ),
                  if (unavailable) ...[
                    const SizedBox(height: 8),
                    Text(
                      'No ${_environment.wireName} host is provisioned for '
                      '${_region.wireName} — this will not resolve.',
                      style: TextStyle(
                        color: Theme.of(context).colorScheme.error,
                      ),
                    ),
                  ],
                ],
              ),
            ),
          ),
          const SizedBox(height: 16),
          FilledButton(
            onPressed: _start,
            child: const Text('Start onboarding'),
          ),
          if (_outcome != null) ...[
            const SizedBox(height: 16),
            Card(
              color: Theme.of(context).colorScheme.surfaceContainerHighest,
              child: ListTile(
                title: const Text('Result'),
                subtitle: Text(_outcome!),
              ),
            ),
          ],
        ],
      ),
    );
  }
}
0
likes
130
points
74
downloads

Documentation

Documentation
API reference

Publisher

verified publisherazakaw.com

Weekly Downloads

Azakaw KYC onboarding for Flutter — runs the Azakaw compliance onboarding flow in a WebView, with region and environment selection matching the Azakaw web SDK.

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_inappwebview, http, permission_handler

More

Packages that depend on azakaw_kyc_flutter

Packages that implement azakaw_kyc_flutter