TechniqueÀ la une

Guide complet : Intégrer Moov Money via API

J

Jean-Pierre Mbarga

Lead Developer

20 janvier 202612 min de lecture
G

Guide complet : Intégrer Moov Money via API

Moov Africa (ex-Atlantique Telecom) est un acteur majeur du Mobile Money en Afrique de l'Ouest avec une présence forte au Bénin, Togo, Côte d'Ivoire et Niger. Ce guide vous accompagne dans l'intégration de Moov Money via l'API Simiz.

Présentation de Moov Money

Pays couverts

PaysCode ISODevisePréfixes téléphoniques
BéninBJXOF+229 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
TogoTGXOF+228 90, 91, 92, 93, 96, 97, 98, 99
Côte d'IvoireCIXOF+225 01, 02, 03, 04, 05, 06, 07
NigerNEXOF+227 90, 91, 92, 93, 94, 95, 96, 97, 98, 99

Chiffres clés Moov Money

  • 10 millions d'utilisateurs actifs
  • 500 000 points de vente
  • 2.5 milliards de dollars de transactions annuelles
  • 35% de parts de marché en zone UEMOA

Pourquoi intégrer Moov Money ?

Avantages

  1. Couverture rurale - Moov a un excellent réseau en zones rurales
  2. Frais compétitifs - Commission généralement inférieure à Orange Money
  3. Clients exclusifs - Certains clients n'ont que Moov comme opérateur
  4. API stable - Infrastructure fiable et éprouvée

Défis

  1. Documentation limitée - Peu de ressources en ligne
  2. Support réactif - Parfois lent pour les développeurs tiers
  3. Validation stricte - Processus KYB rigoureux

Architecture de l'intégration

Flux de paiement

┌─────────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐

│ Client │────>│ Votre App │────>│ Simiz API │────>│ Moov Money │

│ (Moov) │ │ │ │ │ │ │

└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘

│ │ │

│<─────────────────────────────────────────│<───────────────────│

│ Notification USSD/Push │ Confirmation │

│ │ │

│<─────────────────────────────────────────│<───────────────────│

│ Webhook de statut │ Callback │

└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘

Étape 1 : Configuration du compte

Création du compte Simiz

  1. Rendez-vous sur simiz.io/register
  2. Complétez votre inscription
  3. Vérifiez votre email
  4. Soumettez vos documents KYB :
- RCCM / Registre du commerce

- Statuts de la société

- Pièce d'identité du dirigeant

- Justificatif de domicile

Configuration Moov Money

Dans votre dashboard Simiz :

  1. Activez Moov Money pour votre projet
  2. Sélectionnez les pays où vous opérez
  3. Configurez vos webhooks de notification

Étape 2 : Installation du SDK

Node.js / JavaScript

bun add @simiz/sdk

PHP

composer require simiz/simiz-php

Python

pip install simiz

Étape 3 : Initier un paiement Moov Money

Exemple JavaScript

import { Simiz } from '@simiz/sdk';

// Initialisation

const simiz = new Simiz({

apiKey: process.env.SIMIZ_API_KEY,

secretKey: process.env.SIMIZ_SECRET_KEY,

sandbox: true // false en production

});

// Créer un paiement Moov Money

async function createMoovPayment(phoneNumber, amount, reference) {

try {

const payment = await simiz.payments.create({

amount: amount, // Montant en FCFA

currency: 'XOF', // Devise locale

phone: phoneNumber, // Numéro Moov Money

provider: 'moov_money', // Moov Money

country: 'BJ', // Code pays (BJ, TG, CI, NE)

description: 'Achat sur MonSite.com',

reference: reference,

callbackUrl: 'https://monsite.com/webhooks/simiz',

returnUrl: 'https://monsite.com/paiement/merci',

cancelUrl: 'https://monsite.com/paiement/annule',

metadata: {

orderId: reference,

customerId: 'CUST-001',

items: JSON.stringify([{ id: 'PROD-001', qty: 1 }])

}

});

console.log('Paiement créé:', payment.id);

console.log('Statut:', payment.status); // 'pending'

return payment;

} catch (error) {

console.error('Erreur:', error.message);

throw error;

}

}

// Utilisation

createMoovPayment('+22997001234', 10000, 'CMD-2026-001');

Exemple PHP

<?php

require 'vendor/autoload.php';

use Simiz\SimizClient;

$simiz = new SimizClient([

'api_key' => getenv('SIMIZ_API_KEY'),

'secret_key' => getenv('SIMIZ_SECRET_KEY'),

'sandbox' => true

]);

$payment = $simiz->payments->create([

'amount' => 10000,

'currency' => 'XOF',

'phone' => '+22997001234',

'provider' => 'moov_money',

'country' => 'BJ',

'description' => 'Achat sur MonSite.com',

'reference' => 'CMD-2026-001',

'callback_url' => 'https://monsite.com/webhooks/simiz'

]);

echo "Paiement ID: " . $payment->id . "\n";

echo "Statut: " . $payment->status . "\n";

Étape 4 : Gérer les webhooks

Configuration du endpoint

// Express.js

import express from 'express';

import { Simiz } from '@simiz/sdk';

const app = express();

app.use(express.json());

const simiz = new Simiz({

apiKey: process.env.SIMIZ_API_KEY,

secretKey: process.env.SIMIZ_SECRET_KEY

});

app.post('/webhooks/simiz', async (req, res) => {

try {

// Vérifier la signature

const signature = req.headers['x-simiz-signature'];

const isValid = simiz.webhooks.verify(req.body, signature);

if (!isValid) {

console.error('Signature webhook invalide');

return res.status(401).json({ error: 'Invalid signature' });

}

const event = req.body;

// Traiter l'événement

switch (event.type) {

case 'payment.success':

await handlePaymentSuccess(event.data);

break;

case 'payment.failed':

await handlePaymentFailed(event.data);

break;

case 'payment.expired':

await handlePaymentExpired(event.data);

break;

case 'payment.cancelled':

await handlePaymentCancelled(event.data);

break;

default:

console.log('Événement inconnu:', event.type);

}

// Répondre rapidement (avant 30 secondes)

res.json({ received: true });

} catch (error) {

console.error('Erreur webhook:', error);

res.status(500).json({ error: 'Internal server error' });

}

});

app.listen(3000, () => {

console.log('Serveur webhook démarré sur le port 3000');

});

// Handlers d'événements

async function handlePaymentSuccess(data) {

const { reference, amount, currency } = data;

// Mettre à jour la commande

await updateOrderStatus(reference, 'PAID');

// Envoyer confirmation client

await sendPaymentConfirmation(reference);

// Libérer le produit/service

await fulfillOrder(reference);

console.log(Paiement réussi: ${reference} - ${amount} ${currency});

}

async function handlePaymentFailed(data) {

const { reference, errorCode, errorMessage } = data;

await updateOrderStatus(reference, 'FAILED');

await notifyPaymentFailed(reference, errorMessage);

console.log(Paiement échoué: ${reference} - ${errorCode});

}

Types d'événements Moov Money

ÉvénementDescriptionAction recommandée
payment.successPaiement confirméLivrer le produit/service
payment.failedPaiement échouéNotifier le client, proposer réessayer
payment.expiredDélai dépasséRenvoyer lien de paiement
payment.cancelledAnnulé par le clientArchiver la commande

Étape 5 : Codes d'erreur Moov Money

Codes d'erreur courants

CodeDescriptionSolution
insufficient_balanceSolde Moov Money insuffisantInformer le client de recharger
invalid_phoneNuméro non Moov MoneyVérifier le préfixe téléphonique
transaction_limitPlafond journalier atteintReporter le paiement au lendemain
service_unavailableMoov Money temporairement indisponibleRéessayer plus tard
pin_errorCode PIN incorrectContact support Moov
account_inactiveCompte Moov Money inactifClient doit réactiver son compte
timeoutTimeout opérateurRéessayer la transaction
duplicate_transactionTransaction en doubleVérifier le statut de la commande

Gestion des erreurs

try {

const payment = await simiz.payments.create({

amount: 10000,

phone: '+22997001234',

provider: 'moov_money',

country: 'BJ',

// ... autres paramètres

});

} catch (error) {

switch (error.code) {

case 'insufficient_balance':

return res.status(400).json({

error: 'Solde insuffisant',

message: 'Veuillez recharger votre compte Moov Money'

});

case 'invalid_phone':

return res.status(400).json({

error: 'Numéro invalide',

message: 'Ce numéro n\'est pas un compte Moov Money'

});

case 'transaction_limit':

return res.status(400).json({

error: 'Limite atteinte',

message: 'Limite journalière dépassée. Réessayez demain.'

});

case 'service_unavailable':

return res.status(503).json({

error: 'Service indisponible',

message: 'Moov Money est temporairement indisponible. Veuillez réessayer.'

});

default:

return res.status(500).json({

error: 'Erreur inconnue',

message: error.message

});

}

}

Étape 6 : Validation du numéro

Vérifier si un numéro est Moov Money

function isMoovNumber(phone, country) {

const cleanPhone = phone.replace(/[^0-9]/g, '');

const moovPrefixes = {

'BJ': ['22990', '22991', '22992', '22993', '22994', '22995', '22996', '22997', '22998', '22999'],

'TG': ['22890', '22891', '22892', '22893', '22896', '22897', '22898', '22899'],

'CI': ['22501', '22502', '22503', '22504', '22505', '22506', '22507'],

'NE': ['22790', '22791', '22792', '22793', '22794', '22795', '22796', '22797', '22798', '22799']

};

const prefixes = moovPrefixes[country];

if (!prefixes) return false;

return prefixes.some(prefix => cleanPhone.startsWith(prefix));

}

// Utilisation

console.log(isMoovNumber('+22997001234', 'BJ')); // true

console.log(isMoovNumber('+22507001234', 'CI')); // true

console.log(isMoovNumber('+23769001234', 'CM')); // false (Cameroun)

Étape 7 : Tests en Sandbox

Numéros de test

NuméroPaysComportement
+229990000001BéninPaiement réussi
+229990000002BéninSolde insuffisant
+229990000003BéninTimeout
+229990000004BéninRefusé par le client
+228990000001TogoPaiement réussi
+228990000002TogoSolde insuffisant
+225010000001Côte d'IvoirePaiement réussi
+225010000002Côte d'IvoireSolde insuffisant

Scénarios de test

// Test paiement réussi

await testPayment('+229990000001', 10000, 'BJ'); // Success

// Test solde insuffisant

await testPayment('+229990000002', 100000, 'BJ'); // Error: insufficient_balance

// Test timeout

await testPayment('+229990000003', 5000, 'BJ'); // Error: timeout

// Test annulation

await testPayment('+229990000004', 5000, 'BJ'); // Error: cancelled

Étape 8 : Passage en production

Checklist avant le lancement

  • [ ] Tous les tests Sandbox validés
  • [ ] Webhooks configurés et testés
  • [ ] Gestion des erreurs implémentée
  • [ ] Emails de confirmation configurés
  • [ ] Logs de transactions activés
  • [ ] Clés Production générées
  • [ ] Variable sandbox: false
  • [ ] Système de monitoring mis en place
  • [ ] Équipe support formée

Configuration production

const simiz = new Simiz({

apiKey: process.env.SIMIZ_API_KEY_PROD, // smz_live_pk_xxx

secretKey: process.env.SIMIZ_SECRET_KEY_PROD, // smz_live_sk_xxx

sandbox: false // Important : false en production

});

Bonnes pratiques

1. Idempotence

Évitez les doubles paiements :

const payment = await simiz.payments.create({

amount: 10000,

phone: '+22997001234',

provider: 'moov_money',

country: 'BJ',

reference: 'CMD-2026-001'

}, {

idempotencyKey: order-${orderId}-v1

});

2. Timeout et retry

Les paiements Moov Money expirent après 15 minutes :

async function waitForPayment(paymentId, maxAttempts = 10) {

for (let i = 0; i < maxAttempts; i++) {

const payment = await simiz.payments.retrieve(paymentId);

if (['success', 'failed', 'expired', 'cancelled'].includes(payment.status)) {

return payment;

}

await new Promise(resolve => setTimeout(resolve, 30000)); // 30 secondes

}

throw new Error('Timeout en attente du paiement');

}

3. Sécurité

  • Stockez vos clés API dans des variables d'environnement
  • Validez toujours les signatures des webhooks
  • Utilisez HTTPS pour tous les endpoints
  • Ne loggez jamais les numéros de téléphone complets
  • Implémentez une politique de rétention des données

4. Surveillance

// Metriques à surveiller

const metrics = {

paymentsInitiated: 0,

paymentsSuccess: 0,

paymentsFailed: 0,

averageResponseTime: 0,

errorsByCode: {}

};

// Alerte si taux d'échec > 5%

if (metrics.paymentsFailed / metrics.paymentsInitiated > 0.05) {

alertTeam('Taux d\'échec élevé sur Moov Money');

}

Conclusion

L'intégration de Moov Money via Simiz est simple et rapide. En suivant ce guide, vous pouvez accepter les paiements Moov Money au Bénin, Togo, Côte d'Ivoire et Niger en quelques heures.

Les avantages clés de passer par Simiz :
  • Une seule API pour Moov Money + Orange Money + MTN MoMo
  • Documentation unifiée en français
  • Support technique dédié
  • Tests en sandbox gratuits

Prêt à commencer ? Créez votre compte gratuit et commencez à intégrer Moov Money aujourd'hui.
Besoin d'aide ? Contactez notre équipe technique à developer@simiz.io
Partager cet article
J

Jean-Pierre Mbarga

Lead Developer

Passionné par les technologies financières et l'inclusion financière en Afrique. Contribue régulièrement au blog Simiz sur les sujets liés aux paiements Mobile Money.

Articles similaires