laravel-mobile-money maintained by mmchrist89
Laravel Mobile Money Package
Package Laravel complet pour l'intégration de MTN Mobile Money et Airtel Money. Solution flexible et prête pour la production.
🚀 Fonctionnalités
- ✅ Support de MTN Mobile Money et Airtel Money
- ✅ Demandes de paiement (Collection)
- ✅ Transferts d'argent (Disbursement)
- ✅ Vérification du statut des transactions
- ✅ Consultation du solde
- ✅ Détection automatique du provider
- ✅ Gestion des webhooks/callbacks
- ✅ Enregistrement des transactions en base de données
- ✅ Logging complet
- ✅ Configuration flexible
- ✅ Gestion des erreurs robuste
📦 Installation
Étape 1 : Installation via Composer
composer require mmchrist89/laravel-mobile-money
Étape 2 : Publier la configuration
php artisan vendor:publish --tag=mobile-money-config
Étape 3 : Publier les migrations
php artisan vendor:publish --tag=mobile-money-migrations
Étape 4 : Exécuter les migrations
php artisan migrate
⚙️ Configuration
Ajoutez vos identifiants dans le fichier .env :
MTN Mobile Money
MTN_ENABLED=true
MTN_ENVIRONMENT=sandbox
MTN_CURRENCY=XAF
MTN_COUNTRY=CM
MTN_API_USER=your-api-user
MTN_API_KEY=your-api-key
MTN_SUBSCRIPTION_KEY=your-subscription-key
MTN_COLLECTION_SUBSCRIPTION_KEY=your-collection-key
MTN_DISBURSEMENT_SUBSCRIPTION_KEY=your-disbursement-key
MTN_BASE_URL=https://sandbox.momodeveloper.mtn.com
MTN_CALLBACK_URL=https://votre-domaine.com/mobile-money/webhooks/mtn
Airtel Money
AIRTEL_ENABLED=true
AIRTEL_ENVIRONMENT=staging
AIRTEL_CURRENCY=XAF
AIRTEL_COUNTRY=CM
AIRTEL_CLIENT_ID=your-client-id
AIRTEL_CLIENT_SECRET=your-client-secret
AIRTEL_PIN=your-pin
AIRTEL_BASE_URL=https://openapiuat.airtel.africa
AIRTEL_CALLBACK_URL=https://votre-domaine.com/mobile-money/webhooks/airtel
Configuration générale
MOBILE_MONEY_DEFAULT_PROVIDER=mtn
MOBILE_MONEY_LOGGING=true
MOBILE_MONEY_LOG_CHANNEL=stack
📖 Utilisation
Utilisation de base
use MobileMoney\Facades\MobileMoney;
// Demander un paiement
$transaction = MobileMoney::requestPayment(
phone: '237650123456',
amount: 5000,
options: [
'provider' => 'mtn', // optionnel
'reference' => 'CMD-12345', // optionnel, généré automatiquement
'metadata' => [
'customer_name' => 'John Doe',
'order_id' => 12345,
]
]
);
// Vérifier le statut
$transaction = MobileMoney::checkStatus($transaction->transaction_id);
// Effectuer un transfert
$transaction = MobileMoney::transfer(
phone: '237690123456',
amount: 2000,
options: ['provider' => 'airtel']
);
// Obtenir le solde
$balance = MobileMoney::getBalance('mtn');
Détection automatique du provider
// Le package détecte automatiquement MTN ou Airtel
$transaction = MobileMoney::smartPayment(
phone: '237650123456', // MTN sera détecté
amount: 5000
);
Utilisation avec provider spécifique
// Utiliser directement un provider
$result = MobileMoney::provider('mtn')->requestPayment(
phone: '237650123456',
amount: 5000,
reference: 'CMD-12345'
);
// Vérifier les providers disponibles
$providers = MobileMoney::availableProviders();
// ['mtn', 'airtel']
Gestion des transactions en base de données
use MobileMoney\Models\Transaction;
// Récupérer toutes les transactions
$transactions = Transaction::all();
// Filtrer par provider
$mtnTransactions = Transaction::provider('mtn')->get();
// Filtrer par statut
$successfulTransactions = Transaction::successful()->get();
$pendingTransactions = Transaction::pending()->get();
$failedTransactions = Transaction::failed()->get();
// Vérifier le statut
if ($transaction->isSuccessful()) {
// Transaction réussie
}
if ($transaction->isPending()) {
// Transaction en attente
}
if ($transaction->isFailed()) {
// Transaction échouée
}
// Marquer manuellement une transaction
$transaction->markAsSuccessful();
$transaction->markAsFailed('Solde insuffisant');
Gestion des erreurs
use MobileMoney\Exceptions\MobileMoneyException;
try {
$transaction = MobileMoney::requestPayment('237650123456', 5000);
} catch (MobileMoneyException $e) {
// Gérer l'erreur
Log::error('Erreur Mobile Money: ' . $e->getMessage());
// Obtenir le contexte
$context = $e->getContext();
}
🔔 Webhooks/Callbacks
Le package enregistre automatiquement les routes de webhook :
- MTN :
POST /mobile-money/webhooks/mtn - Airtel :
POST /mobile-money/webhooks/airtel
Les transactions sont automatiquement mises à jour lors de la réception des callbacks.
Personnaliser le traitement des callbacks
Vous pouvez écouter les événements de transaction (à implémenter selon vos besoins) :
// Dans EventServiceProvider
protected $listen = [
'MobileMoney\Events\TransactionUpdated' => [
'App\Listeners\SendTransactionNotification',
],
];
🧪 Tests
composer test
📝 Exemples d'utilisation
Cas d'usage 1 : Système de paiement e-commerce
class PaymentController extends Controller
{
public function processPayment(Request $request)
{
$validated = $request->validate([
'phone' => 'required|string',
'amount' => 'required|numeric|min:100',
'order_id' => 'required|integer',
]);
try {
$transaction = MobileMoney::smartPayment(
phone: $validated['phone'],
amount: $validated['amount'],
options: [
'reference' => 'ORDER-' . $validated['order_id'],
'metadata' => [
'order_id' => $validated['order_id'],
'customer_id' => auth()->id(),
],
]
);
return response()->json([
'success' => true,
'transaction_id' => $transaction->transaction_id,
'message' => 'Veuillez confirmer le paiement sur votre téléphone',
]);
} catch (MobileMoneyException $e) {
return response()->json([
'success' => false,
'message' => $e->getMessage(),
], 400);
}
}
public function checkPaymentStatus($transactionId)
{
$transaction = MobileMoney::checkStatus($transactionId);
return response()->json([
'status' => $transaction->status,
'amount' => $transaction->amount,
]);
}
}
Cas d'usage 2 : Système de retrait
class WithdrawalController extends Controller
{
public function withdraw(Request $request)
{
$validated = $request->validate([
'phone' => 'required|string',
'amount' => 'required|numeric|min:500',
]);
// Vérifier le solde utilisateur
if (auth()->user()->balance < $validated['amount']) {
return response()->json([
'success' => false,
'message' => 'Solde insuffisant',
], 400);
}
try {
$transaction = MobileMoney::transfer(
phone: $validated['phone'],
amount: $validated['amount'],
options: [
'provider' => MobileMoney::detectProvider($validated['phone']),
'metadata' => [
'user_id' => auth()->id(),
'type' => 'withdrawal',
],
]
);
// Déduire du solde utilisateur
auth()->user()->decrement('balance', $validated['amount']);
return response()->json([
'success' => true,
'transaction_id' => $transaction->transaction_id,
'message' => 'Retrait initié avec succès',
]);
} catch (MobileMoneyException $e) {
return response()->json([
'success' => false,
'message' => $e->getMessage(),
], 400);
}
}
}
Cas d'usage 3 : Commande artisan pour vérifier les transactions en attente
namespace App\Console\Commands;
use Illuminate\Console\Command;
use MobileMoney\Facades\MobileMoney;
use MobileMoney\Models\Transaction;
class CheckPendingTransactions extends Command
{
protected $signature = 'mobile-money:check-pending';
protected $description = 'Vérifier le statut des transactions en attente';
public function handle()
{
$pendingTransactions = Transaction::pending()
->where('created_at', '>', now()->subHours(24))
->get();
$this->info("Vérification de {$pendingTransactions->count()} transactions...");
foreach ($pendingTransactions as $transaction) {
try {
$updated = MobileMoney::checkStatus(
$transaction->transaction_id,
$transaction->provider
);
$this->info("Transaction {$transaction->transaction_id}: {$updated->status}");
} catch (\Exception $e) {
$this->error("Erreur pour {$transaction->transaction_id}: {$e->getMessage()}");
}
}
$this->info('Terminé !');
}
}
🛠️ Configuration avancée
Personnaliser la table des transactions
Dans config/mobile-money.php :
'database' => [
'transactions_table' => 'custom_transactions_table',
'connection' => 'custom_connection',
],
Désactiver un provider
MTN_ENABLED=false
Configuration multi-pays
Le package supporte plusieurs pays. Modifiez simplement :
MTN_COUNTRY=UG # Ouganda
AIRTEL_COUNTRY=GH # Ghana
📚 API Reference
MobileMoneyManager
requestPayment(string $phone, float $amount, array $options = []): Transaction
Demander un paiement au client.
transfer(string $phone, float $amount, array $options = []): Transaction
Effectuer un transfert vers un numéro.
checkStatus(string $transactionId, ?string $provider = null): Transaction
Vérifier le statut d'une transaction.
getBalance(?string $provider = null): array
Obtenir le solde du compte.
detectProvider(string $phone): ?string
Détecter le provider à partir du numéro.
smartPayment(string $phone, float $amount, array $options = []): Transaction
Paiement avec détection automatique du provider.
availableProviders(): array
Obtenir la liste des providers disponibles.
🔒 Sécurité
- Les données sensibles sont automatiquement masquées dans les logs
- Support HTTPS pour la production
- Validation des numéros de téléphone
- Gestion sécurisée des tokens d'accès
🤝 Contribution
Les contributions sont les bienvenues ! N'hésitez pas à ouvrir une issue ou une pull request.
📄 Licence
Ce package est open-source sous licence MIT.
👨💻 Auteur
Créé avec ❤️ pour la communauté Laravel