nadra_verisys_flutter 0.1.2 copy "nadra_verisys_flutter: ^0.1.2" to clipboard
nadra_verisys_flutter: ^0.1.2 copied to clipboard

A Flutter package for integrating NADRA Verisys API for Pakistani CNIC verification, biometric validation, and KYC compliance. Perfect for fintech, banking, and identity verification apps.

example/lib/main.dart

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

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'NADRA Verisys Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.green),
        useMaterial3: true,
      ),
      home: const VerificationScreen(),
    );
  }
}

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

  @override
  State<VerificationScreen> createState() => _VerificationScreenState();
}

class _VerificationScreenState extends State<VerificationScreen> {
  final _formKey = GlobalKey<FormState>();
  final _cnicController = TextEditingController();
  final _nameController = TextEditingController();
  final _dobController = TextEditingController();

  bool _isLoading = false;
  VerificationResponse? _response;
  String? _errorMessage;

  // Initialize Verisys client
  late final VerisysClient _client;

  @override
  void initState() {
    super.initState();
    _client = VerisysClient(
      apiKey: 'your-api-key-here', // Replace with API key from NADRA
      useSandbox: true, // Use sandbox environment (requires NADRA sandbox credentials)
    );
  }

  @override
  void dispose() {
    _cnicController.dispose();
    _nameController.dispose();
    _dobController.dispose();
    _client.dispose();
    super.dispose();
  }

  Future<void> _verifyCnic() async {
    if (!_formKey.currentState!.validate()) {
      return;
    }

    setState(() {
      _isLoading = true;
      _errorMessage = null;
      _response = null;
    });

    try {
      final request = VerificationRequest(
        cnicNumber: _cnicController.text.replaceAll('-', ''),
        fullName: _nameController.text.isNotEmpty ? _nameController.text : null,
        dateOfBirth: _dobController.text.isNotEmpty ? _dobController.text : null,
      );

      final response = await _client.verifyCnic(request);

      setState(() {
        _response = response;
        _isLoading = false;
      });
    } on VerisysException catch (e) {
      setState(() {
        _errorMessage = e.message;
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _errorMessage = 'Unexpected error: $e';
        _isLoading = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('NADRA CNIC Verification'),
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              // Info card
              Card(
                color: Colors.blue[50],
                child: Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Row(
                        children: [
                          Icon(Icons.info_outline, color: Colors.blue[700]),
                          const SizedBox(width: 8),
                          Text(
                            'Important Note',
                            style: TextStyle(
                              fontWeight: FontWeight.bold,
                              color: Colors.blue[700],
                            ),
                          ),
                        ],
                      ),
                      const SizedBox(height: 8),
                      const Text('• Requires NADRA API credentials'),
                      const Text('• Test CNICs provided by NADRA'),
                      const Text('• Contact NADRA for access'),
                    ],
                  ),
                ),
              ),
              const SizedBox(height: 24),

              // CNIC Input
              TextFormField(
                controller: _cnicController,
                decoration: const InputDecoration(
                  labelText: 'CNIC Number',
                  hintText: '12345-6789012-3 or 1234567890123',
                  border: OutlineInputBorder(),
                  prefixIcon: Icon(Icons.credit_card),
                ),
                keyboardType: TextInputType.number,
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Please enter CNIC number';
                  }
                  final cleanCnic = value.replaceAll('-', '');
                  if (cleanCnic.length != 13) {
                    return 'CNIC must be 13 digits';
                  }
                  if (!RegExp(r'^\d+$').hasMatch(cleanCnic)) {
                    return 'CNIC must contain only digits';
                  }
                  return null;
                },
              ),
              const SizedBox(height: 16),

              // Name Input (Optional)
              TextFormField(
                controller: _nameController,
                decoration: const InputDecoration(
                  labelText: 'Full Name (Optional)',
                  hintText: 'Muhammad Ali',
                  border: OutlineInputBorder(),
                  prefixIcon: Icon(Icons.person),
                ),
              ),
              const SizedBox(height: 16),

              // Date of Birth (Optional)
              TextFormField(
                controller: _dobController,
                decoration: const InputDecoration(
                  labelText: 'Date of Birth (Optional)',
                  hintText: 'YYYY-MM-DD',
                  border: OutlineInputBorder(),
                  prefixIcon: Icon(Icons.calendar_today),
                ),
                validator: (value) {
                  if (value != null && value.isNotEmpty) {
                    if (!RegExp(r'^\d{4}-\d{2}-\d{2}$').hasMatch(value)) {
                      return 'Use format: YYYY-MM-DD';
                    }
                  }
                  return null;
                },
              ),
              const SizedBox(height: 24),

              // Verify Button
              ElevatedButton(
                onPressed: _isLoading ? null : _verifyCnic,
                style: ElevatedButton.styleFrom(
                  padding: const EdgeInsets.symmetric(vertical: 16),
                ),
                child: _isLoading
                    ? const SizedBox(
                        height: 20,
                        width: 20,
                        child: CircularProgressIndicator(strokeWidth: 2),
                      )
                    : const Text(
                        'Verify CNIC',
                        style: TextStyle(fontSize: 16),
                      ),
              ),
              const SizedBox(height: 24),

              // Error Message
              if (_errorMessage != null)
                Card(
                  color: Colors.red[50],
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Row(
                      children: [
                        Icon(Icons.error_outline, color: Colors.red[700]),
                        const SizedBox(width: 8),
                        Expanded(
                          child: Text(
                            _errorMessage!,
                            style: TextStyle(color: Colors.red[700]),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),

              // Response
              if (_response != null) ...[
                Card(
                  color: _response!.isVerified
                      ? Colors.green[50]
                      : Colors.orange[50],
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Row(
                          children: [
                            Icon(
                              _response!.isVerified
                                  ? Icons.check_circle_outline
                                  : Icons.warning_amber,
                              color: _response!.isVerified
                                  ? Colors.green[700]
                                  : Colors.orange[700],
                            ),
                            const SizedBox(width: 8),
                            Text(
                              _response!.isVerified
                                  ? 'Verification Successful'
                                  : 'Verification Failed',
                              style: TextStyle(
                                fontWeight: FontWeight.bold,
                                fontSize: 16,
                                color: _response!.isVerified
                                    ? Colors.green[700]
                                    : Colors.orange[700],
                              ),
                            ),
                          ],
                        ),
                        const SizedBox(height: 12),
                        Text(
                          'Status: ${_response!.status.name}',
                          style: const TextStyle(fontWeight: FontWeight.w500),
                        ),
                        Text('Message: ${_response!.message}'),
                        if (_response!.transactionId != null)
                          Text('Transaction ID: ${_response!.transactionId}'),
                        if (_response!.citizenData != null) ...[
                          const Divider(height: 24),
                          const Text(
                            'Citizen Information',
                            style: TextStyle(
                              fontWeight: FontWeight.bold,
                              fontSize: 14,
                            ),
                          ),
                          const SizedBox(height: 8),
                          _buildInfoRow('CNIC',
                              _response!.citizenData!.cnicNumber),
                          _buildInfoRow(
                              'Full Name', _response!.citizenData!.fullName),
                          if (_response!.citizenData!.fatherName != null)
                            _buildInfoRow('Father Name',
                                _response!.citizenData!.fatherName!),
                          if (_response!.citizenData!.dateOfBirth != null)
                            _buildInfoRow('Date of Birth',
                                _response!.citizenData!.dateOfBirth!),
                          if (_response!.citizenData!.gender != null)
                            _buildInfoRow(
                                'Gender', _response!.citizenData!.gender!),
                          if (_response!.citizenData!.presentAddress != null)
                            _buildInfoRow('Address',
                                _response!.citizenData!.presentAddress!),
                        ],
                      ],
                    ),
                  ),
                ),
              ],
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildInfoRow(String label, String value) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 4),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(
            width: 120,
            child: Text(
              '$label:',
              style: const TextStyle(fontWeight: FontWeight.w500),
            ),
          ),
          Expanded(
            child: Text(value),
          ),
        ],
      ),
    );
  }
}
0
likes
150
points
--
downloads

Publisher

unverified uploader

A Flutter package for integrating NADRA Verisys API for Pakistani CNIC verification, biometric validation, and KYC compliance. Perfect for fintech, banking, and identity verification apps.

Repository (GitHub)
View/report issues

Topics

#nadra #verification #kyc #pakistan #cnic

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

flutter, http, meta

More

Packages that depend on nadra_verisys_flutter