ecocash_dart_sdk 2.1.0
ecocash_dart_sdk: ^2.1.0 copied to clipboard
A comprehensive Dart SDK for integrating with the Ecocash Open API with advanced features like retry mechanisms, analytics, validation, and batch operations
Ecocash Dart SDK #
A comprehensive, production-ready Dart SDK for integrating with the Ecocash Open API. This SDK provides enterprise-grade features for processing payments, refunds, and transaction lookups in the Zimbabwe fintech ecosystem.
Features #
Core API Features #
- Payment Processing - C2B (Customer to Business) instant payments
- Refund Management - Process refunds for previous transactions
- Transaction Lookup - Check transaction status and details
- Mobile Money Integration - Full Zimbabwe mobile money support
Advanced SDK Features #
- Input Validation - Comprehensive validation for all inputs
- Retry Mechanism - Configurable retry with exponential backoff
- Batch Operations - Process multiple transactions concurrently
- Analytics & Reporting - Built-in transaction analytics
- Logging & Auditing - Comprehensive logging with data masking
- Circuit Breaker - Prevent cascading failures
- Offline Queue - Queue transactions when network is unavailable
- Sandbox Utilities - Testing tools and mock responses
- Data Security - Automatic masking of sensitive information
- Type Safety - Full Dart null safety and strong typing
Installation #
Add to your pubspec.yaml
:
dependencies:
http: ^1.1.0
uuid: ^4.1.0
Then run:
dart pub get
Quick Start #
Basic Usage #
import 'package:ecocash_dart_sdk/ecocash_dart_sdk.dart';
void main() async {
// Initialize with basic configuration
final ecocash = EcocashApi(
apiKey: "your_api_key_here",
environment: EcocashEnvironment.sandbox,
);
try {
// Make a payment
final payment = await ecocash.makePayment(
customerMsisdn: "263XXXXXXXXX",
amount: 10.50,
reason: "Payment for services",
currency: "USD",
);
print('Payment successful: ${payment.ecocashTransactionReference}');
} catch (e) {
print('Payment failed: $e');
} finally {
ecocash.dispose();
}
}
Advanced Configuration #
import 'package:ecocash_dart_sdk/ecocash_dart_sdk.dart';
void main() async {
// Initialize with all features enabled
final ecocash = EcocashApi(
apiKey: "your_api_key_here",
environment: EcocashEnvironment.sandbox,
bearerToken: "your_bearer_token", // Optional
enableValidation: true,
enableRetries: true,
enableOfflineQueue: true,
enableAnalytics: true,
enableLogging: true,
);
// Use the SDK...
ecocash.dispose();
}
API Reference #
Constructor #
EcocashApi({
required String apiKey,
EcocashEnvironment environment = EcocashEnvironment.sandbox,
String? bearerToken,
bool enableValidation = true,
bool enableRetries = true,
bool enableOfflineQueue = false,
bool enableAnalytics = true,
bool enableLogging = true,
})
Parameters:
apiKey
(required) - Your Ecocash API keyenvironment
(optional) - Sandbox or live environmentbearerToken
(optional) - Bearer token for authenticated endpointsenableValidation
(optional) - Enable input validationenableRetries
(optional) - Enable retry mechanismenableOfflineQueue
(optional) - Enable offline queueenableAnalytics
(optional) - Enable analytics trackingenableLogging
(optional) - Enable logging
Core Methods #
makePayment()
Initiates a C2B (Customer to Business) payment.
Future<PaymentResponse> makePayment({
required String customerMsisdn,
required double amount,
required String reason,
required String currency,
String? sourceReference,
String? clientName,
})
Parameters:
customerMsisdn
- Customer's mobile number (e.g., "263XXXXXXXXX")amount
- Payment amount as double (e.g., 10.50)reason
- Payment description/reasoncurrency
- Currency code (e.g., "USD", "ZWL")sourceReference
- Optional unique reference (UUID generated if not provided)clientName
- Optional client name for the transaction
Example:
final result = await ecocash.makePayment(
customerMsisdn: "263XXXXXXXXX",
amount: 25.00,
reason: "Online purchase",
currency: "USD",
);
processRefund()
Processes a refund for a previous transaction.
Future<RefundResponse> processRefund({
required String originalEcocashTransactionReference,
required String sourceMobileNumber,
required double amount,
required String reasonForRefund,
required String currency,
String? refundCorrelator,
String? clientName,
})
Parameters:
originalEcocashTransactionReference
- Reference from the original paymentsourceMobileNumber
- Customer's mobile numberamount
- Refund amount as doublereasonForRefund
- Refund reason/descriptioncurrency
- Currency coderefundCorrelator
- Optional unique correlator (UUID generated if not provided)clientName
- Optional client name for the refund
Example:
final refund = await ecocash.processRefund(
originalEcocashTransactionReference: "ECO123456789",
sourceMobileNumber: "263XXXXXXXXX",
amount: 10.00,
reasonForRefund: "Customer requested refund",
currency: "USD",
);
lookupTransaction()
Looks up the status of a transaction.
Future<TransactionStatus> lookupTransaction({
required String sourceMobileNumber,
required String sourceReference,
})
Parameters:
sourceMobileNumber
- Customer's mobile numbersourceReference
- The source reference used in the original transaction
Example:
final status = await ecocash.lookupTransaction(
sourceMobileNumber: "263XXXXXXXXX",
sourceReference: "your-source-reference-uuid",
);
Utility Methods #
generateSourceReference()
Generates a new UUID for use as a source reference.
String generateSourceReference()
generateRefundCorrelator()
Generates a new UUID for use as a refund correlator.
String generateRefundCorrelator()
dispose()
Disposes of the HTTP client to free up resources.
void dispose()
Advanced Features #
Batch Operations #
Process multiple payments concurrently:
// Process multiple payments concurrently
final requests = [
PaymentRequest(
customerMsisdn: "263XXXXXXXXX",
amount: 10.0,
reason: "Batch payment 1",
currency: "USD",
sourceReference: ecocash.generateSourceReference(),
),
PaymentRequest(
customerMsisdn: "263XXXXXXXXX",
amount: 15.50,
reason: "Batch payment 2",
currency: "USD",
sourceReference: ecocash.generateSourceReference(),
),
];
final result = await ecocash.batchPayments(
requests,
concurrency: 3, // Process 3 at a time
);
print('Successful: ${result.successful.length}');
print('Failed: ${result.failed.length}');
print('Success Rate: ${(result.successRate * 100).toStringAsFixed(1)}%');
Analytics and Reporting #
Get comprehensive analytics:
// Get comprehensive analytics
final analytics = ecocash.getAnalytics(
startDate: DateTime.now().subtract(Duration(days: 30)),
endDate: DateTime.now(),
);
print('Total Transactions: ${analytics.totalTransactions}');
print('Net Amount: ${analytics.netAmount}');
print('Payment Success Rate: ${(analytics.paymentAnalytics.successRate * 100).toStringAsFixed(1)}%');
// Get payment-specific analytics
final paymentAnalytics = ecocash.getPaymentAnalytics();
print('Total Payments: ${paymentAnalytics.totalPayments}');
print('Average Amount: ${paymentAnalytics.averageAmount}');
// Currency breakdown
for (final entry in paymentAnalytics.currencyBreakdown.entries) {
print('${entry.key}: ${entry.value}');
}
Input Validation #
The SDK includes comprehensive input validation:
import 'package:ecocash_dart_sdk/ecocash_dart_sdk.dart';
// Validate phone numbers
bool isValid = EcocashValidators.isValidMobileNumber("263XXXXXXXXX");
String normalized = EcocashValidators.normalizePhoneNumber("077XXXXXXX"); // Returns "263XXXXXXXXX"
String? operator = EcocashValidators.getMobileNetworkOperator("263XXXXXXXXX"); // Returns "Econet"
// Validate amounts
bool validAmount = EcocashValidators.isValidAmount(50.25); // true
bool invalidAmount = EcocashValidators.isValidAmount(-10.0); // false
// Validate currencies
bool validCurrency = EcocashValidators.isValidCurrency("USD"); // true
bool invalidCurrency = EcocashValidators.isValidCurrency("XYZ"); // false
Retry Configuration #
Configure retry behavior for network resilience:
// Aggressive retry strategy
final aggressiveConfig = RetryConfig(
maxAttempts: 5,
initialDelay: Duration(milliseconds: 500),
maxDelay: Duration(seconds: 30),
backoffMultiplier: 1.5,
exponentialBackoff: true,
retryableStatusCodes: [408, 429, 500, 502, 503, 504],
);
// Conservative retry strategy
final conservativeConfig = RetryConfig(
maxAttempts: 2,
initialDelay: Duration(seconds: 2),
backoffMultiplier: 3.0,
);
final ecocash = EcocashApi(
apiKey: "your_api_key",
retryConfig: aggressiveConfig,
);
Logging Configuration #
Flexible logging system with data masking:
import 'package:ecocash_dart_sdk/ecocash_dart_sdk.dart';
// Console logger with colors
final consoleLogger = ConsoleLogger(
minLevel: LogLevel.info,
colorOutput: true,
);
// File logger with daily rotation
final fileLogger = FileLogger(
filePath: 'logs/ecocash_sdk.log',
minLevel: LogLevel.debug,
rotateDaily: true,
);
// Composite logger (multiple destinations)
final logger = CompositeLogger([consoleLogger, fileLogger]);
// Data masking for sensitive information
final sensitiveData = {
'customerMsisdn': '263XXXXXXXXX',
'apiKey': 'secret_key_12345',
'amount': 100.50,
};
final masked = DataMasker.maskSensitiveData(sensitiveData);
// Result: {'customerMsisdn': '263***XX', 'apiKey': 'se***45', 'amount': 100.50}
Sandbox and Testing #
Comprehensive testing utilities:
import 'package:ecocash_dart_sdk/ecocash_dart_sdk.dart';
// Test phone numbers for different scenarios
final testPhones = {
SandboxUtils.testPhoneSuccess: 'Successful transaction',
SandboxUtils.testPhoneInsufficientFunds: 'Insufficient funds error',
SandboxUtils.testPhoneTimeout: 'Transaction timeout',
SandboxUtils.testPhoneInvalidPin: 'Invalid PIN error',
SandboxUtils.testPhoneNetworkError: 'Network error',
};
// Enable mock responses for testing
final ecocash = EcocashApi(
apiKey: "test_api_key",
environment: EcocashEnvironment.sandbox,
enableValidation: true,
);
// Generate mock responses
final mockPayment = SandboxUtils.mockSuccessfulPaymentResponse(
sourceReference: "test-ref-123",
amount: 50.0,
currency: "USD",
);
Error Handling #
The SDK includes comprehensive error handling:
try {
final payment = await ecocash.makePayment(/* params */);
} on ValidationException catch (e) {
print('Validation Error: ${e.message} (Field: ${e.field})');
} on EcocashApiException catch (e) {
print('API Error: ${e.message}');
print('Status Code: ${e.statusCode}');
print('Response: ${e.response}');
} on CircuitBreakerOpenException catch (e) {
print('Circuit Breaker Open: ${e.message}');
} catch (e) {
print('Unexpected Error: $e');
}
Configuration Examples #
Development Environment #
final devSdk = EcocashApi(
apiKey: "dev_api_key",
environment: EcocashEnvironment.sandbox,
enableValidation: true,
enableRetries: true,
enableOfflineQueue: true,
enableAnalytics: true,
enableLogging: true,
);
Production Environment #
final prodSdk = EcocashApi(
apiKey: "prod_api_key",
environment: EcocashEnvironment.live,
bearerToken: "prod_bearer_token",
enableValidation: true,
enableRetries: true,
enableOfflineQueue: false,
enableAnalytics: true,
enableLogging: true,
);
Testing Environment #
final testSdk = EcocashApi(
apiKey: "test_api_key",
environment: EcocashEnvironment.sandbox,
enableValidation: false,
enableRetries: false,
enableOfflineQueue: false,
enableAnalytics: false,
enableLogging: false,
);
API Endpoints #
The SDK supports the following Ecocash API endpoints:
Method | Endpoint | Purpose |
---|---|---|
POST | /v2/payment/instant/c2b/sandbox |
Initiate C2B payments (sandbox) |
POST | /v2/payment/instant/c2b/live |
Initiate C2B payments (live) |
POST | /v2/refund/instant/c2b/sandbox |
Process refunds (sandbox) |
POST | /v2/refund/instant/c2b/live |
Process refunds (live) |
POST | /v1/transaction/c2b/status/sandbox |
Transaction lookup (sandbox) |
POST | /v1/transaction/c2b/status/live |
Transaction lookup (live) |
Testing #
Run the examples:
# Basic example
dart run example/basic_example.dart
# Advanced example
dart run example/advanced_example.dart
# Main example
dart run example/main.dart
Best Practices #
-
Always dispose of the EcocashApi instance when done:
final ecocash = EcocashApi(apiKey: "key"); try { // Use the API } finally { ecocash.dispose(); }
-
Handle errors gracefully:
try { final result = await ecocash.makePayment(/* params */); } on EcocashApiException catch (e) { // Handle API-specific errors } catch (e) { // Handle other errors }
-
Use meaningful source references:
final ref = ecocash.generateSourceReference(); // Store this reference for future lookups
-
Validate input parameters before making API calls:
if (amount <= 0) { throw ArgumentError('Amount must be positive'); }
Security Features #
- Data Masking: Automatic masking of sensitive data in logs
- Input Validation: Comprehensive validation prevents injection attacks
- Secure Headers: Proper API key and authorization handling
- Network Security: Circuit breaker prevents DoS scenarios
Performance Features #
- Batch Processing: Concurrent processing with configurable limits
- Connection Pooling: Efficient HTTP client reuse
- Retry Optimization: Exponential backoff with jitter
- Circuit Breaker: Fail-fast for improved resilience
- Offline Queue: Handle network interruptions gracefully
Environment Variables #
For production use, consider storing sensitive information in environment variables:
final ecocash = EcocashApi(
apiKey: Platform.environment['ECOCASH_API_KEY'] ?? '',
bearerToken: Platform.environment['ECOCASH_BEARER_TOKEN'],
);
Support #
- API Documentation: Ecocash Developer Portal
- Test Credentials: Use placeholder phone numbers for sandbox testing
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Credits #
Author: Kudah Ndlovu
GitHub: eisax
This SDK is provided for integration with the Ecocash Open API. Please refer to Ecocash's terms of service for API usage guidelines.
Contributing #
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
Changelog #
v2.0.0 - Enhanced Release #
- Added comprehensive input validation
- Implemented retry mechanism with exponential backoff
- Added batch operations support
- Built-in analytics and reporting
- Advanced logging with data masking
- Circuit breaker pattern implementation
- Offline queue management
- Comprehensive sandbox utilities
- Enhanced security features
- Performance optimizations
- Full type safety with data models
- Flexible configuration system
v1.0.0 - Initial Release #
- Basic payment, refund, and lookup operations
- Simple error handling
- UUID generation
- Basic examples and documentation
Built with love by kudah ndhlovu for the Zimbabwe fintech ecosystem