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

retracted

Official Flutter SDK for Lipila payment gateway. Accept payments and make disbursements in Zambia.

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Lipila Flutter SDK Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
        useMaterial3: true,
      ),
      home: const LipilaDemo(),
    );
  }
}

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

  @override
  State<LipilaDemo> createState() => _LipilaDemoState();
}

class _LipilaDemoState extends State<LipilaDemo> {
  late LipilaClient _client;
  String _output = 'Ready to test Lipila SDK...';
  bool _isLoading = false;

  // Controllers
  final _apiKeyController = TextEditingController(text: 'Lsk_your_sandbox_key');
  final _amountController = TextEditingController(text: '100');
  final _phoneController = TextEditingController(text: '260977123456');
  final _referenceController = TextEditingController();

  @override
  void initState() {
    super.initState();
    _initClient();
  }

  void _initClient() {
    _client = LipilaClient.sandbox(
      _apiKeyController.text,
      enableLogging: true,
      logLevel: LogLevel.debug,
    );
  }

  Future<void> _checkBalance() async {
    setState(() {
      _isLoading = true;
      _output = 'Checking balance...';
    });

    try {
      final balance = await _client.balance.getBalance();
      setState(() {
        _output =
            '''
✅ Balance Retrieved Successfully!

Available Balance: ${balance.availableBalance} ${balance.currency}
Booked Balance: ${balance.bookedBalance} ${balance.currency}
''';
      });
    } on AuthException catch (e) {
      setState(() {
        _output = '❌ Authentication Error:\n${e.message}';
      });
    } on NetworkException catch (e) {
      setState(() {
        _output = '❌ Network Error:\n${e.message}';
      });
    } catch (e) {
      setState(() {
        _output = '❌ Error:\n$e';
      });
    } finally {
      setState(() => _isLoading = false);
    }
  }

  Future<void> _createCollection() async {
    final amount = double.tryParse(_amountController.text) ?? 0;
    final phone = _phoneController.text;
    final reference = _referenceController.text.isEmpty
        ? 'TEST-${DateTime.now().millisecondsSinceEpoch}'
        : _referenceController.text;

    setState(() {
      _isLoading = true;
      _output = 'Creating collection...';
    });

    try {
      final collection = await _client.collections.createCollection(
        referenceId: reference,
        amount: amount,
        accountNumber: phone,
        currency: 'ZMW',
      );

      setState(() {
        _output =
            '''
✅ Collection Created!

Reference ID: ${collection.referenceId}
Identifier: ${collection.identifier}
Status: ${collection.status}
Payment Type: ${collection.paymentType}
Created: ${collection.createdAt}
''';
      });
    } on ValidationException catch (e) {
      setState(() {
        _output =
            '''
❌ Validation Error:
${e.message}

Field Errors:
${e.errors.entries.map((e) => '${e.key}: ${e.value}').join('\n')}
''';
      });
    } on ApiException catch (e) {
      setState(() {
        _output = '❌ API Error (${e.statusCode}):\n${e.message}';
      });
    } catch (e) {
      setState(() {
        _output = '❌ Error:\n$e';
      });
    } finally {
      setState(() => _isLoading = false);
    }
  }

  Future<void> _createDisbursement() async {
    final amount = double.tryParse(_amountController.text) ?? 0;
    final phone = _phoneController.text;
    final reference = _referenceController.text.isEmpty
        ? 'PAYOUT-${DateTime.now().millisecondsSinceEpoch}'
        : _referenceController.text;

    setState(() {
      _isLoading = true;
      _output = 'Creating disbursement...';
    });

    try {
      final disbursement = await _client.disbursements.createMobileDisbursement(
        referenceId: reference,
        amount: amount,
        accountNumber: phone,
        currency: 'ZMW',
        narration: 'Test disbursement from Flutter SDK',
      );

      setState(() {
        _output =
            '''
✅ Disbursement Created!

Reference ID: ${disbursement.referenceId}
Identifier: ${disbursement.identifier}
Status: ${disbursement.status}
Payment Type: ${disbursement.paymentType}
Created: ${disbursement.createdAt}
''';
      });
    } catch (e) {
      setState(() {
        _output = '❌ Error:\n$e';
      });
    } finally {
      setState(() => _isLoading = false);
    }
  }

  Future<void> _checkStatus() async {
    final reference = _referenceController.text;
    if (reference.isEmpty) {
      setState(() {
        _output = '❌ Please enter a reference ID';
      });
      return;
    }

    setState(() {
      _isLoading = true;
      _output = 'Checking status...';
    });

    try {
      TransactionStatus status;
      if (reference.startsWith('PAYOUT')) {
        status = await _client.status.checkDisbursementStatus(reference);
      } else {
        status = await _client.status.checkCollectionStatus(reference);
      }

      setState(() {
        _output =
            '''
✅ Status Retrieved!

Reference ID: ${status.referenceId}
Status: ${status.status}
Amount: ${status.amount} ${status.currency ?? 'ZMW'}
Account: ${status.accountNumber}
Payment Type: ${status.paymentType}
${status.message != null ? 'Message: ${status.message}' : ''}

Is Successful: ${status.isSuccessful}
Is Pending: ${status.isPending}
Is Failed: ${status.isFailed}
''';
      });
    } catch (e) {
      setState(() {
        _output = '❌ Error:\n$e';
      });
    } finally {
      setState(() => _isLoading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Lipila SDK Demo'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            // API Key Input
            TextField(
              controller: _apiKeyController,
              decoration: const InputDecoration(
                labelText: 'API Key',
                border: OutlineInputBorder(),
                prefixIcon: Icon(Icons.key),
              ),
              onChanged: (_) => _initClient(),
            ),
            const SizedBox(height: 16),

            // Amount Input
            TextField(
              controller: _amountController,
              decoration: const InputDecoration(
                labelText: 'Amount',
                border: OutlineInputBorder(),
                prefixIcon: Icon(Icons.money),
              ),
              keyboardType: TextInputType.number,
            ),
            const SizedBox(height: 16),

            // Phone Input
            TextField(
              controller: _phoneController,
              decoration: const InputDecoration(
                labelText: 'Phone Number',
                border: OutlineInputBorder(),
                prefixIcon: Icon(Icons.phone),
              ),
              keyboardType: TextInputType.phone,
            ),
            const SizedBox(height: 16),

            // Reference ID Input
            TextField(
              controller: _referenceController,
              decoration: const InputDecoration(
                labelText: 'Reference ID (optional)',
                border: OutlineInputBorder(),
                prefixIcon: Icon(Icons.tag),
              ),
            ),
            const SizedBox(height: 24),

            // Action Buttons
            Wrap(
              spacing: 8,
              runSpacing: 8,
              children: [
                ElevatedButton.icon(
                  onPressed: _isLoading ? null : _checkBalance,
                  icon: const Icon(Icons.account_balance_wallet),
                  label: const Text('Check Balance'),
                ),
                ElevatedButton.icon(
                  onPressed: _isLoading ? null : _createCollection,
                  icon: const Icon(Icons.arrow_downward),
                  label: const Text('Create Collection'),
                  style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.green,
                    foregroundColor: Colors.white,
                  ),
                ),
                ElevatedButton.icon(
                  onPressed: _isLoading ? null : _createDisbursement,
                  icon: const Icon(Icons.arrow_upward),
                  label: const Text('Create Disbursement'),
                  style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.orange,
                    foregroundColor: Colors.white,
                  ),
                ),
                ElevatedButton.icon(
                  onPressed: _isLoading ? null : _checkStatus,
                  icon: const Icon(Icons.info),
                  label: const Text('Check Status'),
                  style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.blue,
                    foregroundColor: Colors.white,
                  ),
                ),
              ],
            ),
            const SizedBox(height: 24),

            // Output Display
            Container(
              padding: const EdgeInsets.all(16),
              decoration: BoxDecoration(
                color: Colors.grey[100],
                borderRadius: BorderRadius.circular(8),
                border: Border.all(color: Colors.grey[300]!),
              ),
              constraints: const BoxConstraints(minHeight: 200),
              child: _isLoading
                  ? const Center(child: CircularProgressIndicator())
                  : SelectableText(
                      _output,
                      style: const TextStyle(
                        fontFamily: 'monospace',
                        fontSize: 13,
                      ),
                    ),
            ),

            const SizedBox(height: 24),

            // Info Card
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Test Credentials',
                      style: Theme.of(context).textTheme.titleMedium,
                    ),
                    const SizedBox(height: 8),
                    const Text(
                      '• Success: 0977000001\n'
                      '• Failure: 0977000002\n'
                      '• Pending: 0977000003',
                      style: TextStyle(fontFamily: 'monospace'),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _apiKeyController.dispose();
    _amountController.dispose();
    _phoneController.dispose();
    _referenceController.dispose();
    _client.close();
    super.dispose();
  }
}
0
likes
0
points
109
downloads

Publisher

unverified uploader

Weekly Downloads

Official Flutter SDK for Lipila payment gateway. Accept payments and make disbursements in Zambia.

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, http, meta

More

Packages that depend on lipila_flutter

Packages that implement lipila_flutter