saafe_aa_sdk 0.1.5 copy "saafe_aa_sdk: ^0.1.5" to clipboard
saafe_aa_sdk: ^0.1.5 copied to clipboard

Flutter SDK for integrating SAAFE's secure authentication and financial experience

example/lib/main.dart

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'dart:io' show Platform;
import 'package:saafe_aa_sdk/saafe_sdk.dart';
import 'package:http/http.dart' as http;

void main() async {
  // Initialize Flutter binding
  WidgetsFlutterBinding.ensureInitialized();
  
  // Initialize SAAFE SDK with sandbox mode (default is true)
  await SaafeSdk.initialize(useSandbox: true);
  
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SAAFE SDK Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const SaafeDemo(),
    );
  }
}


class SaafeDemo extends StatefulWidget {
  const SaafeDemo({Key? key}) : super(key: key);

  @override
  State<SaafeDemo> createState() => SaafeDemoState();
}

class SaafeDemoState extends State<SaafeDemo> {
  String fi = '';
  String reqdate = '';
  String ecreq = '';

  final TextEditingController textEditingController = TextEditingController();
  final FocusNode focusNode = FocusNode();

  SaafeRedirectInstance? _redirectInstance;
  String _status = 'Not started';
  bool _isSupported = true;
  bool _useSandbox = true; // Default to sandbox environment

  @override
  void initState() {
    super.initState();
    _checkPlatformSupport();
    setState(() {
      _status = 'Enter mobile number and click "Start SAAFE Flow"';
    });
    // Don't fetch data on init - wait for user to enter mobile number
  }

  void _checkPlatformSupport() {
    setState(() {
      _isSupported = !(kIsWeb || !(Platform.isAndroid || Platform.isIOS));
      if (!_isSupported) {
        _status = 'Platform not supported';
      }
    });
  }

  // Switch between sandbox and production environments
  Future<void> _toggleEnvironment() async {
    setState(() {
      _useSandbox = !_useSandbox;
      // Re-initialize the SDK with the new environment setting
      SaafeSdk.initialize(useSandbox: _useSandbox);
      _status = 'Switched to ${_useSandbox ? 'sandbox' : 'production'} environment';
    });
  }

  bool get isTenDigits => textEditingController.text.length == 10;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('SAAFE SDK Demo'),
        actions: [
          // Add environment indicator and toggle button in the app bar
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16.0),
            child: Center(
              child: Row(
                children: [
                  // Environment indicator text
                  Text(
                    _useSandbox ? 'SANDBOX' : 'PRODUCTION',
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                      color: _useSandbox ? Colors.amber : Colors.red,
                    ),
                  ),
                  // Toggle button
                  Switch(
                    value: _useSandbox,
                    activeColor: Colors.amber,
                    inactiveTrackColor: Colors.red.withOpacity(0.5),
                    onChanged: (value) => _toggleEnvironment(),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
      body: Center(
        child: SingleChildScrollView(
          padding: const EdgeInsets.all(16),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'Status: $_status',
                style: const TextStyle(fontSize: 18),
              ),
              const SizedBox(height: 30),
              if (!_isSupported)
                const Text(
                  'This platform does not support WebView. SAAFE SDK requires Android or iOS.',
                  textAlign: TextAlign.center,
                  style: TextStyle(color: Colors.red, fontSize: 16),
                )
              else ...[
                // Environment selection card
                Card(
                  elevation: 2,
                  margin: const EdgeInsets.only(bottom: 20),
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        const Text(
                          'Environment',
                          style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
                        ),
                        const SizedBox(height: 8),
                        Row(
                          children: [
                            Switch(
                              value: _useSandbox,
                              activeColor: Colors.green,
                              onChanged: (value) => _toggleEnvironment(),
                            ),
                            const SizedBox(width: 8),
                            Text(
                              _useSandbox ? 'Sandbox' : 'Production',
                              style: TextStyle(
                                fontWeight: FontWeight.bold,
                                color: _useSandbox ? Colors.green : Colors.red,
                              ),
                            ),
                          ],
                        ),
                        const SizedBox(height: 4),
                        Text(
                          _useSandbox 
                              ? 'Using stage-redirection.saafe.in'
                              : 'Using app-redirection.saafe.in',
                          style: TextStyle(
                            fontSize: 12,
                            color: Colors.grey[600],
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
                
                TextField(
                  controller: textEditingController,
                  maxLength: 10,
                  keyboardType: TextInputType.phone,
                  decoration: InputDecoration(
                    labelText: 'Mobile Number',
                    hintText: 'Enter 10 digit mobile number',
                    border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(12),
                    ),
                    prefixIcon: const Icon(Icons.phone),
                    filled: true,
                    fillColor: Colors.grey[100],
                    counterText: '', // Hide character counter
                  ),
                  onChanged: (value) {
                    setState(() {
                      // Update UI when text changes
                    });
                  },
                ),
                const SizedBox(height: 20),
                ElevatedButton(
                  onPressed: isTenDigits ? _fetchAndStartFlow : null,
                  style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.blueAccent,
                    minimumSize: const Size(200, 50),
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(12),
                    ),
                  ),
                  child: const Text('Start SAAFE Flow', style: TextStyle(color: Colors.white)),
                ),
                if (_redirectInstance != null)
                  Padding(
                    padding: const EdgeInsets.only(top: 16.0),
                    child: ElevatedButton(
                      onPressed: _closeFlow,
                      style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.redAccent,
                        minimumSize: const Size(200, 50),
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(12),
                        ),
                      ),
                      child: const Text('Close Flow',style: TextStyle(color: Colors.white),),
                    ),
                  ),
              ],
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _fetchAndStartFlow() async {
    setState(() {
      _status = 'Fetching data...';
    });

    try {
      // First fetch the data
      const apiUrl = 'https://api.sandbox.saafe.tech/bank-data/generate_consent';

      // Get mobile number from text field
      final mobileNumber = textEditingController.text;

      final response = await http.post(
        Uri.parse(apiUrl),
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Basic MTExOm9XajdubWNLdDBKaUczYw=='
        },
        body: jsonEncode({
          "client_ref_num": "test123",
          "txn_completed_cburl": "https://www.evil.com",
          "mobile_num": mobileNumber,
          "aa_vendor": "dashboard-aa-preprod",
          "fipId": "ACME-FIP,setu-fip-2",
          "institutionId": 93
        }),
      );

      print("API Response Status: ${response.statusCode}");
      print("API Response Body: ${response.body}");
      print("Using mobile number: $mobileNumber");

      if (response.statusCode == 200) {
        final jsonResponse = jsonDecode(response.body);
        print("Parsed JSON Response: $jsonResponse");

        setState(() {
          fi = jsonResponse['fi'] ?? '';
          reqdate = jsonResponse['reqdate'] ?? '';
          ecreq = jsonResponse['ecreq'] ?? '';
        });

        print('Extracted values:\nfi: $fi\nreqdate: $reqdate\necreq: $ecreq');
        
        // Check if we have valid parameters from the API
        if (fi.isEmpty || reqdate.isEmpty || ecreq.isEmpty) {
          setState(() {
            _status = 'API Error: Missing parameters from response';
          });
          return;
        }
        
        // Now start the SAAFE flow with the fetched parameters
        _startSaafeFlow();
      } else {
        print('Failed to fetch data. Status code: ${response.statusCode}');
        setState(() {
          _status = 'API Error: ${response.statusCode}';
        });
      }
    } catch (e) {
      print('Error fetching data: $e');
      setState(() {
        _status = 'API Error: $e';
      });
    }
  }

  Future<void> _startSaafeFlow() async {
    setState(() {
      _status = 'Starting...';
    });

    print("Starting SAAFE flow with: fi=$fi, reqdate=$reqdate, ecreq=$ecreq");
    print("Timestamp of parameters: ${DateTime.now()}");
    
    final options = SaafeRedirectOptions(
      fi: fi,
      reqdate: reqdate,
      ecreq: ecreq,
      onLoad: () {
        print("WebView onLoad callback fired");
        setState(() {
          _status = 'Flow loaded';
        });
      },
      onComplete: (data) {
        print("WebView onComplete callback fired with data: $data");
        setState(() {
          _status = 'Completed: $data';
          _redirectInstance = null;
        });
      },
      onCancel: () {
        print("WebView onCancel callback fired");
        setState(() {
          _status = 'Cancelled by user';
          _redirectInstance = null;
        });
      },
      onError: (error) {
        print("WebView onError callback fired with error: $error");
        setState(() {
          _status = 'Error: $error';
          _redirectInstance = null;
        });
      },
    );

    _redirectInstance = await SaafeSdk.triggerRedirect(context, options);
  }

  void _closeFlow() {
    _redirectInstance?.close();
    setState(() {
      _status = 'Closed by app';
      _redirectInstance = null;
    });
  }
}
2
likes
0
points
118
downloads

Documentation

Documentation

Publisher

unverified uploader

Weekly Downloads

Flutter SDK for integrating SAAFE's secure authentication and financial experience

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

cupertino_icons, flutter, http, url_launcher, webview_flutter

More

Packages that depend on saafe_aa_sdk