The Dart-First Paystack SDK
Built from the ground up for Dart and Flutter developers
Pure Dart Core • Type-Safe • Production-Ready • Transaction-Focused
Unlike generic API wrappers, MindPaystack is architected specifically for the Dart ecosystem
// Other SDKs: Dynamic types and unclear errors final response = await http.post(url, body: data); final result = json.decode(response.body); // Map<String, dynamic> // MindPaystack: Strongly typed, clean, and predictable final transaction = await MindPaystack.instance.transaction.initialize( InitializeTransactionOptions( email: 'customer@example.com', amount: Money.fromCents(50000, Currency.ngn), // Type-safe money handling ), ); // Returns: Resource<TransactionInitialization>| Feature | MindPaystack | Generic HTTP Client |
|---|---|---|
| Type Safety | Available - Strongly typed responses | Missing - Dynamic Map<String, dynamic> |
| Error Handling | Available - Structured MindException hierarchy | Missing - Generic HTTP errors |
| Dependency Injection | Available - Built-in Injectable support | Missing - Manual setup required |
| Testing | Available - Mockable services & interfaces | Missing - HTTP mocking complexity |
| Money/Currency | Available - Dedicated value objects | Missing - Raw integers (error-prone) |
| Dart Conventions | Available - Follows Dart/Flutter patterns | Missing - Generic API wrapper |
For Pure Dart projects (CLI, server, backend):
dart pub add mind_paystackFor Flutter applications:
dart pub add mind_paystack # Note: mind_paystack_flutter coming soon!import 'package:mind_paystack/mind_paystack.dart'; Future<void> main() async { // 🔧 One-time setup await MindPaystack.initialize( PaystackConfig( publicKey: 'pk_test_your_public_key', secretKey: 'sk_test_your_secret_key', environment: Environment.test, ), ); // 🚀 Ready to use! print('MindPaystack initialized successfully!'); }final sdk = MindPaystack.instance; try { final transaction = await sdk.transaction.initialize( InitializeTransactionOptions( email: 'customer@example.com', amount: Money.fromCents(50000, Currency.ngn), // ₦500.00 metadata: {'product_id': '12345'}, ), ); // ✅ Type-safe access to all properties print('Payment URL: ${transaction.data.authorizationUrl}'); print('Reference: ${transaction.data.reference}'); } on MindException catch (e) { // 🛡️ Structured error handling print('Payment failed: ${e.message} (${e.code})'); }final verification = await sdk.transaction.verify( VerifyTransactionOptions(reference: 'your-transaction-reference'), ); if (verification.data.status == 'success') { print('💰 Payment successful!'); // Fulfill the order } else { print('❌ Payment failed or pending'); }E-commerce Checkout
class CheckoutService { static Future<String?> createPayment({ required String customerEmail, required List<CartItem> items, }) async { final total = items.fold(0, (sum, item) => sum + item.price); final sdk = MindPaystack.instance; try { final result = await sdk.transaction.initialize( InitializeTransactionOptions( email: customerEmail, amount: Money.fromCents(total, Currency.ngn), metadata: { 'order_items': items.map((e) => e.toJson()).toList(), 'customer_id': await getUserId(), }, ), ); return result.data.authorizationUrl; } on MindException catch (e) { _logger.error('Checkout failed', e); return null; } } }Testing with Mocks
class MockTransactionService extends Mock implements ITransactionService {} void main() { group('PaymentService Tests', () { late MockTransactionService mockTransaction; late PaymentService paymentService; setUp(() { mockTransaction = MockTransactionService(); // Inject mock via dependency injection GetIt.instance.registerSingleton<ITransactionService>(mockTransaction); paymentService = PaymentService(); }); test('should create payment successfully', () async { // Arrange when(() => mockTransaction.initialize(any())) .thenAnswer((_) async => mockTransactionResponse); // Act final result = await paymentService.createPayment(testRequest); // Assert expect(result.isSuccess, true); verify(() => mockTransaction.initialize(any())).called(1); }); }); }"Finally, a Paystack SDK that feels like it was built by Dart developers, for Dart developers."
— Flutter Developer
"The type safety and error handling saved us hours of debugging. No more
dynamicnightmares!"
— Backend Developer
"Injectable integration made testing our payment flows so much cleaner."
— QA Engineer
| Use Case | Why MindPaystack Excels |
|---|---|
| E-commerce Apps | Type-safe money handling, structured error handling |
| Fintech Platforms | Enterprise-grade architecture, comprehensive testing |
| SaaS Billing | Transaction management, webhook handling (coming soon) |
| Banking Apps | Security-first design, audit trails |
| Mobile Apps | Flutter-core support, with UI components coming soon |
| Package | Platform | Status | Features |
|---|---|---|---|
mind_paystack | Pure Dart | Available | Core SDK, Transaction APIs |
mind_paystack_flutter | Flutter | Coming Soon | UI widgets, platform integration |
| Platform | Support Level | Package Required |
|---|---|---|
| Flutter Mobile | Core Features | mind_paystack |
| Flutter Web | Core Features | mind_paystack |
| Flutter Desktop | Core Features | mind_paystack |
| Dart VM (Server) | Full Support | mind_paystack |
| Dart CLI Tools | Full Support | mind_paystack |
@injectable class PaymentService { PaymentService(this._transactionService); final ITransactionService _transactionService; Future<PaymentResult> processPayment(PaymentRequest request) async { // Fully testable and mockable } }// Error-prone raw integers final amount = 50000; // Is this ₦500 or ₦50,000? // Clear, type-safe money values final amount = Money.fromCents(50000, Currency.ngn); // Clearly ₦500.00 final naira = Money.fromNaira(500.00); // Alternative constructortry { final result = await sdk.transaction.initialize(request); } on MindException catch (e) { switch (e.category) { case ErrorCategory.network: _handleNetworkError(e); case ErrorCategory.validation: _showValidationErrors(e.validationErrors); case ErrorCategory.paystack: _handlePaystackError(e); } }- Transaction Management: Initialize, verify, list transactions
- Type-Safe Money Handling: Structured money/currency objects
- Error Handling: Comprehensive MindException system
- Dependency Injection: Built-in Injectable support
- Pure Dart Support: CLI tools, server applications, web
- Charge Operations: Direct card charging and tokenization
- Payment Channels: Available payment methods management
- Payment Methods: Customer payment method storage
- Flutter Package: UI widgets and platform integration
- Webhooks: Event handling and verification
- Subscriptions: Recurring billing management
- Advanced Analytics: Transaction insights and reporting
- Multi-tenant Support: Organization-level configurations
- Offline Capabilities: Queue transactions for later processing
- Enhanced Security: Additional fraud prevention tools
| Resource | Description |
|---|---|
| Full Documentation | Complete guides and API reference |
| Getting Started | 3-step integration guide |
| Architecture Guide | Understanding the SDK design |
| Testing Guide | Mocking and unit testing |
| Configuration | Environment setup and options |
We welcome and appreciate contributions from developers of all skill levels!
Our detailed contribution guide covers:
- Quick Start - Get up and running in minutes
- Project Structure - Understanding the monorepo architecture
- Development Workflow - Step-by-step contribution process
- Code Standards - Dart/Flutter style guidelines with examples
- Testing Guidelines - TDD approach, mocking, and coverage requirements
- Pull Request Process - Templates, checklists, and review process
- Security Guidelines - Best practices for handling sensitive data
- Development Tools - VS Code settings, Melos commands, Git hooks
| I Want To... | Action |
|---|---|
| Report a Bug | Open an Issue |
| Request a Feature | Request Feature |
| Ask Questions | Start a Discussion |
| Contribute Code | See Contributing Guide |
# 1. Fork and clone the repository git clone https://github.com/Dartmind-OpenSource/mind-paystack.git cd mind-paystack # 2. Install Melos and bootstrap packages dart pub global activate melos melos bootstrap # 3. Verify setup melos run test && melos run analyze # You're ready to contribute!New to open source? We're here to help! Check out issues labeled good first issue for beginner-friendly contributions.
This project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤️ by the Dart community
Star us on GitHub • Follow us on Twitter • Join our Discord
Building the future of payments in Dart