Duticotac API Flutter

A Flutter package for integrating Duticotac payment services into your Flutter applications. This package provides a simple and efficient way to handle mobile money payments, transaction management, and offer/product fetching.

Features

  • 💳 Mobile Money Payments - Support for multiple payment providers (Orange Money, MTN, Moov, Wave, Cash)
  • 📊 Transaction Management - Real-time transaction status polling with automatic retry logic
  • 🛍️ Offer Management - Fetch and cache product offers with local storage
  • 🔄 Offline Support - Built-in caching with Hive for offline access
  • 🌐 Network Resilience - Automatic retry for transient network errors
  • 📱 Cross-Platform - Works on both iOS and Android

Installation

Add this package to your pubspec.yaml:

dependencies:
  duticotac_api_flutter:
    git:
      url: https://github.com/freddydrodev/duticotac_api_flutter.git
      ref: main

Or if published to pub.dev:

dependencies:
  duticotac_api_flutter: ^0.0.19

Then run:

flutter pub get

Setup

1. Initialize Hive Adapters

Before using the package, you need to initialize Hive adapters in your app's main function:

import 'package:duticotac_api_flutter/duticotac_api_flutter.dart';
import 'package:hive_ce_flutter/hive_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Initialize Hive
  await Hive.initFlutter();

  // Initialize Duticotac Hive adapters
  await initDuticotacHiveAdapters();

  runApp(MyApp());
}

2. Generate Code (if needed)

If you're modifying models, run the build runner:

flutter packages pub run build_runner clean
flutter packages pub run build_runner build --delete-conflicting-outputs --build-filter="lib/src/models/**/**.dart"

3. Initialize the Duticotac Client

final duticotac = Duticotac(
  apiKey: 'your-api-key-here',
  // baseUrl is optional, defaults to 'https://api.applite.freddydro.dev'
  baseUrl: 'https://api.applite.freddydro.dev',
);

Usage

Mobile Money Payments

Process mobile money payments using various payment providers:

import 'package:duticotac_api_flutter/duticotac_api_flutter.dart';

// Initialize Hive box for local storage (optional but recommended)
final box = await Hive.openBox('duticotac');

// Process a payment
try {
  final response = await duticotac.mobileMoney.cashout(
    amount: 5000.0,
    transactionId: 'unique-transaction-id',
    phone: '+2250123456789',
    name: 'John Doe',
    email: 'john.doe@example.com',
    paymentMethod: PaymentProvider.mtnCI, // or orangeMoneyCI, moovCI, waveCI, cash
    productReference: 'product-ref-123', // or use idFromClient
    // idFromClient: 'client-id-123', // Alternative to productReference
    otp: '123456', // Required for Orange Money CI
    kolaboReference: 'kolabo-partner-code', // Optional: for partner rewards
  );

  if (response.success && response.data != null) {
    print('Payment initiated: ${response.data!.id}');
    print('Status: ${response.data!.status}');
  }
} catch (e) {
  print('Payment error: $e');
}

Supported Payment Providers

  • PaymentProvider.mtnCI - MTN Mobile Money (Côte d'Ivoire)
  • PaymentProvider.orangeMoneyCI - Orange Money (Côte d'Ivoire) - Requires OTP
  • PaymentProvider.moovCI - Moov Money (Côte d'Ivoire)
  • PaymentProvider.waveCI - Wave Money (Côte d'Ivoire)
  • PaymentProvider.cash - Cash payment
  • PaymentProvider.creditCard - Credit card (coming soon)
  • PaymentProvider.iap - In-App Purchase (coming soon)

Transaction Status

Get Transaction Status by ID

try {
  final response = await duticotac.transaction.getStatusById(
    id: 'transaction-id-here',
  );

  if (response.success && response.data != null) {
    final transaction = response.data!;
    print('Transaction ID: ${transaction.id}');
    print('Status: ${transaction.status}');
    print('Amount: ${transaction.amount}');
  }
} catch (e) {
  print('Error: $e');
}

The getStatus method automatically polls the transaction status until it's confirmed, cancelled, or failed:

try {
  final response = await duticotac.transaction.getStatus(
    'transaction-id-here',
    intervalMin: Duration(seconds: 2), // Minimum polling interval
    timeout: Duration(seconds: 90),    // Maximum polling duration
  );

  if (response.success && response.data != null) {
    final transaction = response.data!;

    switch (transaction.status) {
      case TransactionStatus.confirmed:
        print('✅ Payment confirmed!');
        break;
      case TransactionStatus.cancelled:
        print('❌ Payment cancelled');
        break;
      case TransactionStatus.failed:
        print('❌ Payment failed');
        break;
      case TransactionStatus.pending:
        print('⏳ Payment pending');
        break;
    }
  } else {
    print('Error: ${response.error}');
  }
} catch (e) {
  print('Error: $e');
}

Features:

  • Automatic retry on network errors
  • Connectivity checking before retries
  • Exponential backoff strategy
  • Handles DNS issues after app resume

Offer Management

Fetch and cache product offers:

import 'package:hive_ce/hive.dart';

// Open a Hive box for caching
final box = await Hive.openBox('duticotac');

try {
  final offer = await duticotac.offer.get(
    reference: 'product-reference-here',
    localDB: box,
  );

  print('Offer Name: ${offer.name}');
  print('Price: ${offer.price}');
  print('Description: ${offer.description}');
} catch (e) {
  print('Error fetching offer: $e');
}

The offer is automatically cached locally and refreshed in the background on subsequent calls.

Models

TransactionModel

class TransactionModel {
  final String id;
  final double amount;
  final TransactionStatus status;
  final PaymentProvider paymentMethod;
  final Currency currency;
  final DateTime? createdAt;
  final DateTime? updatedAt;
  // ... other fields
}

TransactionStatus Enum

  • TransactionStatus.pending - Payment is pending
  • TransactionStatus.confirmed - Payment confirmed
  • TransactionStatus.cancelled - Payment cancelled
  • TransactionStatus.failed - Payment failed

PaymentProvider Enum

See Supported Payment Providers section above.

Error Handling

The package throws string errors that you can catch and handle:

try {
  await duticotac.mobileMoney.cashout(...);
} catch (e) {
  if (e == 'otp-required') {
    // Handle OTP requirement for Orange Money
  } else if (e == 'ref-or-idFromClient-required') {
    // Handle missing reference
  } else if (e == 'payment-cancelled') {
    // Handle cancelled payment
  } else if (e == 'payment-failed') {
    // Handle failed payment
  } else if (e == 'polling-timeout') {
    // Handle polling timeout
  } else {
    // Handle other errors
    print('Unknown error: $e');
  }
}

Dependencies

This package requires the following dependencies:

  • dio: ^5.8.0+1 - HTTP client
  • hive_ce: ^2.11.3 - Local storage
  • hive_ce_flutter: ^2.3.1 - Flutter integration for Hive
  • connectivity_plus: ^6.1.2 - Network connectivity checking

Troubleshooting

Build Runner Issues

If you encounter issues with generated files, try:

flutter packages pub run build_runner clean
flutter packages pub run build_runner build --delete-conflicting-outputs --build-filter="lib/src/models/**/**.dart"

In-App Purchase Plugin Issues

If you have issues with the in-app purchase plugin, try:

rm -r ~/.pub-cache/hosted/pub.dev/in_app_purchase_storekit-0.4.0
flutter pub get

Roadmap

  • IAP (In-App Purchase) Testing
  • Credit Card Implementation
  • Enhanced IAP Response Handling
  • Duticotac Core API Integration

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

See LICENSE file for details.

Support