Démarrage
URL de l'API (Production)
https://app.epaybf.com/api/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.
Guide de Démarrage Rapide
Intégrez E-PAY en 3 étapes simples. Votre serveur n'a besoin d'appeler qu'un seul endpoint — le reste est géré automatiquement par notre page de paiement hébergée.
RÉSUMÉ DU FLUX
┌─────────────────┐ ┌─────────────┐ ┌─────────────┐
│ VOTRE SERVEUR │ │ E-PAY │ │ CLIENT │
└────────┬────────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
│ 1. POST /checkout-sessions │
│─────────────────────>│ │
│ │ │
│ { checkout_url } │ │
│<─────────────────────│ │
│ │ │
│ 2. Rediriger vers checkout_url │
│─────────────────────────────────────────>│
│ │ │
│ │ 3. Client paie │
│ │<───────────────────│
│ │ │
│ 4. Webhook (paiement complété) │
│<─────────────────────│ │
│ │ │
│ │ 5. Redirection │
│ │───────────────────>│
│ │ │
ÉTAPE 1 : CRÉER UNE SESSION DE PAIEMENT
Depuis votre serveur backend, appelez l'API pour créer une session :
curl -X POST https://app.epaybf.com/api/v1/checkout-sessions \
-H "Authorization: Bearer pk_live_VOTRE_CLE_API" \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"currency": "XOF",
"merchant_order_id": "CMD-001",
"merchant_webhook_url": "https://votresite.com/webhooks/epay",
"success_redirect_url": "https://votresite.com/success",
"cancel_redirect_url": "https://votresite.com/cancel"
}'
Réponse :
{
"session_id": "cs_abc123",
"status": "PENDING",
"checkout_url": "https://app.epaybf.com/checkout/cs_abc123",
"expires_at": "2026-01-21T14:00:00Z"
}
ÉTAPE 2 : REDIRIGER LE CLIENT
Redirigez votre client vers le checkout_url reçu. C'est tout ! Notre page de paiement hébergée gère :
- Le choix de l'opérateur (Orange Money / Moov Money)
- La saisie du numéro de téléphone
- La demande et saisie de l'OTP
- La confirmation du paiement
// PHP - Exemple de redirection
header('Location: ' . $response['checkout_url']);
exit;
// JavaScript - Exemple de redirection
window.location.href = response.checkout_url;
ÉTAPE 3 : RECEVOIR LE WEBHOOK
Quand le paiement est complété (ou échoue), E-PAY envoie une notification à votre merchant_webhook_url :
{
"event": "payment.updated",
"session_id": "cs_abc123",
"status": "COMPLETED",
"payment_reference": "pay_xyz789",
"amount": 5000,
"currency": "XOF",
"merchant_order_id": "CMD-001"
}
Mettez à jour votre commande en fonction du statut reçu.
EXEMPLE COMPLET (PHP)
<?php
// ============================================
// FICHIER: create-payment.php
// Appelé quand le client clique sur "Payer"
// ============================================
$apiKey = 'pk_live_VOTRE_CLE_API';
$apiUrl = 'https://app.epaybf.com/api/v1/checkout-sessions';
// Données de la commande
$orderData = [
'amount' => 5000, // 5000 XOF
'currency' => 'XOF',
'merchant_order_id' => 'CMD-' . uniqid(),
'description' => 'Commande sur MaBoutique',
'merchant_webhook_url' => 'https://votresite.com/webhooks/epay.php',
'success_redirect_url' => 'https://votresite.com/success.php',
'cancel_redirect_url' => 'https://votresite.com/cancel.php',
];
// Appel API
$ch = curl_init($apiUrl);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($orderData),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
// Sauvegarder la session dans votre base de données
saveOrder($orderData['merchant_order_id'], $response['session_id']);
// Rediriger vers la page de paiement E-PAY
header('Location: ' . $response['checkout_url']);
exit;
<?php
// ============================================
// FICHIER: webhooks/epay.php
// Reçoit les notifications de paiement
// ============================================
$payload = file_get_contents('php://input');
$data = json_decode($payload, true);
// TODO: Vérifier la signature (voir section Webhooks)
$orderId = $data['merchant_order_id'];
$status = $data['status'];
if ($status === 'COMPLETED') {
// Paiement réussi !
markOrderAsPaid($orderId, $data['payment_reference']);
sendConfirmationEmail($orderId);
} elseif ($status === 'FAILED') {
// Paiement échoué
markOrderAsFailed($orderId);
}
// Toujours répondre 200 OK
http_response_code(200);
echo 'OK';
C'EST TOUT !
Notre page de paiement hébergée gère automatiquement tout le processus de paiement (choix de l'opérateur, saisie du numéro, OTP, confirmation).
Récapitulatif :
| Votre serveur fait | E-PAY fait |
|---|---|
1. POST /checkout-sessions |
Affiche la page de paiement |
2. Redirige vers checkout_url |
Gère OTP et confirmation |
| 3. Reçoit le webhook | Redirige le client vers votre site |
Authentification
# Exemple d'authentification
curl -X GET https://app.epaybf.com/api/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
- 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 (si configuré)
MOOV MONEY
- 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 (si configuré)
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://app.epaybf.com/api/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 ou moov |
| 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://app.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://app.epaybf.com/api/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",
"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 |
Webhooks (Facultatif)
Les webhooks sont facultatifs mais recommandés. E-PAY peut envoyer des notifications à 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.
Alternative sans webhook : Vous pouvez utiliser l'endpoint GET /checkout-sessions/{id} pour vérifier le statut du paiement après la redirection du client.
EXEMPLE DE PAYLOAD
{
"event": "payment.updated",
"session_id": "cs_01JABCDXYZ",
"payment_reference": "pay_01JPAIDXYZ",
"status": "COMPLETED",
"amount": 5000,
"currency": "XOF",
"provider": "orange",
"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) |
| 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 |
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.
