Intégrer Orange Money au Burkina Faso en 30 minutes
Orange Money domine le marché des paiements mobiles au Burkina Faso avec 62% de parts de marché et plus de 4.5 millions d'utilisateurs actifs. Intégrer Orange Money est obligatoire pour capter ces clients. Voici comment obtenir vos identifiants API, configurer l'intégration et recevoir votre premier paiement en 30 minutes.
Le marché Orange Money au Burkina Faso
Chiffres clés 2026
| Indicateur | Valeur |
|---|---|
| Utilisateurs actifs | 4.5 millions |
| Parts de marché | 62% |
| Transactions mensuelles | 18 millions |
| Volume annuel | 4.2 milliards FCFA |
| Points de vente | 12 000+ |
Positionnement réglementaire
Le Burkina Faso est membre de l'UEMOA et suit les directives de la BCEAO pour les services de paiement. Orange Money Burkina est agréé comme Établissement de Monnaie Électronique (EME) et opère sous la supervision de l'Unité de Contrôle et de Régulation des Établissements de Monnaie Électronique (UCR-EME) de la BCEAO.
Quels sont les prérequis pour intégrer Orange Money au Burkina Faso ?
Pour intégrer Orange Money au Burkina, il faut cinq éléments : un compte développeur Orange, une adresse IP statique ou un serveur HTTPS pour les webhooks, des documents KYB valides (registre de commerce), et un contrat d'intégration signé avec Orange Sonatel ou via un agrégateur agréé.
Environnement technique requis
- Serveur HTTPS : Obligatoire pour les webhooks de production
- IP statique : Recommandée pour la liste blanche Orange
- Support TLS 1.2+ : Minimum pour les communications API
- Capacité de traitement webhooks : Maximum 3 secondes de réponse
Documents administratifs
- Registre de commerce (RCCM)
- Autorisation UEMOA si applicable
- Contrat d'intégration signé
- Attestation de conformité sécurité (si volumes > 10M FCFA/mois)
Comment obtenir ses identifiants API Orange Money Burkina Faso ?
L'obtention des identifiants API se fait via le portail développeur Orange Money ou auprès de l'équipe partenariat de Sonatel Burkina. La procédure dure 48h à 2 semaines. Deux options existent : l'intégration directe avec Orange ou l'utilisation d'un agrégateur comme Simiz.
Option 1 : Intégration directe avec Orange
Contact :- Email : partenariats.money@sonatel.bf
- Adresse : Ouagadougou, Rue 31.033
- Délai moyen : 2-4 semaines
- Soumission du dossier de partenariat
- Audit technique de votre infrastructure
- Signature du contrat d'intégration
- Création du compte développeur
- Génération des identifiants Sandbox
- Validation et passage en Production
Option 2 : Via Simiz (recommandé)
Simiz est agréé par la BCEAO comme PSP et dispose d'un contrat d'intégration multi-pays avec Orange. Vous obtenez vos identifiants immédiatement après création de compte et vérification KYB.
// Création de compte Simiz et obtention des clés API
// 1. Créer un compte sur https://simiz.io/register
// 2. Compléter le KYB (5-10 minutes)
// 3. Obtenir les clés API instantanément
const simiz = new Simiz({
apiKey: 'smz_test_pk_burkina_xxxxx',
secretKey: 'smz_test_sk_burkina_xxxxx',
environment: 'sandbox'
});
Quelle est la procédure d'intégration étape par étape ?
Une fois vos identifiants API obtenus, l'intégration technique suit cinq étapes : configuration de l'environnement de développement, installation du SDK ou configuration des requêtes HTTP directes, création du premier paiement, mise en place des webhooks pour les notifications, et tests avant le passage en production.
Étape 1 : Configuration de l'environnement
Variables d'environnement à définir :.env file
ORANGE_MONEY_CLIENT_ID=bf_sandbox_client_xxxxx
ORANGE_MONEY_CLIENT_SECRET=bf_sandbox_secret_xxxxx
ORANGE_MONEY_API_KEY=bf_api_key_xxxxx
ORANGE_MONEY_MERCHANT_ID=BF_MERCHANT_XXXXX
ORANGE_MONEY_WEBHOOK_SECRET=webhook_secret_xxxxx
ORANGE_MONEY_ENVIRONMENT=sandbox
OU avec Simiz (recommandé)
SIMIZ_API_KEY=smz_test_pk_burkina_xxxxx
SIMIZ_SECRET_KEY=smz_test_sk_burkina_xxxxx
SIMIZ_ENVIRONMENT=sandbox
Étape 2 : Installation du SDK
Node.js :npm install @simiz/sdk axiospip install simiz-sdk requestsÉtape 3 : Configuration de l'instance
// config/orange-money.js
import { Simiz } from '@simiz/sdk';
export const paymentProvider = new Simiz({
apiKey: process.env.SIMIZ_API_KEY,
secretKey: process.env.SIMIZ_SECRET_KEY,
environment: process.env.SIMIZ_ENVIRONMENT || 'sandbox',
webhookSecret: process.env.SIMIZ_WEBHOOK_SECRET
});
export default paymentProvider;
config/orange_money.py
from simiz_sdk import Simiz
import os
payment_provider = Simiz(
api_key=os.getenv('SIMIZ_API_KEY'),
secret_key=os.getenv('SIMIZ_SECRET_KEY'),
environment=os.getenv('SIMIZ_ENVIRONMENT', 'sandbox'),
webhook_secret=os.getenv('SIMIZ_WEBHOOK_SECRET')
)
Étape 4 : Créer un paiement
// services/payment.js
import { paymentProvider } from '../config/orange-money.js';
export async function createOrangeMoneyPayment(amount, phone, reference) {
try {
const payment = await paymentProvider.payments.create({
amount: amount,
currency: 'XOF', // Franc CFA West Africa
phone: formatPhoneBurkina(phone), // Format: +226 XX XX XX XX
provider: 'orange_money_burkina',
reference: reference,
description: 'Paiement sur MaPlateforme',
webhookUrl: 'https://votre-site.com/webhooks/orange-money',
metadata: {
country: 'BF',
merchant_reference: reference
}
});
return {
success: true,
paymentId: payment.id,
status: payment.status,
expiresAt: payment.expiresAt
};
} catch (error) {
console.error('Erreur création paiement:', error);
return {
success: false,
error: error.message
};
}
}
function formatPhoneBurkina(phone) {
// Nettoyer et formater au format international +226
const cleaned = phone.replace(/\D/g, '');
if (cleaned.startsWith('226')) {
return +${cleaned};
}
if (cleaned.length === 8) {
return +226${cleaned};
}
return phone;
}
services/payment.py
from config.orange_money import payment_provider
import re
def create_orange_money_payment(amount: int, phone: str, reference: str):
try:
payment = payment_provider.payments.create(
amount=amount,
currency='XOF',
phone=format_phone_burkina(phone),
provider='orange_money_burkina',
reference=reference,
description='Paiement sur MaPlateforme',
webhook_url='https://votre-site.com/webhooks/orange-money',
metadata={
'country': 'BF',
'merchant_reference': reference
}
)
return {
'success': True,
'payment_id': payment.id,
'status': payment.status,
'expires_at': payment.expires_at
}
except Exception as error:
print(f'Erreur création paiement: {error}')
return {
'success': False,
'error': str(error)
}
def format_phone_burkina(phone: str) -> str:
cleaned = re.sub(r'\D', '', phone)
if cleaned.startswith('226'):
return f'+{cleaned}'
if len(cleaned) == 8:
return f'+226{cleaned}'
return phone
Étape 5 : Gérer les webhooks
// routes/webhooks.js
import express from 'express';
import { paymentProvider } from '../config/orange-money.js';
const router = express.Router();
router.post('/orange-money', express.raw({type: 'application/json'}), (req, res) => {
const signature = req.headers['x-simiz-signature'];
const payload = req.body;
// Vérification de la signature webhook
if (!paymentProvider.webhooks.verify(payload, signature)) {
console.error('Signature webhook invalide');
return res.status(401).json({ error: 'Invalid signature' });
}
const event = JSON.parse(payload);
switch (event.type) {
case 'payment.success':
handlePaymentSuccess(event.data);
break;
case 'payment.failed':
handlePaymentFailed(event.data);
break;
case 'payment.expired':
handlePaymentExpired(event.data);
break;
}
res.json({ received: true });
});
async function handlePaymentSuccess(payment) {
// Mettre à jour votre base de données
// Confirmer la commande
// Envoyer notification au client
console.log(Paiement ${payment.id} réussi pour ${payment.reference});
}
async function handlePaymentFailed(payment) {
// Annuler la commande
// Notifier le client
console.log(Paiement ${payment.id} échoué: ${payment.failureReason});
}
async function handlePaymentExpired(payment) {
// Libérer le stock
// Notifier le client
console.log(Paiement ${payment.id} expiré);
}
export default router;
Comment tester les paiements en mode sandbox ?
Le mode sandbox Orange Money Burkina Faso simule des paiements réels sans débourser d'argent. Vous disposez de numéros de test prédéfinis pour quatre scénarios : paiement réussi, échec par solde insuffisant, annulation utilisateur, et timeout. Les environnements sandbox sont accessibles 24h/24 sans latence.
Numéros de test sandbox
| Scénario | Numéro de test | Code PIN | Résultat |
|---|---|---|---|
| Paiement réussi | +22670000001 | 1234 | Success |
| Solde insuffisant | +22670000002 | 1234 | Failed (insufficient_funds) |
| Annulation | +22670000003 | 1234 | Cancelled |
| Timeout | +22670000004 | 1234 | Expired après 5 min |
Script de test complet
// tests/payment.test.js
import { createOrangeMoneyPayment } from '../services/payment.js';
import { paymentProvider } from '../config/orange-money.js';
async function testScenarios() {
const testCases = [
{ phone: '+22670000001', amount: 5000, scenario: 'Succès' },
{ phone: '+22670000002', amount: 500000, scenario: 'Solde insuffisant' },
{ phone: '+22670000003', amount: 5000, scenario: 'Annulation' },
{ phone: '+22670000004', amount: 5000, scenario: 'Timeout' }
];
for (const testCase of testCases) {
console.log(\n--- Test : ${testCase.scenario} ---);
console.log(Numéro: ${testCase.phone});
console.log(Montant: ${testCase.amount} XOF);
const result = await createOrangeMoneyPayment(
testCase.amount,
testCase.phone,
TEST-${Date.now()}
);
if (result.success) {
console.log(✓ Paiement créé: ${result.paymentId});
console.log( Statut: ${result.status});
console.log( Expiration: ${result.expiresAt});
// Attendre et vérifier le statut final
await new Promise(resolve => setTimeout(resolve, 3000));
const status = await paymentProvider.payments.retrieve(result.paymentId);
console.log( Statut final: ${status.status});
} else {
console.log(✗ Erreur: ${result.error});
}
}
}
testScenarios();
Vérification des webhooks en local
Pour tester les webhooks en développement, utilisez ngrok ou un outil similaire :
Installation ngrok
npm install -g ngrok
Lancer votre serveur local
npm run dev
Dans un autre terminal, exposer le port
ngrok http 3000
Configurer l'URL webhook dans votre dashboard Simiz
https://votre-id.ngrok.io/webhooks/orange-money
Quels sont les codes d'erreur fréquents et comment les gérer ?
Les erreurs les plus fréquentes lors de l'intégration Orange Money Burkina se regroupent en trois catégories : erreurs de validation (numéro invalide, montant hors plage), erreurs d'authentification (clés API incorrectes, signature webhook invalide), et erreurs transactionnelles (solde insuffisant, utilisateur introuvable). Une gestion appropriée de ces erreurs améliore le taux de conversion.
Codes d'erreur principaux
| Code HTTP | Code erreur | Description | Action recommandée |
|---|---|---|---|
| 400 | INVALID_PHONE | Format numéro invalide | Vérifier format +226 XX XX XX XX |
| 400 | AMOUNT_OUT_OF_RANGE | Montant hors limites | Vérifier min 100 XOF, max 500 000 XOF |
| 401 | INVALID_API_KEY | Clé API incorrecte | Vérifier variables environnement |
| 403 | MERCHANT_SUSPENDED | Marchand suspendu | Contacter le support |
| 404 | USER_NOT_FOUND | Utilisateur Orange introuvable | Vérifier le numéro |
| 409 | DUPLICATE_REFERENCE | Référence déjà utilisée | Générer une référence unique |
| 422 | INSUFFICIENT_FUNDS | Solde client insuffisant | Demander autre moyen de paiement |
| 429 | RATE_LIMIT_EXCEEDED | Trop de requêtes | Implémenter retry avec backoff |
| 500 | PROVIDER_ERROR | Erreur Orange Sonatel | Réessayer plus tard |
Gestion des erreurs en production
// services/payment-handler.js
export class PaymentHandler {
static handlePaymentError(error, context) {
const errorMap = {
'INVALID_PHONE': {
userMessage: 'Le numéro de téléphone est invalide. Veuillez entrer un numéro au format +226 XX XX XX XX.',
retryable: false
},
'AMOUNT_OUT_OF_RANGE': {
userMessage: 'Le montant doit être compris entre 100 et 500 000 FCFA.',
retryable: false
},
'INSUFFICIENT_FUNDS': {
userMessage: 'Le solde Orange Money est insuffisant. Veuillez recharger votre compte ou utiliser un autre moyen de paiement.',
retryable: false
},
'USER_NOT_FOUND': {
userMessage: 'Ce numéro n\'est pas associé à un compte Orange Money. Vérifiez le numéro.',
retryable: false
},
'DUPLICATE_REFERENCE': {
userMessage: 'Une erreur technique est survenue. Veuillez réessayer.',
retryable: true,
action: 'generateNewReference'
},
'RATE_LIMIT_EXCEEDED': {
userMessage: 'Trop de tentatives. Veuillez attendre quelques instants.',
retryable: true,
delay: 5000
},
'PROVIDER_ERROR': {
userMessage: 'Un problème temporaire est survenu. Veuillez réessayer dans quelques minutes.',
retryable: true,
delay: 30000
}
};
const errorCode = error.code || 'UNKNOWN_ERROR';
const errorConfig = errorMap[errorCode] || errorMap['PROVIDER_ERROR'];
// Log pour monitoring
this.logError(error, context, errorCode);
return {
userMessage: errorConfig.userMessage,
retryable: errorConfig.retryable,
retryDelay: errorConfig.delay || 0,
action: errorConfig.action
};
}
static logError(error, context, code) {
// Envoyer à votre système de monitoring
// Sentry, DataDog, ou votre propre solution
console.error({
timestamp: new Date().toISOString(),
code,
message: error.message,
context: {
phone: context.phone,
amount: context.amount,
reference: context.reference
}
});
}
static async retryWithBackoff(fn, maxRetries = 3, baseDelay = 1000) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (attempt === maxRetries - 1) throw error;
const handling = this.handlePaymentError(error, {});
if (!handling.retryable) throw error;
const delay = baseDelay * Math.pow(2, attempt);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
}
Comment passer en production et sécuriser ses webhooks ?
Le passage en production nécessite trois validations : validation complète des tests sandbox, approbation du compte par l'équipe compliance (24-48h), et configuration des clés API de production. La sécurité des webhooks est critique : implémentez la vérification de signature HTTPS, utilisez des secrets uniques par environnement, et rejetez les requêtes non signées.
Checklist avant production
- [ ] Tous les scénarios sandbox validés
- [ ] Serveur HTTPS avec certificat valide
- [ ] IP stative configurée (recommandé)
- [ ] Webhook signature vérification implémentée
- [ ] Logs structurés en place
- [ ] Monitoring et alertes configurés
- [ ] Limites de taux (rate limiting) actives
- [ ] Base de données backup automatisé
- [ ] Processus de gestion des refunds défini
Configuration production
// config/orange-money.production.js
import { Simiz } from '@simiz/sdk';
const validateEnvironment = () => {
const required = [
'SIMIZ_API_KEY',
'SIMIZ_SECRET_KEY',
'SIMIZ_WEBHOOK_SECRET',
'DATABASE_URL'
];
const missing = required.filter(key => !process.env[key]);
if (missing.length > 0) {
throw new Error(Variables manquantes: ${missing.join(', ')});
}
if (process.env.NODE_ENV !== 'production') {
console.warn(' Attention: environnement != production');
}
};
validateEnvironment();
export const paymentProvider = new Simiz({
apiKey: process.env.SIMIZ_API_KEY,
secretKey: process.env.SIMIZ_SECRET_KEY,
environment: 'production',
webhookSecret: process.env.SIMIZ_WEBHOOK_SECRET,
timeout: 30000,
maxRetries: 3
});
Sécurité webhook renforcée
// middleware/webhook-security.js
import crypto from 'crypto';
export function webhookSecurity(req, res, next) {
const signature = req.headers['x-simiz-signature'];
const timestamp = req.headers['x-simiz-timestamp'];
const payload = req.body;
// Vérifier que le timestamp est récent (anti-replay)
const now = Math.floor(Date.now() / 1000);
if (Math.abs(now - parseInt(timestamp)) > 300) {
return res.status(401).json({ error: 'Timestamp too old' });
}
// Vérifier la signature
const expectedSignature = crypto
.createHmac('sha256', process.env.SIMIZ_WEBHOOK_SECRET)
.update(${timestamp}.${payload})
.digest('hex');
if (!crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(sha256=${expectedSignature})
)) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Vérifier l'IP (optionnel, si IP fixe)
const allowedIPs = process.env.WEBHOOK_ALLOWED_IPS?.split(',') || [];
if (allowedIPs.length > 0 && !allowedIPs.includes(req.ip)) {
return res.status(403).json({ error: 'IP not allowed' });
}
next();
}
Quelles sont les spécificités réglementaires du Burkina Faso ?
Le Burkina Faso suit le cadre réglementaire UEMOA défini par la BCEAO. Les paiements mobiles sont régis par l'Instruction n°009/05-2011 (services de paiement), le Réglement n°14/2016 (EME), et les directives LCB-FT. En tant que marchand, conservez les logs de transactions pendant 10 ans et déclarez toute opération suspecte.
Obligations légales pour les marchands
| Obligation | Description | Périodicité |
|---|---|---|
| Conservation des logs | Toutes les transactions pendant 10 ans | Permanent |
| Seuil de déclaration | Transactions > 5 000 000 XOF | À chaque opération |
| Audit annuel | Si volume > 50M XFA/an | Annuel |
| Conformité LCB-FT | Vérification KYC clients | À l'onboarding |
Plafonds transactionnels Orange Money Burkina
| Type | Par transaction | Quotidien | Mensuel |
|---|---|---|---|
| Paiement marchand | 500 000 XOF | 1 500 000 XOF | 5 000 000 XOF |
| Transfert P2P | 500 000 XOF | 1 000 000 XOF | 3 000 000 XOF |
| Cash-in/cash-out | 500 000 XOF | 2 000 000 XOF | 7 500 000 XOF |
Conformité et certification
Si votre plateforme traite plus de 100 millions FCFA de transactions annuelles, vous devrez obtenir une certification de sécurité délivrée par un organisme agréé par la BCEAO. Simiz, en tant qu'agrégateur, maintient cette certification et vous permet de bénéficier de sa conformité via son infrastructure.
Pour plus d'informations sur la réglementation des paiements mobiles au Burkina Faso, consultez le site de la BCEAO ou contactez l'UCR-EME.
Pourquoi utiliser un agrégateur comme Simiz ?
L'intégration directe avec Orange Money Burkina expose à plusieurs défis : délais de 2 à 4 semaines, documentation limitée, support développeur minimal, et obligation de signer des contrats séparés pour chaque pays (MTN MoMo, Moov, etc.). Simiz résout ces problèmes en agissant comme orchestrateur non-custodial : vous gardez le contrôle de vos fonds, Simiz achemine les transactions vers les PSP partenaires.
Avantages de l'intégration via Simiz
- Délai : 30 minutes pour le premier paiement
- Une seule API : Orange Money + MTN MoMo + Coris + 15 autres PSP
- Documentation complète : Guides, SDK, exemples de code
- Support réactif : Réponses sous 2h ouvrées
- Multi-pays : Burkina Faso, Sénégal, Mali, Côte d'Ivoire, etc.
- Conformité : Simiz est agréé PSP UEMOA/CEMAC
Découvrez les pages de paiement Simiz pour accepter des paiements sans code, ou consultez notre guide de démarrage rapide.
FAQ
Combien coûte l'intégration Orange Money au Burkina Faso ?
L'intégration via Simiz est gratuite : aucun frais de setup, aucun abonnement mensuel. Vous payez uniquement une commission de 2.5% par transaction réussie, avec un plan tarifaire dégressif selon votre volume. Consultez notre page pricing pour les détails.
Quels délais de paiement puis-je attendre avec Orange Money Burkina ?
Les paiements Orange Money sont confirmés en temps réel (5-30 secondes après la validation PIN du client). Le webhook est envoyé immédiatement après confirmation. Les fonds sont crédités sur votre compte marchand J+1 (jour ouvrable suivant).
Puis-je tester l'intégration sans compte Orange Money ?
Oui, le mode sandbox Simiz fonctionne avec des numéros de test virtuels. Aucun compte Orange Money réel n'est nécessaire pour les tests. Vous pouvez simuler tous les scénarios (succès, échec, annulation) avant le passage en production.
Quels sont les plafonds de paiement Orange Money au Burkina Faso ?
Le plafond par paiement est de 500 000 FCFA, avec une limite journalière de 1 500 000 FCFA par client. Pour les montants supérieurs, vous devez implémenter des paiements fractionnés ou proposer d'autres moyens de paiement.
Comment gérer les remboursements avec Orange Money Burkina ?
Les remboursements sont possibles jusqu'à 30 jours après la transaction originale. Via Simiz, utilisez l'endpoint refunds.create() avec le payment_id. Le remboursement est crédité sur le compte Orange Money du client sous 24h ouvrées.
À propos de l'auteur
Jean-Pierre Mbarga est Lead Developer chez Simiz. Il a architecté l'API de paiement Simiz et accompagné plus de 200 startups dans leur intégration Mobile Money en Afrique francophone.