Orange Money vs MTN MoMo Sénégal : Le comparatif complet pour les entreprises
Au Sénégal, le marché des paiements mobiles est dominé par deux acteurs majeurs : Orange Money et MTN Mobile Money. Pour une entreprise ou une fintech qui souhaite intégrer des paiements mobiles, choisir entre ces deux PSP (Payment Service Providers) a un impact direct sur l'expérience utilisateur et les coûts d'exploitation.
Ce comparatif technique détaille les différences entre Orange Money et MTN MoMo au Sénégal, avec des données concrètes sur les tarifs, les APIs, et les processus d'intégration.
C'est quoi Orange Money et MTN MoMo au Sénégal ?
Orange Money est le service de Mobile Money d'Orange Sénégal, lancé en 2010. C'est le leader historique du marché avec environ 42% de parts de marché. Les utilisateurs Orange Money sont identifiés par les préfixes +221 77 et 78. MTN Mobile Money (MTN MoMo) est le service de paiement mobile de MTN Sénégal, lancé en 2017. Il représente environ 15% du marché du mobile money sénégalais et cible les utilisateurs des préfixes +221 76 (MTN).Les deux services sont régulés par l'ARS (Autorité de Régulation des Télécommunications et des Postes) du Sénégal et opèrent sous agrément de la Direction de la Monnaie et du Crédit (DMC) conformément à la réglementation UEMOA sur les services de paiement.
Quelles sont les différences de tarifs entre Orange Money et MTN MoMo ?
Les structures tarifaires diffèrent significativement entre les deux opérateurs. Voici les tarifs applicables aux entreprises pour les paiements marchands (merchant payments) :
Frais de transaction (B2C)
| Type de transaction | Orange Money | MTN MoMo |
|---|---|---|
| Paiement marchand (0-10 000 FCFA) | 1.5% (min 50 FCFA) | 1.2% (min 40 FCFA) |
| Paiement marchand (10 000-50 000 FCFA) | 1.2% | 1.0% |
| Paiement marchand (50 000+ FCFA) | 1.0% (max 2 500 FCFA) | 0.8% (max 2 000 FCFA) |
| Remboursement (refund) | 1.0% | 0.8% |
Frais de retrait (cash-out)
Pour les entreprises qui permettent aux clients de retirer des fonds :
| Type | Orange Money | MTN MoMo |
|---|---|---|
| Retrait vers agent | 2% | 1.8% |
| Retrait en compte bancaire | 1.5% | 1.2% |
Frais d'intégration et mensuels
| Frais | Orange Money | MTN MoMo |
|---|---|---|
| Frais de setup | 150 000 FCFA | 100 000 FCFA |
| Abonnement mensuel | 25 000 FCFA | 20 000 FCFA |
| Maintenance API | Inclus | Inclus |
Comment intégrer l'API Orange Money Sénégal ?
L'intégration d'Orange Money Sénégal nécessite de passer par Orange Developer Portal et d'obtenir des credentials d'API.
Prérequis
- Compte entreprise Orange Money validé
- Contrat de services de paiement marchand signé
- Certificat SSL pour les webhooks
- Environnement de production conforme aux exigences de sécurité
Processus d'intégration
Étape 1 : Inscription sur Orange Developer PortalCréez un compte sur developer.orange.com et sélectionnez l'API "Orange Money API Sénégal".
Étape 2 : Configuration de l'applicationCréez une application avec les scopes suivants :
orange_money:payment_initiationorange_money:payment_statusorange_money:refund
Vous recevrez un client_id et un client_secret.
L'API utilise OAuth 2.0. Voici un exemple de requête pour obtenir un token :
async function getOrangeToken(): Promise<string> {
const response = await fetch('https://api.orange.com/oauth/v3/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': Basic ${Buffer.from(${clientId}:${clientSecret}).toString('base64')}
},
body: 'grant_type=client_credentials'
});
const data = await response.json();
return data.access_token;
}
interface OrangePaymentRequest {
amount: string;
currency: 'XOF';
merchant_key: string;
order_id: string;
callback_url: string;
customer_phone: string;
}
async function initiateOrangePayment(
token: string,
payment: OrangePaymentRequest
): Promise<{ payment_url: string; transaction_id: string }> {
const response = await fetch('https://api.orange.com/orange-money-webpay/senegal/v1/webpay', {
method: 'POST',
headers: {
'Authorization': Bearer ${token},
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: payment.amount,
currency: payment.currency,
merchant_key: payment.merchant_key,
order_id: payment.order_id,
callback_url: payment.callback_url,
customer_phone: payment.customer_phone,
return_url: ${payment.callback_url}/return,
cancel_url: ${payment.callback_url}/cancel
})
});
if (!response.ok) {
throw new Error(Orange Money API error: ${response.status});
}
const data = await response.json();
return {
payment_url: data.payment_url,
transaction_id: data.transaction_id
};
}
Orange envoie une notification POST à votre callback_url lors du paiement :
interface OrangeWebhookPayload {
transaction_id: string;
order_id: string;
status: 'SUCCESS' | 'FAILED' | 'PENDING';
amount: string;
currency: string;
payment_method: 'ORANGE_MONEY';
timestamp: string;
}
async function handleOrangeWebhook(req: Request, res: Response) {
const payload = await req.json() as OrangeWebhookPayload;
// Vérifier la signature HMAC-SHA256
const signature = req.headers['x-orange-signature'];
const expectedSignature = crypto
.createHmac('sha256', process.env.ORANGE_WEBHOOK_SECRET)
.update(JSON.stringify(payload))
.digest('base64');
if (signature !== expectedSignature) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Traiter le paiement
if (payload.status === 'SUCCESS') {
await updateOrderStatus(payload.order_id, 'PAID');
}
res.status(200).json({ received: true });
}
Limites et contraintes
- Délai de validité du token : 3600 secondes (1 heure)
- Montant minimum : 100 FCFA
- Montant maximum : 1 000 000 FCFA par transaction
- Taux limite : 100 requêtes/minute par IP
Comment intégrer l'API MTN MoMo Sénégal ?
L'intégration de MTN Mobile Money Sénégal passe par le MTN Developer Portal avec une architecture basée sur les collections d'API.
Prérequis
- Compte marchand MTN MoMo actif
- Compte sur developer.mtn.com
- Clés API (API Key, API User, Subscription Key)
- Certificat de callback whiteliste par MTN
Processus d'intégration
Étape 1 : Création de compte développeurInscrivez-vous sur MTN Developer Portal et créez une application pour l'environnement "Sénégal".
Étape 2 : Obtenir les credentialsVous recevrez :
Ocp-Apim-Subscription-Key(clé primaire)X-Reference-Id(identifiant d'API)API UseretAPI Key(pour l'authentification)
MTN utilise une authentification basique avec API User/API Key :
interface MTNAuthResponse {
access_token: string;
token_type: string;
expires_in: number;
}
async function getMTNToken(): Promise<string> {
const authString = Buffer.from(${apiUser}:${apiKey}).toString('base64');
const response = await fetch('https://sandbox.momodeveloper.mtn.com/collection/token/', {
method: 'POST',
headers: {
'Authorization': Basic ${authString},
'Ocp-Apim-Subscription-Key': subscriptionKey
}
});
const data = await response.json() as MTNAuthResponse;
return data.access_token;
}
interface MTNPaymentRequest {
amount: string;
currency: 'XOF';
external_id: string;
payer_phone: string;
payer_message: string;
payee_note: string;
}
async function requestMTNPayment(
token: string,
payment: MTNPaymentRequest
): Promise<{ reference_id: string; financial_transaction_id: string }> {
const response = await fetch('https://momodeveloper.mtn.com/collection/v1_0/requesttopay', {
method: 'POST',
headers: {
'Authorization': Bearer ${token},
'X-Reference-Id': generateUUID(),
'X-Target-Environment': 'senegal',
'Ocp-Apim-Subscription-Key': subscriptionKey,
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: payment.amount,
currency: payment.currency,
externalId: payment.external_id,
payer: {
partyIdType: 'MSISDN',
partyId: payment.payer_phone
},
payerMessage: payment.payer_message,
payeeNote: payment.payee_note
})
});
if (!response.ok) {
const error = await response.text();
throw new Error(MTN MoMo API error: ${error});
}
const referenceId = response.headers.get('X-Reference-Id');
const statusResponse = await fetch(
https://momodeveloper.mtn.com/collection/v1_0/requesttopay/${referenceId},
{
headers: {
'Authorization': Bearer ${token},
'X-Target-Environment': 'senegal',
'Ocp-Apim-Subscription-Key': subscriptionKey
}
}
);
const statusData = await statusResponse.json();
return {
reference_id: referenceId!,
financial_transaction_id: statusData.financialTransactionId
};
}
type PaymentStatus = 'PENDING' | 'SUCCESSFUL' | 'FAILED' | 'TIMED_OUT';
async function getMTNPaymentStatus(
token: string,
referenceId: string
): Promise<{ status: PaymentStatus; amount?: string }> {
const response = await fetch(
https://momodeveloper.mtn.com/collection/v1_0/requesttopay/${referenceId},
{
headers: {
'Authorization': Bearer ${token},
'X-Target-Environment': 'senegal',
'Ocp-Apim-Subscription-Key': subscriptionKey
}
}
);
const data = await response.json();
return {
status: data.status as PaymentStatus,
amount: data.amount
};
}
Limites et contraintes
- Durée de validité du token : 1800 secondes (30 minutes)
- Montant minimum : 100 FCFA
- Montant maximum : 500 000 FCFA par transaction
- Timeout du paiement : Le client a 15 minutes pour valider le USSD
- Taux limite : 50 requêtes/seconde par subscription
Quel est le délai de crédit mobile money au Sénégal ?
Le délai de crédit — le temps entre la validation du paiement par le client et la disponibilité effective des fonds sur le compte marchand — varie selon l'opérateur et le type de transaction.
Délais moyens de crédit
| Opérateur | Paiement direct | Paiement via API | Retrait espèces |
|---|---|---|---|
| Orange Money | Immédiat | 2-5 secondes | Immédiat (agent) |
| MTN MoMo | Immédiat | 3-7 secondes | Immédiat (agent) |
Facteurs influençant le délai de crédit
- Type de validation : USSD (immédiat) vs API (2-7 secondes)
- Volume de transactions : Pics de charge peuvent ajouter 1-3 secondes
- Connexion réseau : Latence entre le client, l'opérateur et vos serveurs
- Rapprochement bancaire : Pour les virements vers compte bancaire, comptez 24-48h ouvrées
Bonnes pratiques pour gérer les délais
// Configuration des timeouts par opérateur
const PSP_TIMEOUTS = {
ORANGE_MONEY: {
payment_validation: 30000, // 30s max pour validation client
webhook_delay: 5000, // Premier webhook attendu après ~5s
max_waiting_time: 120000 // 2min max avant considérer comme timeout
},
MTN_MOMO: {
payment_validation: 900000, // 15min pour validation USSD
webhook_delay: 7000, // Premier webhook après ~7s
max_waiting_time: 960000 // 16min max avant timeout
}
};
async function waitForPaymentConfirmation(
psp: 'ORANGE_MONEY' | 'MTN_MOMO',
transactionId: string
): Promise<PaymentStatus> {
const timeout = PSP_TIMEOUTS[psp].max_waiting_time;
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
const status = await checkTransactionStatus(psp, transactionId);
if (status === 'SUCCESS') return 'SUCCESS';
if (status === 'FAILED') return 'FAILED';
// Attendre avant prochaine vérification
await new Promise(resolve => setTimeout(resolve, 2000));
}
return 'TIMEOUT';
}
Quels sont les limites de transaction par opérateur ?
Les plafonds de transaction sont réglementés par l'ARS Sénégal et varient selon le niveau de KYC du client et le type de compte marchand.
Limites pour les comptes marchands
| Type de limite | Orange Money | MTN MoMo |
|---|---|---|
| Maximum par transaction | 1 000 000 FCFA | 500 000 FCFA |
| Maximum journalier | 5 000 000 FCFA | 2 000 000 FCFA |
| Maximum mensuel | 20 000 000 FCFA | 10 000 000 FCFA |
| Maximum cumulé (solde) | 3 000 000 FCFA | 1 500 000 FCFA |
Limites pour les clients (selon niveau KYC)
| Niveau KYC | Orange Money | MTN MoMo |
|---|---|---|
| Base (téléphone seulement) | 100 000 FCFA/jour | 50 000 FCFA/jour |
| Standard (CNIE requis) | 500 000 FCFA/jour | 300 000 FCFA/jour |
| Étendu (justificatif domicile) | 1 000 000 FCFA/jour | 500 000 FCFA/jour |
Impact sur l'intégration
Ces limites ont des implications directes pour votre architecture de paiement :
interface TransactionLimits {
min_amount: number;
max_amount: number;
daily_max: number;
}
const PSP_LIMITS: Record<string, TransactionLimits> = {
ORANGE_MONEY: {
min_amount: 100,
max_amount: 1000000,
daily_max: 5000000
},
MTN_MOMO: {
min_amount: 100,
max_amount: 500000,
daily_max: 2000000
}
};
function selectPSPForAmount(
amount: number,
customerPSPPreference?: string
): string {
// Vérifier si le montant dépasse les limites du PSP préféré
if (customerPSPPreference) {
const limits = PSP_LIMITS[customerPSPPreference];
if (amount <= limits.max_amount) {
return customerPSPPreference;
}
}
// Sinon, router vers le PSP avec la limite la plus élevée
if (amount > PSP_LIMITS.MTN_MOMO.max_amount) {
return 'ORANGE_MONEY';
}
// Pour les montants compatibles avec les deux, choisir le moins cher
return amount > 50000 ? 'MTN_MOMO' : 'ORANGE_MONEY';
}
Pourquoi utiliser un orchestrateur comme Simiz au Sénégal ?
Intégrer Orange Money et MTN MoMo directement demande de maintenir deux intégrations séparées, gérer deux contrats, et composer avec la fragmentation des paiements. Simiz résout cette complexité.
Architecture non-custodiale
Simiz agit comme une couche d'orchestration sans jamais détenir les fonds. Chaque transaction est routée en temps réel vers le PSP approprié :
Client → Simiz API → [Orange Money | MTN MoMo] → Client
↓
Votre webhook
Cette architecture garantit que :
- Les fonds ne transitent jamais par Simiz : Ils vont directement du client au marchand via le PSP
- La conformité est simplifiée : Simiz ne nécessite pas de licence de paiement
- La transparence est totale : Vous conservez la relation directe avec chaque PSP
Avantages opérationnels
| Aspect | Intégration directe | Avec Simiz |
|---|---|---|
| Contrats à signer | 2 (Orange + MTN) | 1 (Simiz) |
| Intégrations techniques | 2 APIs différentes | 1 API unifiée |
| Settlement (rapprochement) | 2 relevés séparés | 1 rapport consolidé |
| Support technique | 2 canaux distincts | 1 point de contact |
| Routing intelligent | Manuel (développement sur mesure) | Automatique (règles configurables) |
Routing intelligent
Simiz route automatiquement chaque transaction vers le PSP optimal :
// Exemple de règles de routing configurables dans Simiz
interface RoutingRule {
condition: (context: PaymentContext) => boolean;
psp: 'ORANGE_MONEY' | 'MTN_MOMO';
priority: number;
}
const SIMIZ_ROUTING_RULES: RoutingRule[] = [
{
// Préférence explicite du client
condition: (ctx) => ctx.customerPreference !== null,
psp: 'CUSTOMER_PREFERENCE',
priority: 1
},
{
// Montants > 500K FCFA → Orange (limite plus élevée)
condition: (ctx) => ctx.amount > 500000,
psp: 'ORANGE_MONEY',
priority: 2
},
{
// Optimisation tarifaire → MTN pour 50K-500K
condition: (ctx) => ctx.amount >= 50000 && ctx.amount <= 500000,
psp: 'MTN_MOMO',
priority: 3
},
{
// Fallback sur disponibilité
condition: () => true,
psp: 'LEAST_LOADED',
priority: 4
}
];
API unifiée Simiz
Une seule API pour tous les PSPs sénégalais :
// Une seule interface pour tous les PSPs Sénégal
async function initiatePayment(params: {
amount: number;
currency: 'XOF';
customer_phone: string;
customer_email?: string;
order_id: string;
}): Promise<{
transaction_id: string;
status: 'PENDING' | 'SUCCESS';
payment_url?: string;
}> {
const response = await fetch('https://api.simiz.io/v1/payments/initiate', {
method: 'POST',
headers: {
'Authorization': Bearer ${SIMIZ_API_KEY},
'Content-Type': 'application/json'
},
body: JSON.stringify({
...params,
country: 'SN',
allowed_psps: ['ORANGE_MONEY', 'MTN_MOMO'],
success_url: 'https://votre-site.com/payment/success',
cancel_url: 'https://votre-site.com/payment/cancel',
webhook_url: 'https://votre-site.com/webhooks/simiz'
})
});
return response.json();
}
Découvrez la tarification Simiz pour le Sénégal et comparez avec une intégration directe.
Tableau de comparaison finale
| Critère | Orange Money | MTN MoMo | Avec Simiz |
|---|---|---|---|
| Parts de marché Sénégal | 42% | 15% | Multi-PSP |
| Frais moyens (0-50K) | 1.35% | 1.1% | Optimisé |
| Max par transaction | 1M FCFA | 500K FCFA | 1M FCFA |
| API documentation | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Temps d'intégration | 3-4 semaines | 2-3 semaines | 2-3 jours |
| Maintenance continue | Oui (2 PSP) | Oui (2 PSP) | Non (géré) |
FAQ
Est-ce qu'un client MTN peut payer avec Orange Money ?
Non. Un client MTN (préfixe 76) doit utiliser un compte MTN MoMo pour payer. Un client Orange (préfixes 77, 78) doit utiliser Orange Money. C'est pourquoi les entreprises sénégalaises ont intérêt à offrir les deux options, ou à utiliser un orchestrateur comme Simiz qui propose automatiquement le bon PSP selon le numéro de téléphone du client.
Quels sont les délais de remboursement (refund) ?
Pour un remboursement vers le client : Orange Money traite les refunds en 24-48h ouvrées, MTN MoMo en 12-24h ouvrées. Les deux opérateurs limitent les refunds à 7 jours après la transaction initiale, sauf accord commercial spécifique.
Simiz est-il agréé par l'ARS Sénégal ?
Simiz n'est pas un PSP et ne nécessite pas d'agrément. L'orchestrateur agit comme une couche technique qui route les transactions vers les PSP agréés (Orange Money, MTN MoMo, Wave, Proximo). Chaque PSP partenaire est licencié et régulé par l'ARS et la DMC.
Comment gérer les webhooks lorsque les deux PSP sont utilisés ?
Avec une intégration directe, vous devez implémenter et maintenir deux endpoints de webhook distincts, chacun avec son propre format de payload et sa propre méthode de signature. Avec Simiz, vous recevez un webhook unifié avec un format standardisé, indépendamment du PSP utilisé pour la transaction.
Le client peut-il changer de méthode de paiement en cours de processus ?
Avec Orange Money et MTN MoMo directs, le choix du PSP est figé dès l'initiation. Avec Simiz, le client peut basculer entre Orange Money et MTN MoMo depuis la page de paiement, même après avoir initialement sélectionné une méthode, tant que la transaction n'est pas validée.
Cet article vous a aidé à comprendre les différences entre Orange Money et MTN MoMo au Sénégal. Pour explorer l'intégration des paiements mobiles dans d'autres pays d'Afrique francophone, consultez notre guide de l'API paiement mobile ou découvrez nos solutions pour entreprises SaaS.