Démarrage
URL de l'API (Production)
https://api.epaybf.com/v1/
URL de l'API (Sandbox)
http://18.118.249.61/v1/
L'API E-PAY permet aux marchands d'accepter des paiements Mobile Money (Orange Money et Moov Money) au Burkina Faso. Cette documentation décrit comment intégrer l'API dans votre application.
Pour utiliser cette API, vous avez besoin d'une clé API. Connectez-vous à votre tableau de bord marchand sur epaybf.com et accédez à la section API & Clés pour obtenir votre clé.
Pour toute question, contactez-nous à support@epaybf.com.
Authentification
# Exemple d'authentification
curl -X GET https://api.epaybf.com/v1/checkout-sessions/cs_xxx \
-H "Authorization: Bearer pk_live_VotreCléAPI"
Toutes les requêtes API doivent inclure votre clé API dans l'en-tête Authorization en utilisant le schéma Bearer Token.
EN-TÊTE REQUIS
| En-tête | Valeur |
|---|---|
| Authorization | Bearer pk_live_VotreCléAPI |
| Content-Type | application/json |
Important : Gardez votre clé API secrète. Ne l'exposez jamais dans du code côté client (JavaScript, applications mobiles). Effectuez toujours les appels API depuis votre serveur backend.
Flux de Paiement
E-PAY prend en charge deux opérateurs de Mobile Money, chacun avec un flux légèrement différent :
ORANGE MONEY (orange_bf)
- Votre serveur crée une session de paiement
- Redirigez le client vers la page de paiement hébergée
- Le client compose
*144*4*6*MONTANT#sur son téléphone pour générer un OTP - Le client saisit l'OTP sur la page de paiement
- E-PAY traite le paiement et envoie un webhook à votre serveur
MOOV MONEY (moov_bf)
- Votre serveur crée une session de paiement
- Redirigez le client vers la page de paiement hébergée
- Le client saisit son numéro de téléphone et clique sur "Demander OTP"
- Un OTP est envoyé par SMS au client
- Le client saisit l'OTP reçu
- E-PAY traite le paiement et envoie un webhook à votre serveur
Note : La page de paiement hébergée gère automatiquement les différences entre les opérateurs. Vous n'avez qu'à créer la session et rediriger le client.
Créer une Session de Paiement
# Créer une session de paiement
curl -X POST https://api.epaybf.com/v1/checkout-sessions \
-H "Authorization: Bearer pk_live_VotreCléAPI" \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"currency": "XOF",
"merchant_order_id": "CMD-2026-00001",
"description": "Achat sur MaBoutique",
"merchant_webhook_url": "https://votresite.com/webhooks/epay",
"success_redirect_url": "https://votresite.com/paiement/succes",
"cancel_redirect_url": "https://votresite.com/paiement/annule",
"metadata": {
"customer_id": "client_123",
"product_ids": ["prod_1", "prod_2"]
}
}'
Crée une nouvelle session de paiement et retourne une URL de checkout vers laquelle rediriger votre client.
POST /checkout-sessions
PARAMÈTRES DE LA REQUÊTE
| Champ | Type | Requis | Description |
|---|---|---|---|
| amount | Integer | Oui | Montant en XOF (ex: 5000 pour 5 000 XOF) |
| currency | String | Oui | Devise. Uniquement XOF supporté |
| merchant_order_id | String | Oui | Identifiant unique de la commande dans votre système (max 255 caractères) |
| description | String | Non | Description de la commande (max 500 caractères) |
| merchant_webhook_url | String | Non | URL pour recevoir les notifications de paiement |
| success_redirect_url | String | Non | URL de redirection après paiement réussi |
| cancel_redirect_url | String | Non | URL de redirection si le client annule |
| preferred_method | String | Non | Opérateur présélectionné : orange_bf ou moov_bf |
| metadata | Object | Non | Données personnalisées (retournées dans les webhooks) |
RÉPONSE (201 Created)
{
"session_id": "cs_01JABCDXYZ",
"status": "PENDING",
"checkout_url": "https://pay.epaybf.com/checkout/cs_01JABCDXYZ",
"expires_at": "2026-01-21T13:34:56Z"
}
| Champ | Description |
|---|---|
| session_id | Identifiant unique de la session (préfixe cs_) |
| status | Statut initial : PENDING |
| checkout_url | URL vers laquelle rediriger votre client |
| expires_at | Date d'expiration de la session (ISO 8601) |
Récupérer une Session
# Récupérer les détails d'une session
curl -X GET https://api.epaybf.com/v1/checkout-sessions/cs_01JABCDXYZ \
-H "Authorization: Bearer pk_live_VotreCléAPI"
Récupère les détails d'une session de paiement existante. Utilisez cet endpoint pour vérifier le statut d'un paiement.
GET /checkout-sessions/{session_id}
RÉPONSE (200 OK)
{
"session_id": "cs_01JABCDXYZ",
"status": "COMPLETED",
"amount": 5000,
"currency": "XOF",
"selected_provider": "orange_bf",
"merchant_order_id": "CMD-2026-00001",
"customer_msisdn": "+22670123456",
"provider_txn_id": "OMBF-2026-01-CMD001",
"payment_reference": "pay_01JPAIDXYZ",
"failure_reason": null,
"metadata": {
"customer_id": "client_123"
}
}
STATUTS POSSIBLES
| Statut | Description |
|---|---|
PENDING |
Session créée, en attente du paiement |
COMPLETED |
Paiement réussi |
FAILED |
Paiement échoué (voir failure_reason) |
EXPIRED |
Session expirée sans paiement |
Demander un OTP (Moov Money)
# Demander l'envoi d'un OTP par SMS
curl -X POST https://api.epaybf.com/v1/checkout-sessions/cs_01JABCDXYZ/request-otp \
-H "Authorization: Bearer pk_live_VotreCléAPI" \
-H "Content-Type: application/json" \
-d '{
"phone": "+22670123456"
}'
Demande l'envoi d'un code OTP par SMS au client. Cet endpoint est uniquement nécessaire pour Moov Money. Pour Orange Money, le client génère son propre OTP via USSD.
POST /checkout-sessions/{session_id}/request-otp
PARAMÈTRES
| Champ | Type | Description |
|---|---|---|
| phone | String | Numéro au format +226XXXXXXXX (doit commencer par 6 ou 7) |
RÉPONSE (200 OK)
{
"success": true,
"message": "OTP sent successfully"
}
Limite de taux : Vous devez attendre 120 secondes entre chaque demande d'OTP pour la même session. Si vous dépassez cette limite, vous recevrez une erreur rate_limit_exceeded.
Confirmer le Paiement
# Confirmer le paiement avec l'OTP
curl -X POST https://api.epaybf.com/v1/checkout-sessions/cs_01JABCDXYZ/confirm \
-H "Authorization: Bearer pk_live_VotreCléAPI" \
-H "Content-Type: application/json" \
-d '{
"operator": "orange_bf",
"phone": "+22670123456",
"otp": "1234"
}'
Confirme le paiement en soumettant l'OTP fourni par le client. Cet endpoint est généralement appelé par la page de paiement hébergée, mais peut être utilisé directement si vous construisez votre propre interface.
POST /checkout-sessions/{session_id}/confirm
PARAMÈTRES
| Champ | Type | Description |
|---|---|---|
| operator | String | orange_bf ou moov_bf |
| phone | String | Numéro au format +226XXXXXXXX |
| otp | String | Code OTP à 4 chiffres |
RÉPONSE SUCCÈS (200 OK)
{
"session_id": "cs_01JABCDXYZ",
"status": "COMPLETED",
"payment_reference": "pay_01JPAIDXYZ"
}
RÉPONSE ÉCHEC (200 OK)
{
"session_id": "cs_01JABCDXYZ",
"status": "FAILED",
"payment_reference": null
}
Note : Pour Moov Money, vous devez d'abord appeler /request-otp avant de confirmer le paiement.
Webhooks
E-PAY envoie des notifications webhook à votre serveur lorsqu'un paiement est complété ou échoue. Configurez votre URL de webhook dans le champ merchant_webhook_url lors de la création de la session.
EXEMPLE DE PAYLOAD
{
"event": "payment.updated",
"session_id": "cs_01JABCDXYZ",
"payment_reference": "pay_01JPAIDXYZ",
"status": "COMPLETED",
"amount": 5000,
"currency": "XOF",
"provider": "orange_bf",
"provider_txn_id": "OMBF-2026-01-CMD001",
"merchant_order_id": "CMD-2026-00001"
}
VÉRIFICATION DE LA SIGNATURE
Chaque webhook est signé avec votre webhook_secret (disponible dans votre tableau de bord). Vérifiez toujours la signature pour vous assurer que la requête provient bien d'E-PAY.
En-têtes inclus :
| En-tête | Description |
|---|---|
| X-EPay-Signature | Signature HMAC-SHA256 du payload |
| X-EPay-Timestamp | Horodatage de l'envoi (ISO 8601) |
EXEMPLE DE VÉRIFICATION (PHP)
<?php
// Récupérer les en-têtes et le payload
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_EPAY_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_EPAY_TIMESTAMP'] ?? '';
// Votre webhook_secret (depuis le tableau de bord)
$webhookSecret = 'whsec_votre_secret';
// Calculer la signature attendue
$signedPayload = $timestamp . '.' . $payload;
$expectedSignature = 'sha256=' . hash_hmac('sha256', $signedPayload, $webhookSecret);
// Vérifier la signature
if (!hash_equals($expectedSignature, $signature)) {
http_response_code(401);
exit('Signature invalide');
}
// Vérifier que le timestamp n'est pas trop ancien (5 minutes max)
$timestampAge = time() - strtotime($timestamp);
if ($timestampAge > 300) {
http_response_code(401);
exit('Timestamp expiré');
}
// Traiter le webhook
$data = json_decode($payload, true);
if ($data['status'] === 'COMPLETED') {
// Paiement réussi - mettre à jour votre commande
updateOrder($data['merchant_order_id'], 'paid', $data['payment_reference']);
} elseif ($data['status'] === 'FAILED') {
// Paiement échoué
updateOrder($data['merchant_order_id'], 'payment_failed');
}
// Répondre avec 200 OK
http_response_code(200);
echo 'OK';
Important : Répondez toujours avec un code HTTP 200 pour confirmer la réception du webhook. E-PAY ne réessaie pas automatiquement les webhooks échoués ; utilisez l'endpoint GET /checkout-sessions/{id} pour vérifier le statut si nécessaire.
Gestion des Erreurs
L'API E-PAY utilise les codes HTTP standards et retourne des erreurs au format JSON.
FORMAT DES ERREURS
{
"error": {
"code": "duplicate_session_conflict",
"message": "Une session avec ce merchant_order_id existe déjà.",
"details": {
"existing_session": {
"session_id": "cs_01JEXISTING",
"status": "COMPLETED",
"payment_reference": "pay_01JPAIDXYZ"
}
}
}
}
CODES HTTP
| Code | Description |
|---|---|
| 200 | Succès |
| 201 | Ressource créée |
| 400 | Requête invalide (paramètres manquants ou incorrects) |
| 401 | Non authentifié (clé API invalide ou manquante) |
| 404 | Ressource non trouvée |
| 409 | Conflit (session dupliquée) |
| 429 | Trop de requêtes (limite de taux atteinte) |
| 500 | Erreur serveur |
CODES D'ERREUR À GÉRER
| Code | Description | Action recommandée |
|---|---|---|
duplicate_session_conflict |
Une session complétée existe déjà pour ce merchant_order_id |
Utilisez details.existing_session.payment_reference pour retrouver le paiement |
duplicate_session_pending |
Une session en cours existe déjà | Utilisez details.existing_session.session_id pour suivre la session existante |
provider_error |
Erreur temporaire du fournisseur | Réessayez après quelques secondes |
rate_limit_exceeded |
Limite de demandes OTP atteinte | Attendez details.retry_after_seconds secondes avant de réessayer |
validation_error |
Données de requête invalides | Vérifiez les champs dans details |
Environnement de Test (Sandbox)
URL Sandbox
http://18.118.249.61/v1/
Utilisez l'environnement sandbox pour tester votre intégration sans effectuer de vrais paiements. Toutes les fonctionnalités sont identiques à la production.
CLÉS DE TEST
Les clés de test commencent par pk_test_. Vous les trouverez dans votre tableau de bord marchand, section API & Clés.
BONNES PRATIQUES
- Testez tous les scénarios : paiement réussi, échec, expiration
- Vérifiez que vos webhooks fonctionnent correctement
- Testez la gestion des erreurs (sessions dupliquées, OTP invalide)
- Passez en production uniquement après avoir validé tous les tests
Note : En sandbox, les OTP et paiements sont simulés. Utilisez n'importe quel numéro de téléphone valide au format +226XXXXXXXX.
