paygic 1.0.3 copy "paygic: ^1.0.3" to clipboard
paygic: ^1.0.3 copied to clipboard

Official plugin of Paygic Upi Payments by Paygic payment gateway. Powered by Yes Bank.

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Paygic UPI Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFF2B1966),
        ),
        useMaterial3: true,
      ),
      home: const PaymentDemoPage(),
    );
  }
}

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

  @override
  State<PaymentDemoPage> createState() => _PaymentDemoPageState();
}

class _PaymentDemoPageState extends State<PaymentDemoPage> {
  // Form controllers
  final _midController = TextEditingController(text: '');
  final _tokenController = TextEditingController(text: '');
  final _amountController = TextEditingController(text: '1');
  final _orderIdController = TextEditingController();
  final _nameController = TextEditingController(text: 'Test Customer');
  final _emailController = TextEditingController(text: '[email protected]');
  final _mobileController = TextEditingController(text: '9876543210');
  
  PaymentResult? _lastResult;
  bool _isLoading = false;
  bool _hasUpiApp = false;

  @override
  void initState() {
    super.initState();
    _checkUpiAvailability();
    _generateOrderId();
  }

  void _generateOrderId() {
    _orderIdController.text = 'ORDER_${DateTime.now().millisecondsSinceEpoch}';
  }

  Future<void> _checkUpiAvailability() async {
    final hasUpi = await Paygic.hasUpiApp();
    setState(() {
      _hasUpiApp = hasUpi;
    });
  }

  Future<void> _initiatePayment() async {
    // Validate inputs
    if (_midController.text.isEmpty) {
      _showError('Please enter Merchant ID (MID)');
      return;
    }
    if (_tokenController.text.isEmpty) {
      _showError('Please enter API Token');
      return;
    }

    setState(() {
      _isLoading = true;
      _lastResult = null;
    });

    try {
      // NEW SIMPLIFIED API - Just call initiatePayment!
      final result = await Paygic.initiatePayment(
        context: context,
        mid: _midController.text.trim(),
        token: _tokenController.text.trim(),
        amount: double.tryParse(_amountController.text) ?? 1.0,
        merchantReferenceId: _orderIdController.text.trim(),
        customerName: _nameController.text.trim(),
        customerEmail: _emailController.text.trim(),
        customerMobile: _mobileController.text.trim(),

      );

      setState(() {
        _lastResult = result;
        _isLoading = false;
      });

      // Handle result
      if (mounted) {
        _handleResult(result);
      }
      
      // Generate new order ID for next payment
      _generateOrderId();
    } catch (e) {
      setState(() {
        _isLoading = false;
      });
      
      if (mounted) {
        _showError('Error: $e');
      }
    }
  }

  void _handleResult(PaymentResult result) {
    if (result.isSuccess) {
      // Payment successful!
      showDialog(
        context: context,
        builder: (context) => AlertDialog(
          title: const Row(
            children: [
              Icon(Icons.check_circle, color: Colors.green, size: 32),
              SizedBox(width: 12),
              Text('Payment Successful'),
            ],
          ),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              _buildResultRow('UTR', result.utr ?? 'N/A'),
              _buildResultRow('Amount', '₹${result.amount?.toStringAsFixed(2) ?? 'N/A'}'),
              _buildResultRow('Status', result.txnStatus ?? 'SUCCESS'),
            ],
          ),
          actions: [
            ElevatedButton(
              onPressed: () => Navigator.pop(context),
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.green,
                foregroundColor: Colors.white,
              ),
              child: const Text('Done'),
            ),
          ],
        ),
      );
    } else if (result.isFailed) {
      // Payment failed
      _showError(result.errorMessage ?? 'Payment failed');
    } else if (result.isCancelled) {
      // User cancelled - show subtle message
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Payment cancelled'),
          duration: Duration(seconds: 2),
        ),
      );
    }
  }

  Widget _buildResultRow(String label, String value) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 4),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(label, style: const TextStyle(fontWeight: FontWeight.bold)),
          Text(value),
        ],
      ),
    );
  }

  void _showError(String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(message),
        backgroundColor: Colors.red,
        duration: const Duration(seconds: 4),
      ),
    );
  }

  Future<void> _checkInstalledApps() async {
    final apps = await Paygic.getInstalledUpiApps();
    
    if (mounted) {
      showDialog(
        context: context,
        builder: (context) => AlertDialog(
          title: const Text('Installed UPI Apps'),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            children: apps.isEmpty
                ? [const Text('No UPI apps found')]
                : apps.map((app) => ListTile(
                    leading: const Icon(Icons.payment),
                    title: Text(app.displayName),
                  )).toList(),
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: const Text('OK'),
            ),
          ],
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Paygic UPI Demo'),
        backgroundColor: const Color(0xFF2B1966),
        foregroundColor: Colors.white,
        actions: [
          IconButton(
            icon: const Icon(Icons.apps),
            onPressed: _checkInstalledApps,
            tooltip: 'Check UPI Apps',
          ),
        ],
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            // UPI Availability indicator
            Container(
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: _hasUpiApp ? Colors.green.shade50 : Colors.orange.shade50,
                borderRadius: BorderRadius.circular(8),
              ),
              child: Row(
                children: [
                  Icon(
                    _hasUpiApp ? Icons.check_circle : Icons.warning,
                    color: _hasUpiApp ? Colors.green : Colors.orange,
                  ),
                  const SizedBox(width: 8),
                  Text(
                    _hasUpiApp ? 'UPI apps available' : 'No UPI apps detected',
                    style: TextStyle(
                      color: _hasUpiApp ? Colors.green.shade700 : Colors.orange.shade700,
                    ),
                  ),
                ],
              ),
            ),
            const SizedBox(height: 24),

            // Merchant Credentials Section
            const Text(
              'Merchant Credentials',
              style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
            ),
            const SizedBox(height: 8),
            TextField(
              controller: _midController,
              decoration: const InputDecoration(
                labelText: 'Merchant ID (MID)',
                border: OutlineInputBorder(),
                prefixIcon: Icon(Icons.business),
              ),
            ),
            const SizedBox(height: 12),
            TextField(
              controller: _tokenController,
              decoration: const InputDecoration(
                labelText: 'API Token',
                border: OutlineInputBorder(),
                prefixIcon: Icon(Icons.key),
              ),
              obscureText: true,
            ),
            const SizedBox(height: 24),

            // Payment Details Section
            const Text(
              'Payment Details',
              style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
            ),
            const SizedBox(height: 8),
            Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: _amountController,
                    decoration: const InputDecoration(
                      labelText: 'Amount (₹)',
                      border: OutlineInputBorder(),
                      prefixIcon: Icon(Icons.currency_rupee),
                    ),
                    keyboardType: TextInputType.number,
                  ),
                ),
                const SizedBox(width: 12),
                Expanded(
                  child: TextField(
                    controller: _orderIdController,
                    decoration: InputDecoration(
                      labelText: 'Order ID',
                      border: const OutlineInputBorder(),
                      suffixIcon: IconButton(
                        icon: const Icon(Icons.refresh),
                        onPressed: _generateOrderId,
                      ),
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 24),

            // Customer Details Section
            const Text(
              'Customer Details',
              style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
            ),
            const SizedBox(height: 8),
            TextField(
              controller: _nameController,
              decoration: const InputDecoration(
                labelText: 'Customer Name',
                border: OutlineInputBorder(),
                prefixIcon: Icon(Icons.person),
              ),
            ),
            const SizedBox(height: 12),
            TextField(
              controller: _emailController,
              decoration: const InputDecoration(
                labelText: 'Customer Email',
                border: OutlineInputBorder(),
                prefixIcon: Icon(Icons.email),
              ),
              keyboardType: TextInputType.emailAddress,
            ),
            const SizedBox(height: 12),
            TextField(
              controller: _mobileController,
              decoration: const InputDecoration(
                labelText: 'Customer Mobile',
                border: OutlineInputBorder(),
                prefixIcon: Icon(Icons.phone),
              ),
              keyboardType: TextInputType.phone,
            ),
            const SizedBox(height: 24),

            // Pay button
            ElevatedButton(
              onPressed: _isLoading ? null : _initiatePayment,
              style: ElevatedButton.styleFrom(
                backgroundColor: const Color(0xFF2B1966),
                foregroundColor: Colors.white,
                padding: const EdgeInsets.symmetric(vertical: 16),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(8),
                ),
              ),
              child: _isLoading
                  ? const SizedBox(
                      height: 20,
                      width: 20,
                      child: CircularProgressIndicator(
                        strokeWidth: 2,
                        valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
                      ),
                    )
                  : const Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Icon(Icons.payment),
                        SizedBox(width: 8),
                        Text(
                          'Pay Now',
                          style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
                        ),
                      ],
                    ),
            ),
            const SizedBox(height: 24),

            // Last result
            if (_lastResult != null) ...[
              Container(
                padding: const EdgeInsets.all(16),
                decoration: BoxDecoration(
                  color: _lastResult!.isSuccess 
                      ? Colors.green.shade50 
                      : (_lastResult!.isCancelled 
                          ? Colors.grey.shade100 
                          : Colors.red.shade50),
                  borderRadius: BorderRadius.circular(8),
                ),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Last Payment: ${_lastResult!.status.name.toUpperCase()}',
                      style: const TextStyle(fontWeight: FontWeight.bold),
                    ),
                    if (_lastResult!.utr != null)
                      Text('UTR: ${_lastResult!.utr}'),
                    if (_lastResult!.amount != null)
                      Text('Amount: ₹${_lastResult!.amount?.toStringAsFixed(2)}'),
                    if (_lastResult!.errorMessage != null)
                      Text('Message: ${_lastResult!.errorMessage}'),
                  ],
                ),
              ),
            ],

            const SizedBox(height: 24),

            // Instructions
            Container(
              padding: const EdgeInsets.all(16),
              decoration: BoxDecoration(
                color: Colors.blue.shade50,
                borderRadius: BorderRadius.circular(8),
              ),
              child: const Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      Icon(Icons.info, color: Colors.blue),
                      SizedBox(width: 8),
                      Text(
                        'How it works',
                        style: TextStyle(
                          fontWeight: FontWeight.bold,
                          color: Colors.blue,
                        ),
                      ),
                    ],
                  ),
                  SizedBox(height: 8),
                  Text(
                    '1. Enter your Paygic MID and Token\n'
                    '2. Fill payment and customer details\n'
                    '3. Click "Pay Now"\n'
                    '4. Choose UPI app and complete payment\n'
                    '5. Result returned automatically!',
                    style: TextStyle(fontSize: 13),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _midController.dispose();
    _tokenController.dispose();
    _amountController.dispose();
    _orderIdController.dispose();
    _nameController.dispose();
    _emailController.dispose();
    _mobileController.dispose();
    super.dispose();
  }
}
0
likes
130
points
143
downloads

Publisher

verified publisherpaygic.in

Weekly Downloads

Official plugin of Paygic Upi Payments by Paygic payment gateway. Powered by Yes Bank.

Homepage
Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

flutter, http, plugin_platform_interface, qr_flutter, socket_io_client, url_launcher

More

Packages that depend on paygic

Packages that implement paygic