videokyc_flutter 1.5.1 copy "videokyc_flutter: ^1.5.1" to clipboard
videokyc_flutter: ^1.5.1 copied to clipboard

A Flutter SDK for integrating SurePass Video KYC verification.

example/lib/main.dart

// Minimal example for the SurePass Video KYC Flutter SDK.
//
// Replace `your_surepass_api_token` and `your_workflow_id` with your SurePass
// credentials, then run the app. See the package README for the required
// Android/iOS platform setup (manifest permissions, Info.plist keys, and the
// permission_handler Podfile macros).
//
// This example also shows how to pass an optional selfie image: the app
// picks it (via `image_picker`, from the gallery or camera) and hands the
// raw bytes to the SDK, which base64-encodes them and sends them as
// `advance_parameters.user_image`. Picking from the gallery on iOS requires
// adding `NSPhotoLibraryUsageDescription` to Info.plist — see this example's
// own README.

import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:videokyc_flutter/videokyc_flutter.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Video KYC Example',
      home: const HomePage(),
    );
  }
}

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

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

class _HomePageState extends State<HomePage> {
  String _status = 'Not started';
  Uint8List? _userImageBytes;

  Future<void> _pickImage(ImageSource source) async {
    final picked = await ImagePicker().pickImage(
      source: source,
      imageQuality: 85,
    );
    if (picked == null) return;

    final bytes = await picked.readAsBytes();
    if (!mounted) return;
    setState(() => _userImageBytes = bytes);
  }

  Future<void> _startKyc() async {
    final messenger = ScaffoldMessenger.of(context);

    final result = await startSurepassVideoKyc(
      context: context,
      token: 'your_surepass_api_token',
      env: Env.sandbox, // or Env.prod
      workflowId: 'your_workflow_id',
      // These three are optional — drop any you don't collect and the SDK
      // sends a placeholder in its place, since the API requires all three.
      email: 'user@example.com',
      fullName: 'John Doe',
      mobileNumber: '9876543210', // 10-digit number, no country-code prefix
      userImage: _userImageBytes, // optional selfie, picked below
      onInitialized: (VideoKycModel model) {
        debugPrint(
            'Initialized: user=${model.userId} session=${model.sessionId}');
      },
    );

    final outcome = switch (result?.status) {
      VideoKycStatus.success => 'success (session ${result!.sessionId})',
      VideoKycStatus.cancelled => 'cancelled by the user',
      VideoKycStatus.failed => 'failed',
      VideoKycStatus.error => 'error: ${result!.errorMessage}',
      null => 'dismissed before a terminal status',
    };

    if (!mounted) return;
    setState(() => _status = outcome);
    messenger.showSnackBar(SnackBar(content: Text('Result: $outcome')));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Video KYC Example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Status: $_status'),
            const SizedBox(height: 16),
            if (_userImageBytes != null) ...[
              ClipOval(
                child: Image.memory(
                  _userImageBytes!,
                  width: 96,
                  height: 96,
                  fit: BoxFit.cover,
                ),
              ),
              TextButton(
                onPressed: () => setState(() => _userImageBytes = null),
                child: const Text('Remove photo'),
              ),
            ] else
              const Text('No selfie selected (optional)'),
            const SizedBox(height: 8),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                OutlinedButton.icon(
                  onPressed: () => _pickImage(ImageSource.camera),
                  icon: const Icon(Icons.camera_alt_outlined),
                  label: const Text('Camera'),
                ),
                const SizedBox(width: 8),
                OutlinedButton.icon(
                  onPressed: () => _pickImage(ImageSource.gallery),
                  icon: const Icon(Icons.photo_library_outlined),
                  label: const Text('Gallery'),
                ),
              ],
            ),
            const SizedBox(height: 16),
            FilledButton(
              onPressed: _startKyc,
              child: const Text('Start Video KYC'),
            ),
          ],
        ),
      ),
    );
  }
}