Gestion d'Envoi de SMS à Grande Échelle : Retour d'Expérience
Le Contexte
J'ai récemment développé une plateforme SaaS pour BAAF GROUP en Guinée, un acteur du secteur FinTech. La plateforme permet la gestion de points de vente, d'agents et le traitement de milliers de transactions quotidiennes.
Le Défi
Avec plusieurs milliers de transactions par jour, le système doit envoyer automatiquement des SMS pour :
- Confirmer les paiements de factures
- Notifier les agents des transactions
- Envoyer les reçus aux clients
- etc ....
Le volume d'envoi peut atteindre plusieurs milliers de SMS par jour, nécessitant une solution robuste et flexible.
La Solution Technique
Architecture Multi-Provider
Pour éviter la dépendance à un seul fournisseur et assurer la continuité de service, j'ai implémenté une abstraction simple :
<?php
namespace App\Enums;
enum SmsProvider: string
{
case ORANGE = 'orange';
case NIMBA = 'nimba';
public static function getCurrent(): self
{
return self::from(env('SMS_PROVIDER', 'orange'));
}
}
<?php
namespace App\Helpers;
use App\Enums\SmsProvider;
use Tmoh\NimbaSms\Facades\NimbaSms;
use Tmoh\OrangeSmsPackage\Facades\OrangeSms;
class SmsProviderHelper
{
public static function sendSms(string $phoneNumber, string $message): mixed
{
return match (SmsProvider::getCurrent()) {
SmsProvider::ORANGE => OrangeSms::sendSms(
recipientAddress: $phoneNumber,
message: $message
),
SmsProvider::NIMBA => NimbaSms::sendSms($phoneNumber, $message),
};
}
}
Traitement Asynchrone avec Jobs
Pour gérer le volume d'envois sans impacter les performances, j'utilise les queues Laravel :
<?php
namespace App\Jobs;
use App\Helpers\SmsProviderHelper;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class SendTransactionSmsJob implements ShouldQueue
{
use Dispatchable, Queueable;
public $tries = 3;
public function __construct(
public string $phoneNumber,
public string $message
) {}
public function handle(): void
{
SmsProviderHelper::sendSms(
phoneNumber: $this->phoneNumber,
message: $this->message
);
}
}
Utilisation
// Lors d'un paiement de facture
SendTransactionSmsJob::dispatch(
phoneNumber: $customer->phone,
message: "Paiement de {$amount} GNF effectué. Référence: {$ref}"
);
// Pour les agents
SendTransactionSmsJob::dispatch(
phoneNumber: $agent->phone,
message: "Transaction validée. Commission: {$commission} GNF"
);
// En cas d'activité suspecte
SendTransactionSmsJob::dispatch(
phoneNumber: $user->phone,
message: "Alerte sécurité: Tentative de connexion depuis un nouvel appareil. Si ce n'est pas vous, contactez-nous immédiatement."
);
Les Avantages
✅ Flexibilité : Changement de provider SMS via une simple variable d'environnement
✅ Performance : Traitement asynchrone sans ralentir l'application
✅ Fiabilité : Système de retry automatique en cas d'échec
✅ Scalabilité : Capable de gérer plusieurs milliers d'envois par jour
Stack Technique
- Laravel (Redis et Horizon)
- Packages utilisés :
Installation
# Installer les packages SMS
composer require tmoh/orange-sms-package
composer require tmoh/nimba-sms
# Installer Horizon pour le monitoring
composer require laravel/horizon
Configuration
# Provider SMS actif
SMS_PROVIDER=orange
# Configuration Orange SMS
ORANGE_SMS_CLIENT_ID=your_client_id
ORANGE_SMS_CLIENT_SECRET=your_client_secret
# Configuration Nimba SMS
NIMBA_SMS_API_KEY=your_api_key
# Configuration Redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
Résultat
Le système traite actuellement plusieurs milliers de SMS par jour de manière stable et fiable pour BAAF GROUP, avec :
Un taux de succès supérieur à 99% Un temps de traitement moyen inférieur à 2 secondes Zéro interruption de service depuis le déploiement Capacité à gérer des pics de **20,000+ SMS/Jour **
Projet développé pour BAAF GROUP - Guinée