payfast_flutter 0.0.3 copy "payfast_flutter: ^0.0.3" to clipboard
payfast_flutter: ^0.0.3 copied to clipboard

Flutter SDK for PayFast payment gateway integration with WebView support.

PayFast Flutter SDK #

πŸš€ Pakistan’s First PayFast Flutter SDK #

Pakistan’s first Flutter SDK designed to simplify PayFast payment gateway integration for modern mobile applications.

🎯 Features #

  • Production-Ready: Fully tested and production-ready SDK
  • Clean API: Simple, Stripe-like interface for easy integration
  • Secure Token Authentication: SHA256 signature generation for secure transactions
  • WebView-Based Payments: Secure payment processing via WebView
  • Customizable Configuration: Full control over payment parameters
  • Error Handling: Comprehensive error handling and user feedback
  • Support for Multiple Currencies: Flexible currency support (default: PKR)
  • Deep Linking: Success/failure URL monitoring with callback support
  • Nullable Safety: Fully null-safe Dart code

πŸ“‹ Requirements #

  • Flutter SDK: >=3.0.0 <4.0.0
  • Dart SDK: >=3.10.8
  • Active PayFast merchant account

πŸ“¦ Installation #

Add this to your pubspec.yaml:

dependencies:
  payfast_flutter:
    path: ../  # For local development

Then run:

flutter pub get

πŸš€ Quick Start #

Basic Implementation (3 steps) #

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

class CheckoutPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Checkout')),
      body: Center(
        child: ElevatedButton(
          onPressed: () => _startPayment(context),
          child: Text('Pay 100 PKR'),
        ),
      ),
    );
  }

  void _startPayment(BuildContext context) {
    final config = PayFastConfig(
      merchantId: "XXXX",   
      securedKey: "XXXX",
      basketId: "ORDER123",
      amount: "100",
      successUrl: "https://example.com/success",
      failureUrl: "https://example.com/failure",
      checkoutUrl: "https://example.com/ipn",
    );

    PayFast.startPayment(
      context: context,
      config: config,
      onResult: (result) {
        if (result.success) {
          print('βœ“ Payment successful!');
          print('Transaction ID: ${result.transactionId}');
        } else {
          print('βœ— Payment failed: ${result.message}');
        }
      },
    );
  }
}

πŸ“š API Reference #

PayFastConfig #

Configuration class for payment parameters.

Required Parameters

PayFastConfig(
  merchantId: "241665",           // Your PayFast merchant ID
  securedKey: "XXXX",             // Your secure key
  basketId: "ORDER123",           // Unique order ID
  amount: "100.00",               // Amount in decimal format
  successUrl: "https://...",      // Redirect on success
  failureUrl: "https://...",      // Redirect on failure
  checkoutUrl: "https://...",     // IPN endpoint
)

Optional Parameters

PayFastConfig(
  // ... required params ...
  currency: "PKR",                // Default: "PKR"
  txnDesc: "Product Purchase",    // Default: "Payment Transaction"
  customerEmail: "user@example.com",
  customerMobile: "03001234567",
  environment: "sandbox",         // Default: "sandbox"
  additionalDescription: "Order details", // Default: "Flutter Payment"
)

Available Properties

Property Type Default Description
merchantId String Required PayFast merchant ID
securedKey String Required Secure key for authentication
basketId String Required Unique transaction ID
amount String Required Payment amount (decimal)
successUrl String Required Success redirect URL
failureUrl String Required Failure redirect URL
checkoutUrl String Required IPN checkout URL
currency String "PKR" Currency code
txnDesc String "Payment Transaction" Transaction description
customerEmail String? null Customer email (optional)
customerMobile String? null Customer phone (optional)
environment String "sandbox" "sandbox" or "live"
additionalDescription String "Flutter Payment" Additional description

PayFast #

Main SDK class for initiating payments.

startPayment()

Initiates a complete payment flow.

PayFast.startPayment({
  required BuildContext context,
  required PayFastConfig config,
  required Function(PayFastResult result) onResult,
});

Parameters:

  • context: BuildContext for navigation
  • config: PayFastConfig instance with payment details
  • onResult: Callback function that receives PayFastResult

Flow:

  1. βœ“ Requests access token from PayFast API
  2. βœ“ Opens WebView with payment form
  3. βœ“ Auto-submits form to PayFast
  4. βœ“ Monitors for success/failure redirects
  5. βœ“ Returns result via callback

PayFastResult #

Result model returned from payment callback.

class PayFastResult {
  final bool success;           // Payment successful?
  final String message;         // Status message
  final String? transactionId;  // Transaction ID (if successful)
}

Example:

(result) {
  if (result.success) {
    print('Transaction: ${result.transactionId}');
    print('Message: ${result.message}');
  }
}

PayFastService #

Low-level service for API communications.

getAccessToken()

Requests an access token from PayFast API.

final token = await PayFastService.getAccessToken(
  config: payFastConfig,
);

PayFastSignature #

Utility for generating SHA256 signatures.

final signature = PayFastSignature.generate(
  securedKey: "XXXX",
  basketId: "ORDER123",
  amount: "100.00",
);

πŸ’‘ Advanced Usage #

Complete Example #

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'PayFast SDK Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: PaymentDemo(),
    );
  }
}

class PaymentDemo extends StatefulWidget {
  @override
  State<PaymentDemo> createState() => _PaymentDemoState();
}

class _PaymentDemoState extends State<PaymentDemo> {
  String _paymentStatus = "Ready";
  PayFastResult? _lastResult;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('PayFast Payment Demo')),
      body: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            // Status Display
            Card(
              child: Padding(
                padding: EdgeInsets.all(16),
                child: Column(
                  children: [
                    Text('Payment Status', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
                    SizedBox(height: 8),
                    Text(_paymentStatus),
                    if (_lastResult != null) ...[
                      SizedBox(height: 16),
                      Container(
                        padding: EdgeInsets.all(12),
                        decoration: BoxDecoration(
                          color: _lastResult!.success ? Colors.green[100] : Colors.red[100],
                          borderRadius: BorderRadius.circular(8),
                        ),
                        child: Column(
                          children: [
                            Text(
                              _lastResult!.success ? 'βœ“ Success' : 'βœ— Failed',
                              style: TextStyle(
                                fontSize: 16,
                                fontWeight: FontWeight.bold,
                                color: _lastResult!.success ? Colors.green : Colors.red,
                              ),
                            ),
                            SizedBox(height: 8),
                            Text(_lastResult!.message),
                            if (_lastResult!.transactionId != null) ...[
                              SizedBox(height: 8),
                              Text('ID: ${_lastResult!.transactionId}', style: TextStyle(fontSize: 12)),
                            ]
                          ],
                        ),
                      ),
                    ]
                  ],
                ),
              ),
            ),
            SizedBox(height: 24),
            
            // Payment Button
            ElevatedButton.icon(
              onPressed: () => _initiatePayment(),
              icon: Icon(Icons.payment),
              label: Text('Start Payment'),
              style: ElevatedButton.styleFrom(
                padding: EdgeInsets.symmetric(vertical: 16),
              ),
            ),
          ],
        ),
      ),
    );
  }

  void _initiatePayment() {
    final config = PayFastConfig(
      merchantId: "241665",
      securedKey: "XXXX",
      basketId: "ORD-${DateTime.now().millisecondsSinceEpoch}",
      amount: "100.00",
      successUrl: "https://example.com/success",
      failureUrl: "https://example.com/failure",
      checkoutUrl: "https://example.com/ipn",
      currency: "PKR",
      txnDesc: "Product Purchase",
      customerEmail: "customer@example.com",
      customerMobile: "03001234567",
    );

    setState(() => _paymentStatus = "Processing...");

    PayFast.startPayment(
      context: context,
      config: config,
      onResult: (result) {
        setState(() {
          _lastResult = result;
          _paymentStatus = result.success ? "Completed" : "Failed";
        });

        // Show snackbar
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text(result.message),
            backgroundColor: result.success ? Colors.green : Colors.red,
          ),
        );
      },
    );
  }
}

Dynamic Amount Calculation #

String calculateAmount(List<Item> items) {
  double total = items.fold(0, (sum, item) => sum + item.price);
  return total.toStringAsFixed(2);
}

final config = PayFastConfig(
  // ... other params ...
  amount: calculateAmount(cartItems),
);

Custom Error Handling #

PayFast.startPayment(
  context: context,
  config: config,
  onResult: (result) {
    if (!result.success) {
      // Show custom error dialog
      showDialog(
        context: context,
        builder: (context) => AlertDialog(
          title: Text('Payment Failed'),
          content: Text(result.message),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: Text('Retry'),
            ),
          ],
        ),
      );
    }
  },
);

πŸ”’ Security #

  • βœ“ SHA256 signature generation for request verification
  • βœ“ Token-based authentication
  • βœ“ Support for sandbox and live environments
  • βœ“ HTTPS-only communication
  • βœ“ No sensitive data stored locally
  • βœ“ Null-safe Dart code

🌍 Supported Currencies #

Currently supported currencies:

  • PKR (Pakistani Rupee) - Default

More currencies can be added via configuration.

πŸ“± Platform Support #

  • βœ… Android
  • βœ… iOS
  • ⚠️ Web (requires WebView configuration)
  • ⚠️ Windows (requires WebView configuration)
  • ⚠️ macOS (requires WebView configuration)

πŸ“– Examples #

A complete example app is available in the example folder:

cd example
flutter run

πŸ› Troubleshooting #

Issue: "Failed to get access token" #

Solution: Check that your credentials are correct:

  • Verify merchantId
  • Verify securedKey
  • Ensure internet connectivity
  • Test in sandbox mode first

Issue: Payment page doesn't load #

Solution:

  • Check WebView is properly initialized
  • Verify URLs are correct
  • Ensure JavaScript is enabled in WebView
  • Check console for errors

Issue: Success/Failure redirect not triggered #

Solution:

  • Verify successUrl and failureUrl are correct
  • Check URLs contain "success" or "failure" keywords
  • Ensure proper URL encoding

πŸ“ Dependencies #

  • flutter: sdk
  • http: ^1.2.0
  • webview_flutter: ^4.7.0
  • crypto: ^3.0.3

πŸ“„ API Endpoints #

Purpose Endpoint
Get Token https://ipg1.apps.net.pk/Ecommerce/api/Transaction/GetAccessToken
Process Payment https://ipg1.apps.net.pk/Ecommerce/api/Transaction/PostTransaction

πŸ“„ License #

MIT License - See LICENSE file for details

Copyright (c) 2026 Abdullah Ghaffar

🀝 Contributing #

Contributions are welcome! Please feel free to submit pull requests.

πŸ’¬ Support #

For issues, questions, or suggestions:

πŸŽ“ Learn More #


Built with ❀️ for Flutter developers

6
likes
140
points
148
downloads

Publisher

unverified uploader

Weekly Downloads

Flutter SDK for PayFast payment gateway integration with WebView support.

Repository (GitHub)
View/report issues

Topics

#payfast #payment #flutter-payment #pakistan-payment

Documentation

API reference

License

unknown (license)

Dependencies

crypto, flutter, http, webview_flutter

More

Packages that depend on payfast_flutter