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)

  1. Votre serveur crée une session de paiement
  2. Redirigez le client vers la page de paiement hébergée
  3. Le client compose *144*4*6*MONTANT# sur son téléphone pour générer un OTP
  4. Le client saisit l'OTP sur la page de paiement
  5. E-PAY traite le paiement et envoie un webhook à votre serveur

MOOV MONEY (moov_bf)

  1. Votre serveur crée une session de paiement
  2. Redirigez le client vers la page de paiement hébergée
  3. Le client saisit son numéro de téléphone et clique sur "Demander OTP"
  4. Un OTP est envoyé par SMS au client
  5. Le client saisit l'OTP reçu
  6. 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.

© 2026 E-Pay | support@epaybf.com