payfast_flutter 0.0.3
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 navigationconfig: PayFastConfig instance with payment detailsonResult: Callback function that receives PayFastResult
Flow:
- β Requests access token from PayFast API
- β Opens WebView with payment form
- β Auto-submits form to PayFast
- β Monitors for success/failure redirects
- β 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
successUrlandfailureUrlare correct - Check URLs contain "success" or "failure" keywords
- Ensure proper URL encoding
π Dependencies #
flutter: sdkhttp: ^1.2.0webview_flutter: ^4.7.0crypto: ^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:
- π§ Email: support@example.com
- π GitHub Issues: https://github.com/abdullahghaffar4445/payfast_flutter/issues
- π¬ Discussions: https://github.com/abdullahghaffar4445/payfast_flutter/discussions
π Learn More #
Built with β€οΈ for Flutter developers