standard_checkout_plugin 1.0.1 copy "standard_checkout_plugin: ^1.0.1" to clipboard
standard_checkout_plugin: ^1.0.1 copied to clipboard

Flutter plugin for integrating standard checkout payment gateway in Android, iOS, and Web applications.

example/lib/main.dart

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:checkout_plugin/checkout_plugin.dart';
import 'package:checkout_plugin/model/pay_request.dart';
import 'package:checkout_plugin/model/pay_result.dart';
import 'package:http/http.dart' as http;
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Checkout Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        useMaterial3: true,
      ),
      home: const CheckoutActivity(),
    );
  }
}

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

  @override
  State<CheckoutActivity> createState() => _CheckoutActivityState();
}

class _CheckoutActivityState extends State<CheckoutActivity> {
  final TextEditingController _descriptionController = TextEditingController();
  final TextEditingController _amountController = TextEditingController();
  final _formKey = GlobalKey<FormState>();
  late PayRequest _payRequest;
  bool _isProcessing = false;
  String _ipAddress = 'Fetching IP...';

  @override
  void initState() {
    super.initState();
    _initializePayRequest();
    _getRealIPAddress();
  }

  void _initializePayRequest() {
    _payRequest = PayRequest(
      memberId: '14691',
      toType: 'TWPayz',
      memberKey: 'KsidL3VNx4rNaxPG9eYBNXNVmxlbZXvn',
      amount: '',
      currency: 'GBP',
      merchantTransactionId: '',
      hostUrl: 'https://sandbox.twpayz.com/transaction/Checkout',
      // hostUrl: 'https://www.google.com'
    );

    _payRequest.orderDescription = 'Testing Transaction';
    _payRequest.country = 'IN';
    _payRequest.city = 'Mumbai';
    _payRequest.state = 'MH';
    _payRequest.postCode = '400064';
    _payRequest.street = 'Malad';
    _payRequest.telnocc = '91';
    _payRequest.phone = '8668459089';
    _payRequest.email = 'riya.patel@gmail.com';
    _payRequest.paymentBrand = '';      // Added - matches Android
    _payRequest.paymentMode = '';       // Added - matches Android
    _payRequest.terminalId = '';        // Added - matches Android
    _payRequest.ipAddress = '';
    _payRequest.device = 'flutter';
  }

  // Method to get IP address
  static Future<String?> getIPForTransaction() async {
    try {
      final response = await http.get(Uri.parse('https://api.ipify.org?format=json'));
      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);
        final ip = data['ip'] as String?;
        return ip;
      }
      return null;
    } catch (e) {
      debugPrint('Failed to get IP: $e');
      return null;
    }
  }

// Method to fetch and set IP in the UI
  Future<void> _getRealIPAddress() async {
    final ip = await getIPForTransaction();
    if (mounted) {
      setState(() {
        _ipAddress = ip ?? 'Not available';
        _payRequest.ipAddress = ip ?? '';
      });
    }
  }

  void _startPayment() async {
    // Check if IP is empty FIRST - before anything else
    if (_payRequest.ipAddress == null || _payRequest.ipAddress!.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('❌ IP Address is empty. Please check your internet connection.'),
          backgroundColor: Colors.red,
          duration: Duration(seconds: 3),
        ),
      );
      return;
    }

    // Then validate the form
    if (_formKey.currentState!.validate()) {
      setState(() => _isProcessing = true);

      _payRequest.merchantTransactionId = _descriptionController.text;
      _payRequest.amount = double.parse(_amountController.text).toStringAsFixed(2);

      try {
        await FlutterPaymentCheckout.initPayment(
          context: context,
          payRequest: _payRequest,
          onSuccess: (PayResult result) {
            if (mounted) {
              setState(() => _isProcessing = false);

              // ✅ Just reset the form and navigate if needed
              _resetForm();
            }
          },
          onFailure: (PayResult result) {
            if (mounted) {
              setState(() => _isProcessing = false);

              // ✅ Just reset the form
              _resetForm();
            }
          },
        );
      } catch (e) {
        if (mounted) {
          setState(() => _isProcessing = false);
          ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(content: Text('Error: ${e.toString()}'))
          );
        }
      }
    }
  }

// ✅ Add this helper method to reset form
  void _resetForm() {
    _descriptionController.clear();
    _amountController.clear();
    _formKey.currentState?.reset();

    // Optionally show a brief success/failure message
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(
        content: Text('Payment completed. Check the result in the dialog.'),
        duration: Duration(seconds: 2),
      ),
    );
  }

  String? _validateDescription(String? value) {
    if (value == null || value.isEmpty) return 'Order description is required';
    if (value.length < 3) return 'Description must be at least 3 characters';
    return null;
  }

  String? _validateAmount(String? value) {
    if (value == null || value.isEmpty) return 'Amount is required';
    final amount = double.tryParse(value);
    if (amount == null || amount <= 0) return 'Please enter a valid amount';
    if (amount > 999999.99) return 'Amount is too high';
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Checkout Demo'),
        backgroundColor: Colors.blue,
        foregroundColor: Colors.white,
      ),
      body: Form(
        key: _formKey,
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              TextFormField(
                controller: _descriptionController,
                decoration: const InputDecoration(
                  labelText: 'Order Description',
                  hintText: 'Enter order description',
                  border: OutlineInputBorder(),
                  prefixIcon: Icon(Icons.description),
                ),
                validator: _validateDescription,
              ),
              const SizedBox(height: 16),
              TextFormField(
                controller: _amountController,
                decoration: const InputDecoration(
                  labelText: 'Amount',
                  hintText: 'Enter amount',
                  border: OutlineInputBorder(),
                  prefixIcon: Icon(Icons.currency_pound),
                  suffixText: 'GBP',
                ),
                keyboardType: const TextInputType.numberWithOptions(decimal: true),
                validator: _validateAmount,
              ),
              const SizedBox(height: 24),
              Card(
                elevation: 2,
                child: Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      const Text('Payment Details:', style: TextStyle(fontWeight: FontWeight.bold)),
                      const Divider(),
                      _buildInfoRow('Member ID:', _payRequest.memberId ?? ''),
                      _buildInfoRow('Currency:', _payRequest.currency ?? ''),
                      _buildInfoRow('IP Address:', _ipAddress),
                    ],
                  ),
                ),
              ),
              const SizedBox(height: 24),
              ElevatedButton(
                onPressed: _isProcessing ? null : _startPayment,
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                  padding: const EdgeInsets.symmetric(vertical: 16),
                ),
                child: _isProcessing
                    ? const SizedBox(height: 20, width: 20, child: CircularProgressIndicator(strokeWidth: 2))
                    : const Text('Pay Now', style: TextStyle(fontSize: 18)),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildInfoRow(String label, String value) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 4),
      child: Row(
        children: [
          SizedBox(width: 100, child: Text(label)),
          Expanded(child: Text(value)),
        ],
      ),
    );
  }

  @override
  void dispose() {
    _descriptionController.dispose();
    _amountController.dispose();
    super.dispose();
  }
}
0
likes
140
points
166
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter plugin for integrating standard checkout payment gateway in Android, iOS, and Web applications.

Homepage

License

unknown (license)

Dependencies

crypto, flutter, http, webview_flutter

More

Packages that depend on standard_checkout_plugin