Skip to content

Commit 5a680cf

Browse files
committed
Add iOS and macOS Podfile configuration, update documentation and error handling
1 parent 1dfa520 commit 5a680cf

File tree

14 files changed

+689
-86
lines changed

14 files changed

+689
-86
lines changed

README.md

Lines changed: 244 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,52 @@
2323

2424
</div>
2525

26+
## Overview
27+
28+
Moneroo Flutter SDK provides a simple and reliable way to integrate payment processing into your Flutter applications, with support for various payment methods across multiple African countries. The SDK offers both a ready-to-use payment widget and a flexible API wrapper for custom implementations.
29+
30+
### Features
31+
32+
- 🌍 **Multi-currency support** - Process payments in XOF, XAF, NGN, GHS, and many other African currencies
33+
- 🔌 **Multiple payment methods** - Support for mobile money, bank transfers, cards, and more
34+
- 🛡️ **Secure transactions** - PCI-compliant payment processing
35+
- 📱 **Ready-to-use UI** - Pre-built payment widget for quick integration
36+
- 🔧 **Flexible API** - Direct API access for custom implementations
37+
- 🧪 **Sandbox mode** - Test your integration without real transactions
38+
2639
## Requirements
2740

2841
**❗ In order to start using Moneroo Flutter you must have the [Flutter SDK][flutter_install_link] installed on your machine.**
2942

43+
- Flutter SDK 2.5.0 or higher
44+
- Dart 2.14.0 or higher
45+
- A Moneroo account and API key (get yours at [moneroo.io](https://moneroo.io))
46+
3047
## Installation
3148

49+
### Via Flutter CLI
50+
3251
Install via `flutter pub add`:
3352

3453
```sh
3554
flutter pub add moneroo_flutter_sdk
3655
```
3756

57+
### Via pubspec.yaml
58+
59+
Alternatively, add the dependency to your `pubspec.yaml` file:
60+
61+
```yaml
62+
dependencies:
63+
moneroo_flutter_sdk: ^0.3.4 # Use the latest version
64+
```
65+
66+
Then run:
67+
68+
```sh
69+
flutter pub get
70+
```
71+
3872
---
3973

4074
### Configuration
@@ -73,7 +107,16 @@ Add this line in your `Info.plist`. This will help you to avoid an ERR_CLEAR_TEX
73107

74108
## Documentation
75109

76-
You can a have a full example [here](example/lib/main.dart). You can also your the `MonerooApi` class to implement the payment yourself without using the Moneroo widget provided by this package.
110+
This README provides basic usage information. For more detailed documentation:
111+
112+
- **Example App**: Check out the complete example [here](example/lib/main.dart)
113+
- **API Reference**: Comprehensive API documentation is available in the code
114+
- **Official Docs**: Visit [docs.moneroo.io](https://docs.moneroo.io/) for the official Moneroo documentation
115+
116+
The SDK offers two main ways to integrate payments:
117+
118+
1. **Using the Moneroo Widget** - A pre-built UI component that handles the entire payment flow
119+
2. **Using the MonerooApi class** - Direct API access for custom implementations
77120

78121
## Example Usage
79122

@@ -170,22 +213,216 @@ class MyHomePage extends StatelessWidget {
170213
- `onPaymentCompleted`: Callback for payment completion
171214
- `onError`: Callback for error handling
172215

216+
## Using the API Wrapper Directly
217+
218+
While the Moneroo widget provides a complete payment flow with UI, you can also use the `MonerooApi` class directly for more customized payment processing. This is useful when you want to implement your own UI or integrate Moneroo payments into an existing flow.
219+
220+
### Initializing the API
221+
222+
```dart
223+
final api = MonerooApi(
224+
apiKey: 'YOUR_API_KEY',
225+
sandbox: false, // Set to true for testing
226+
);
227+
```
228+
229+
### Creating a Payment
230+
231+
```dart
232+
final payment = await api.initPayment(
233+
amount: 5000, // Amount in smallest currency unit (e.g., cents)
234+
customer: MonerooCustomer(
235+
236+
firstName: 'John',
237+
lastName: 'Doe',
238+
phone: '+1234567890', // Optional
239+
country: 'US', // Optional
240+
),
241+
currency: MonerooCurrency.XOF,
242+
description: 'Premium subscription',
243+
callbackUrl: 'https://your-app.com/payment-callback', // Optional
244+
metadata: { 'orderId': '12345' }, // Optional
245+
);
246+
247+
// The checkout URL can be used in a WebView or browser
248+
final checkoutUrl = payment.checkoutUrl;
249+
// Store the payment ID for later verification
250+
final paymentId = payment.id;
251+
```
252+
253+
### Checking Payment Status
254+
255+
```dart
256+
final paymentInfo = await api.getMonerooPaymentInfos(
257+
paymentId: 'payment_123456789',
258+
);
259+
260+
switch (paymentInfo.status) {
261+
case MonerooStatus.success:
262+
print('Payment was successful!');
263+
// Handle successful payment
264+
break;
265+
case MonerooStatus.pending:
266+
print('Payment is still being processed...');
267+
// Maybe show a waiting screen
268+
break;
269+
case MonerooStatus.failed:
270+
print('Payment failed.');
271+
// Handle failed payment
272+
break;
273+
case MonerooStatus.cancelled:
274+
print('Payment was cancelled.');
275+
// Handle cancelled payment
276+
break;
277+
case MonerooStatus.initiated:
278+
print('Payment has been initiated but not yet processed.');
279+
// Maybe redirect to payment page
280+
break;
281+
}
282+
```
283+
284+
### Getting Available Payment Methods
285+
286+
```dart
287+
final methods = await api.getMonerooPaymentMethods();
288+
289+
// Display available payment methods to the user
290+
for (final method in methods) {
291+
print('${method.name}: ${method.description}');
292+
}
293+
```
294+
295+
### Error Handling
296+
297+
```dart
298+
try {
299+
final payment = await api.initPayment(
300+
amount: 5000,
301+
customer: customer,
302+
currency: MonerooCurrency.XOF,
303+
description: 'Premium subscription',
304+
);
305+
// Process payment
306+
} on MonerooException catch (e) {
307+
// Handle Moneroo API errors
308+
print('Error code: ${e.code}');
309+
print('Error message: ${e.message}');
310+
if (e.errors != null) {
311+
print('Detailed errors: ${e.errors}');
312+
}
313+
} on ServiceUnavailableException {
314+
// Handle service unavailable errors (e.g., network issues)
315+
print('Service is currently unavailable. Please try again later.');
316+
} catch (e) {
317+
// Handle other errors
318+
print('An unexpected error occurred: $e');
319+
}
320+
```
321+
173322
## Development
174323

175-
### DEV Mode
324+
## Development Mode
176325

177-
## Notes
326+
### Sandbox Testing
178327

179-
### Exception Handling 🐛
328+
Moneroo provides a sandbox environment for testing your integration without making real transactions. To use the sandbox mode:
180329

181-
- **MonerooException**: This exception is throw when an error occured in during the API calling. You can have more infos about the related error logging the class's attribute.
182-
- **ServiceUnavailableException**: This exception is throw when the SDK was'nt able to send your request to the server. Maybe due to network issues.
330+
```dart
331+
// When using the widget
332+
Moneroo(
333+
apiKey: 'YOUR_API_KEY',
334+
sandbox: true, // Enable sandbox mode
335+
// other parameters...
336+
);
337+
338+
// When using the API directly
339+
final api = MonerooApi(
340+
apiKey: 'YOUR_API_KEY',
341+
sandbox: true, // Enable sandbox mode
342+
);
343+
```
183344

184-
## Security Vulnerabilities
345+
In sandbox mode, you can use test cards and payment methods to simulate different payment scenarios. For more information on testing, visit the [Moneroo Testing Documentation](https://docs.moneroo.io/payments/testing).
346+
347+
## Handling Errors
348+
349+
### Exception Types 🐛
350+
351+
The SDK throws the following exceptions that you should handle in your code:
352+
353+
- **MonerooException**: Thrown when an error occurs during API communication. Contains:
354+
- `code`: HTTP status code or custom error code
355+
- `message`: Human-readable error message
356+
- `errors`: Detailed error information (if available)
357+
358+
- **ServiceUnavailableException**: Thrown when the SDK cannot reach the Moneroo servers, typically due to network issues.
359+
360+
### Best Practices for Error Handling
361+
362+
```dart
363+
try {
364+
// Moneroo API call
365+
} on MonerooException catch (e) {
366+
// Log the error details
367+
print('Moneroo Error: ${e.message} (Code: ${e.code})');
368+
369+
// Show appropriate message to the user
370+
if (e.code == 401) {
371+
// Authentication error
372+
} else if (e.code == 400) {
373+
// Invalid request
374+
}
375+
} on ServiceUnavailableException {
376+
// Handle connectivity issues
377+
print('Cannot connect to Moneroo. Please check your internet connection.');
378+
} catch (e) {
379+
// Handle other unexpected errors
380+
print('Unexpected error: $e');
381+
}
382+
```
185383

384+
## Frequently Asked Questions
385+
386+
### Is the SDK compatible with Flutter Web?
387+
388+
Currently, the SDK is optimized for mobile platforms (Android and iOS). Flutter Web support is planned for future releases.
389+
390+
### How do I handle payment webhooks?
391+
392+
Moneroo can send webhook notifications to your server when payment status changes. Configure your webhook URL in the Moneroo dashboard and implement an endpoint on your server to process these notifications.
393+
394+
### Can I customize the payment UI?
395+
396+
If you need a custom UI, use the `MonerooApi` class directly instead of the pre-built widget. This gives you full control over the payment flow and UI.
397+
398+
## Contributing
399+
400+
Contributions are welcome! If you'd like to contribute to the Moneroo Flutter SDK:
401+
402+
1. Fork the repository
403+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
404+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
405+
4. Push to the branch (`git push origin feature/amazing-feature`)
406+
5. Open a Pull Request
407+
408+
## Security Vulnerabilities
186409

187410
If you discover a security vulnerability within Moneroo Flutter SDK, please send an e-mail to Moneroo Security via [[email protected]](mailto:[email protected]). All security vulnerabilities will be promptly addressed.
188411

412+
## Support
413+
414+
For support, questions, or feedback:
415+
416+
- 📧 Email: [[email protected]](mailto:[email protected])
417+
- 📝 Issues: [GitHub Issues](https://github.com/MonerooHQ/moneroo_flutter/issues)
418+
- 📚 Documentation: [docs.moneroo.io](https://docs.moneroo.io)
419+
189420
## License
190421

191422
The Moneroo Flutter SDK is open-sourced software licensed under the [MIT license](LICENSE.md).
423+
424+
---
425+
426+
<div align="center">
427+
Powered by <a href="https://moneroo.io">Moneroo</a> - The Payment Stack for Africa
428+
</div>

example/ios/Flutter/Debug.xcconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
12
#include "Generated.xcconfig"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
12
#include "Generated.xcconfig"

example/ios/Podfile

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Uncomment this line to define a global platform for your project
2+
# platform :ios, '12.0'
3+
4+
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5+
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6+
7+
project 'Runner', {
8+
'Debug' => :debug,
9+
'Profile' => :release,
10+
'Release' => :release,
11+
}
12+
13+
def flutter_root
14+
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15+
unless File.exist?(generated_xcode_build_settings_path)
16+
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17+
end
18+
19+
File.foreach(generated_xcode_build_settings_path) do |line|
20+
matches = line.match(/FLUTTER_ROOT\=(.*)/)
21+
return matches[1].strip if matches
22+
end
23+
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24+
end
25+
26+
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27+
28+
flutter_ios_podfile_setup
29+
30+
target 'Runner' do
31+
use_frameworks!
32+
33+
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
34+
target 'RunnerTests' do
35+
inherit! :search_paths
36+
end
37+
end
38+
39+
post_install do |installer|
40+
installer.pods_project.targets.each do |target|
41+
flutter_additional_ios_build_settings(target)
42+
end
43+
end
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
12
#include "ephemeral/Flutter-Generated.xcconfig"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
12
#include "ephemeral/Flutter-Generated.xcconfig"

example/macos/Podfile

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
platform :osx, '10.14'
2+
3+
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
4+
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
5+
6+
project 'Runner', {
7+
'Debug' => :debug,
8+
'Profile' => :release,
9+
'Release' => :release,
10+
}
11+
12+
def flutter_root
13+
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
14+
unless File.exist?(generated_xcode_build_settings_path)
15+
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
16+
end
17+
18+
File.foreach(generated_xcode_build_settings_path) do |line|
19+
matches = line.match(/FLUTTER_ROOT\=(.*)/)
20+
return matches[1].strip if matches
21+
end
22+
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
23+
end
24+
25+
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
26+
27+
flutter_macos_podfile_setup
28+
29+
target 'Runner' do
30+
use_frameworks!
31+
32+
flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
33+
target 'RunnerTests' do
34+
inherit! :search_paths
35+
end
36+
end
37+
38+
post_install do |installer|
39+
installer.pods_project.targets.each do |target|
40+
flutter_additional_macos_build_settings(target)
41+
end
42+
end

0 commit comments

Comments
 (0)