SAAFE SDK for Flutter

This Flutter SDK provides a simple interface to integrate SAAFE's secure authentication and financial experience into your Flutter applications.

Features

  • 🔒 Secure authentication and redirection flows
  • 📱 Platform detection (iOS, Android, Flutter)
  • 🌓 Theme support (light, dark, system)
  • 📏 Forced portrait orientation during flows
  • 🔗 External links handling with intelligent fallbacks
  • ✅ Confirmation dialogs for closing flows
  • 🖥️ High-resolution WebView with optimized text rendering

Installation

Add the SDK to your pubspec.yaml:

dependencies:
  saafe_aa_sdk: ^0.1.5

Usage

Initialize the SDK

Initialize the SDK in your main.dart file before calling runApp():

import 'package:saafe_aa_sdk/saafe_sdk.dart';

void main() async {
  // Initialize with default settings (sandbox environment)
  await SaafeSdk.initialize();
  
  // Or specify sandbox/production environment
  // await SaafeSdk.initialize(useSandbox: true); // For sandbox (default)
  // await SaafeSdk.initialize(useSandbox: false); // For production
  
  // Or with a custom redirect URL
  // await SaafeSdk.initialize(customRedirectUrl: 'https://your-custom-url.example.com/login');
  
  runApp(const MyApp());
}

Environment Configuration

The SDK supports two environments:

  1. Sandbox (default): Uses https://stage-redirection.saafe.in/login - For development and testing
  2. Production: Uses https://app-redirection.saafe.in/login - For live applications

To switch environments, use the useSandbox parameter during initialization:

// For sandbox (development/testing)
await SaafeSdk.initialize(useSandbox: true);

// For production (live environment)
await SaafeSdk.initialize(useSandbox: false);

Trigger the Redirect Flow

Trigger the redirect flow using the parameters from your generated consent response:

// First, get the consent response from SAAFE API
// The response will look like this:
/*
{
    "status": "success",
    "code": "OperationSuccess",
    "msg": "Operation Success",
    "request_id": 7788,
    "txn_id": "daa53abbc1-7fe7-4984-8879-197883daba9d",
    "url": "https://sandbox.redirection.saafe.in/login/?fi=WU9AUEBGV0dXUB5QWUc=&reqdate=160520250536024&ecreq=PuH3d0DSVsNCH3tfu86D4iNKTOYZyyftje7GLsc84gwMcmjFifpO9Pf4v8gDZ0lN4pD7Koskq-CkrHFGRpkvh16HVVjCjmhHiQaKRGuRo1MjoxiqicJJcQP0k-MJwDYR6krtMHFr3RP_W4Trlj2aAxeoucAvoJhGI1Lm5fnsCnnU64BHl7vPHGyXovHZIXl4sr8_HLQPuBkgLUy5oeu0fDDY62ajnztF40KufzuNe5MLI0Aut2_OjR-S94rdFrkbM6IseaBsPbpZnnibU8GuKL3A9idlvBDbLRNvEtgnjKy6AKGMAWQtEC1l6waJKeedhl0j4qCpNLtNBOCXb3VS5sf5kafDitfuSgpJ0pfuA-8=",
    "consent_handle": [
        "8bce1c3b-f289-4c1c-8d4b-7ed2e0d3a31b",
        "b6bc69f8-c77d-4070-a9ec-0d4ad7c72be2"
    ],
    "vua": "8682807087@dashboard-aa-preprod",
    "fi": "WU9AUEBGV0dXUB5QWUc=",
    "reqdate": "160520250536024",
    "ecreq": "PuH3d0DSVsNCH3tfu86D4iNKTOYZyyftje7GLsc84gwMcmjFifpO9Pf4v8gDZ0lN4pD7Koskq-CkrHFGRpkvh16HVVjCjmhHiQaKRGuRo1MjoxiqicJJcQP0k-MJwDYR6krtMHFr3RP_W4Trlj2aAxeoucAvoJhGI1Lm5fnsCnnU64BHl7vPHGyXovHZIXl4sr8_HLQPuBkgLUy5oeu0fDDY62ajnztF40KufzuNe5MLI0Aut2_OjR-S94rdFrkbM6IseaBsPbpZnnibU8GuKL3A9idlvBDbLRNvEtgnjKy6AKGMAWQtEC1l6waJKeedhl0j4qCpNLtNBOCXb3VS5sf5kafDitfuSgpJ0pfuA-8="
}
*/

// Extract the required parameters from the consent response
final consentResponse = await yourApiCallToGetConsent();

// Now use these parameters with the SDK
final redirectInstance = await SaafeSdk.triggerRedirect(
  context,
  SaafeRedirectOptions(
    fi: consentResponse['fi'],          // Use the 'fi' value from consent response
    reqdate: consentResponse['reqdate'], // Use the 'reqdate' value from consent response
    ecreq: consentResponse['ecreq'],    // Use the 'ecreq' value from consent response
    theme: 'light', // Optional: 'light', 'dark', or null for system default
    onComplete: (data) {
      print('Flow completed: $data');
      // Handle successful completion
    },
    onCancel: () {
      print('Flow cancelled by user');
      // Handle user cancellation
    },
    onError: (error) {
      print('Error during flow: $error');
      // Handle errors
    },
    onLoad: () {
      print('WebView loaded successfully');
      // Optional: handle WebView load event
    },
  ),
);

Close the Redirect Flow

You can programmatically close the flow:

// This will show a confirmation dialog before closing
redirectInstance.close();

URL Parameters

The SDK automatically adds the following parameters to the redirect URL:

Platform Detection

  • platform=ios - For iOS devices
  • platform=android - For Android devices
  • platform=flutter - For other Flutter platforms

Theme Support

  • theme=light - Light theme
  • theme=dark - Dark theme

External URL Handling

The SDK intelligently handles external URLs by:

  1. Detecting external links in the WebView
  2. Automatically opening them in the system's default browser
  3. Providing multiple fallback mechanisms if the default method fails
  4. Showing a useful error dialog with copy functionality if all launch attempts fail

You can also use the URL launcher directly in your app:

// Launch a URL in the external browser
await SaafeSdk.launchExternalUrl(
  'https://example.com',
  context: context, // Optional: provide context to show error dialog if needed
);

Example

See the example folder for a complete implementation example.

License

This project is licensed under the MIT License - see the LICENSE file for details.