Documentation / Démarrer / Démarrage rapide
Démarrage rapide
Encaissez votre premier paiement mobile money : créez une session, redirigez votre client vers la page ImpactPay, puis confirmez le paiement côté serveur grâce au webhook.
URL de base
https://www.impactpay.pro/api/v1
Authentification
Toutes les requêtes API doivent inclure vos clés dans les headers HTTP.
Vos clés sont disponibles dans Console → Clés API.
# Exemple avec cURL
curl -X POST "https://www.impactpay.pro/api/v1/session" \
-H "X-API-Key: votre_api_key" \
-H "X-API-Secret: votre_api_secret" \
-H "Content-Type: application/json"
Ne partagez jamais votre X-API-Secret publiquement (frontend, dépôts Git publics).
Toutes les requêtes API doivent être effectuées depuis votre serveur backend.
Créer une session
POST
/api/v1/session
Crée une session de paiement. C'est la première étape obligatoire pour les deux modes d'intégration :
- Guichet hébergé — redirigez votre client vers checkout_url
- API directe — gardez le session_id et appelez POST /api/v1/pay
Paramètres
| Champ | Type | Requis | Description |
|---|---|---|---|
| amount | number | ✓ | Montant (ex : 5000 = 5 000 XOF) |
| currency | string(3) | — | Code ISO 4217. Défaut : XOF |
| description | string | ✓ | Libellé affiché au client (max 500 car.) |
| payer.name | string | — | Nom du payeur (pré-rempli sur le guichet) |
| payer.email | string | — | Email du payeur |
| payer.phone | string | — | Téléphone du payeur (pré-rempli) |
| allowed_methods | array | — | Obsolète, ignoré. Le guichet propose tous les moyens de paiement actifs dans le pays du payeur. |
| success_url | URL | ✓ | Redirection après paiement réussi |
| failure_url | URL | ✓ | Redirection après paiement échoué |
| notify_url | URL | ✓ | URL de réception du webhook de confirmation |
| metadata | object | — | Données libres renvoyées dans le webhook |
| expires_in | integer | — | Durée de validité en minutes (5–1440). Défaut : 30 |
Exemple de requête
{
"amount": 5000,
"currency": "XOF",
"description": "Commande #1042",
"payer": {
"name": "Kouassi Jean",
"phone": "0700000000"
},
"success_url": "https://monsite.com/paiement/succes",
"failure_url": "https://monsite.com/paiement/echec",
"notify_url": "https://monsite.com/webhook/paiement",
"metadata": { "order_id": "1042" },
"expires_in": 30
}
Réponse 201
{
"success": true,
"data": {
"session_id": "aBcDeFgHiJkLmNoPqR12",
"checkout_url": "https://www.impactpay.pro/pay/aBcDeFgHiJkLmNoPqR12",
"amount": 5000.0,
"currency": "XOF",
"status": "pending",
"expires_at": "2026-04-16T10:30:00+00:00",
"created_at": "2026-04-16T10:00:00+00:00"
}
}
Mode guichet : redirigez votre client vers checkout_url.
Mode API directe : conservez le session_id et appelez POST /api/v1/pay. Le notify_url défini ici recevra la confirmation de paiement.
Note : success_url et failure_url sont ignorés en mode API directe — vous gérez vous-même la redirection côté client.
Mode API directe : conservez le session_id et appelez POST /api/v1/pay. Le notify_url défini ici recevra la confirmation de paiement.
Note : success_url et failure_url sont ignorés en mode API directe — vous gérez vous-même la redirection côté client.
Consulter une session
GET
/api/v1/session/{session_id}
Retourne l'état actuel d'une session. Seules vos propres sessions sont accessibles.
Utile en mode API directe pour interroger le statut d'un paiement en attente si votre notify_url n'a pas été appelée (polling de secours).
Utile en mode API directe pour interroger le statut d'un paiement en attente si votre notify_url n'a pas été appelée (polling de secours).
Valeurs de status
| Valeur | Description |
|---|---|
| pending | En attente de paiement |
| completed | Paiement confirmé |
| failed | Paiement échoué ou annulé |
| expired | Session expirée sans paiement |
Réponse 200
{
"success": true,
"data": {
"session_id": "aBcDeFgHiJkLmNoPqR12",
"amount": 5000.0,
"currency": "XOF",
"description": "Commande #1042",
"status": "completed",
"payer_name": "Kouassi Jean",
"payer_phone": "0700000000",
"provider": "orange_money",
"metadata": { "order_id": "1042" },
"paid_at": "2026-04-16T10:12:00+00:00",
"created_at": "2026-04-16T10:00:00+00:00"
}
}
Recommandation API directe : ne faites pas de polling intensif. Attendez le webhook sur votre notify_url — c'est la source de vérité. Utilisez cet endpoint uniquement si le webhook n'est pas arrivé après un délai raisonnable (ex : 60 secondes).
Consulter une transaction
GET
/api/v1/transaction/{transaction_id}
Retourne l'état d'une tentative de paiement précise. Seules les transactions de vos propres sessions sont accessibles.
Le transaction_id est renvoyé par POST /api/v1/pay et inclus dans le webhook envoyé à votre notify_url. Une session peut contenir plusieurs transactions (une par tentative).
Le transaction_id est renvoyé par POST /api/v1/pay et inclus dans le webhook envoyé à votre notify_url. Une session peut contenir plusieurs transactions (une par tentative).
Valeurs de status
| Valeur | Description |
|---|---|
| pending | En attente de confirmation du provider |
| completed | Paiement confirmé |
| failed | Paiement refusé ou échoué |
| cancelled | Transaction annulée (bloquée trop longtemps en attente) |
Réponse 200
{
"success": true,
"data": {
"transaction_id": "9b1f6c2e-4d3a-4f7e-9a51-2c8e7d0b4f13",
"session_id": "aBcDeFgHiJkLmNoPqR12",
"amount": 5000.0,
"currency": "XOF",
"status": "completed",
"provider": "orange_money",
"provider_ref": "OM-48213377",
"phone": "0700000000",
"session_status": "completed",
"paid_at": "2026-04-16T10:12:00+00:00",
"created_at": "2026-04-16T10:00:00+00:00",
"updated_at": "2026-04-16T10:12:00+00:00"
}
}
Réponse 404
{
"success": false,
"error": { "code": "TRANSACTION_NOT_FOUND", "message": "Transaction introuvable." }
}
Solde & statistiques
GET
/api/v1/merchant/balance
Retourne votre solde disponible (net après frais) et les statistiques globales de vos transactions.
Réponse 200
{
"success": true,
"data": {
"balance": 47350.00,
"currency": "XOF",
"transactions": {
"total": 120,
"completed": 98,
"pending": 5,
"failed": 17
},
"volume_completed": 490000.00
}
}
Liste des transactions
GET
/api/v1/merchant/transactions
Retourne la liste paginée de vos sessions de paiement avec les montants nets après frais.
Paramètres query (optionnels)
| Paramètre | Type | Description |
|---|---|---|
| status | string | completed | pending | failed | expired |
| from | date | Date de début YYYY-MM-DD (inclusif) |
| to | date | Date de fin YYYY-MM-DD (inclusif) |
| per_page | integer | Résultats par page, 1–100. Défaut : 25 |
Réponse 200
{
"success": true,
"data": [
{
"session_id": "aBcDeFgHiJkLmNoPqR12",
"description": "Commande #1042",
"amount": 5000.0,
"currency": "XOF",
"status": "completed",
"payer_name": "Kouassi Jean",
"payer_phone": "0700000000",
"fee_total": 125.0,
"net_amount": 4875.0,
"created_at": "2026-04-16T10:00:00+00:00"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total": 98,
"last_page": 4
}
}
Demande de reversement
POST
/api/v1/withdrawal
Soumet une demande de reversement de fonds vers un numéro de téléphone mobile money.
Le montant est immédiatement débité de votre solde disponible et la demande est traitée
par l'équipe après validation.
Corps (JSON)
| Champ | Type | Requis | Description |
|---|---|---|---|
| method | string | ✓ | orange_money, mtn, moov, wave |
| phone | string | ✓ | Numéro de téléphone destinataire (max 20 car.) |
| amount | integer | ✓ | Montant en XOF, minimum 100 |
| note | string | — | Note optionnelle (max 500 car.) |
Exemple de requête
{
"method": "orange_money",
"phone": "0700000000",
"amount": 5000,
"note": "Reversement mensuel"
}
Réponse 201
{
"success": true,
"data": {
"withdrawal_id": "uuid-de-la-demande",
"amount": 5000.00,
"currency": "XOF",
"method": "orange_money",
"phone": "0700000000",
"status": "pending",
"note": "Reversement mensuel",
"created_at": "2026-04-28T10:00:00+00:00"
}
}
Codes d'erreur spécifiques
| HTTP | Code erreur | Description |
|---|---|---|
| 422 | METHOD_DISABLED | Méthode de reversement temporairement indisponible |
| 422 | INSUFFICIENT_BALANCE | Solde insuffisant pour couvrir ce montant |
Le montant est débité de votre solde dès la création de la demande.
En cas de rejet ou d'échec du reversement, le solde vous est automatiquement recrédité.
Paiement direct (API)
POST
/api/v1/pay
Déclenche un paiement directement sans rediriger votre client vers le guichet hébergé.
À utiliser si vous gérez votre propre interface de paiement.
Prérequis : créer d'abord une session via POST /api/v1/session, puis passer le session_id retourné.
Prérequis : créer d'abord une session via POST /api/v1/session, puis passer le session_id retourné.
Corps (JSON)
| Champ | Type | Requis | Description |
|---|---|---|---|
| session_id | string | ✓ | Identifiant de session créée au préalable |
| method | string | ✓ | orange_money, mtn, moov, wave, free_money… — doit être proposé dans le pays |
| country | string(2) | — | Pays du payeur (CI, SN…). Défaut : pays de la session, sinon CI |
| phone | string | ✓ | Numéro de téléphone du payeur |
| name | string | — | Nom du payeur |
| otp | string | Selon le moyen | Code OTP saisi par le client. Obligatoire seulement pour les moyens à parcours « OTP » (aujourd'hui Orange Money en Côte d'Ivoire), ignoré sinon |
Exemple — Orange Money
{
"session_id": "aBcDeFgHiJkLmNoPqR12",
"method": "orange_money",
"phone": "0700000000",
"name": "Kouassi Jean",
"otp": "123456"
}
Exemple — MTN / Moov (sans OTP)
{
"session_id": "aBcDeFgHiJkLmNoPqR12",
"method": "mtn",
"phone": "0500000000",
"name": "Kouassi Jean"
}
Exemple — Wave
{
"session_id": "aBcDeFgHiJkLmNoPqR12",
"method": "wave",
"phone": "0700000000",
"name": "Kouassi Jean"
}
Réponse 200 — En attente (Orange Money / MTN / Moov)
{
"success": true,
"session_id": "aBcDeFgHiJkLmNoPqR12",
"transaction_id": "9b1f6c2e-4d3a-4f7e-9a51-2c8e7d0b4f13",
"status": "pending",
"message": "Confirmez le paiement sur votre téléphone."
}
Réponse 200 — Redirection Wave
{
"success": true,
"session_id": "aBcDeFgHiJkLmNoPqR12",
"transaction_id": "9b1f6c2e-4d3a-4f7e-9a51-2c8e7d0b4f13",
"status": "redirect",
"redirect_url": "https://pay.wave.com/c/cos-xxx"
}
Notes importantes
- OTP : requis uniquement quand le parcours du moyen de paiement est « OTP » dans le pays (aujourd'hui Orange Money en Côte d'Ivoire : le client compose #144*82# pour recevoir son code). Sinon, une erreur OTP_REQUIRED est renvoyée.
- Moyens disponibles : ils sont définis par pays par ImpactPay ; un nouvel opérateur activé est accepté sans changement de votre intégration.
- Wave : redirigez votre client vers redirect_url pour qu'il confirme le paiement.
- Confirmation : le statut final (complété ou échoué) est toujours transmis via le webhook vers votre notify_url.
- Une session ne peut être payée qu'une seule fois. Créez une nouvelle session pour chaque tentative.
Codes d'erreur spécifiques
| Code HTTP | Code erreur | Description |
|---|---|---|
| 404 | SESSION_NOT_FOUND | Session introuvable ou n'appartient pas à ce marchand |
| 422 | SESSION_INVALID | Session déjà payée ou expirée |
| 422 | COUNTRY_NOT_AVAILABLE | Aucun moyen de paiement disponible dans ce pays |
| 422 | METHOD_DISABLED | Moyen de paiement non proposé dans ce pays |
| 422 | OTP_REQUIRED | Code OTP manquant pour un moyen à parcours « OTP » |
| 422 | PAYMENT_FAILED | Échec côté partenaire de paiement |
Webhook de confirmation
Lorsqu'un paiement est confirmé ou échoué, le guichet envoie automatiquement une requête POST vers votre notify_url.
Headers reçus
| Header | Description |
|---|---|
| Content-Type | application/json |
| X-Timestamp | Timestamp Unix de l'envoi |
| X-Signature | HMAC-SHA256 du corps JSON signé avec votre X-API-Secret |
Corps reçu
{
"event": "payment.completed",
"session_id": "aBcDeFgHiJkLmNoPqR12",
"status": "completed",
"amount": 5000.0,
"currency": "XOF",
"provider": "orange_money",
"payer_name": "Kouassi Jean",
"payer_phone": "0700000000",
"metadata": { "order_id": "1042" },
"transaction_id": "uuid-de-la-transaction",
"provider_ref": "ref-provider-001",
"paid_at": "2026-04-16T10:12:00+00:00"
}
Événements
| event | Description |
|---|---|
| payment.completed | Paiement confirmé — créditer la commande |
| payment.failed | Paiement échoué ou annulé |
| payment.pending | Paiement toujours en attente (re-notification) |
Vérification de signature (recommandé)
// PHP
$payload = file_get_contents('php://input');
$signature = hash_hmac('sha256', $payload, $apiSecret);
if (!hash_equals($signature, $_SERVER['HTTP_X_SIGNATURE'] ?? '')) {
http_response_code(401);
exit;
}
Votre endpoint notify_url doit répondre avec un code HTTP 2xx.
Aucune relance automatique n'est effectuée en cas d'échec.
Codes d'erreur
| HTTP | Code | Description |
|---|---|---|
| 401 | MISSING_CREDENTIALS | Headers X-API-Key ou X-API-Secret absents |
| 401 | INVALID_API_KEY | Clés invalides ou inactives |
| 404 | SESSION_NOT_FOUND | Session inexistante ou appartenant à un autre marchand |
| 422 | — | Erreur de validation — voir le champ errors |
Cycle de vie d'une transaction
Mode guichet hébergé
Votre serveur Guichet Client Provider
│ │ │ │
│ POST /session │ │ │
│─────────────────>│ │ │
│ checkout_url ◄───│ │ │
│ │ │ │
│ Redirige le client vers checkout_url │
│─────────────────────────────────────>│ │
│ │ Choix méthode │ │
│ │◄─────────────────│ │
│ │ Lance paiement ──────────────────── >│
│ │ │ Confirmation │
│ │◄─ Webhook interne ──────────────────│
│ │ │ │
│◄─ POST notify_url│ │ │
│ │ Redirige ──────────────────────────>│
│ │ success/failure_url │
Mode API directe
Votre serveur Guichet Client Provider
│ │ │ │
│ POST /session │ │ │
│ (+ notify_url) │ │ │
│─────────────────>│ │ │
│ session_id ◄─────│ │ │
│ │ │ │
│ Affiche votre propre interface de paiement │
│─────────────────────────────────────>│ │
│ │ Saisie téléphone + OTP (si Orange)│
│◄─────────────────────────────────────│ │
│ │ │ │
│ POST /pay │ │ │
│ (session_id, │ │ │
│ method, phone, │ │ │
│ otp?) │ │ │
│─────────────────>│ │ │
│ │ Lance paiement ──────────────────── >│
│ { status: │ │ │
│ "pending" } ◄──│ │ Confirmation │
│ │◄─ Webhook interne ──────────────────│
│ │ │ │
│◄─ POST notify_url│ │ │
│ │ │ │
│ Cas Wave : redirect_url retourné par POST /pay │
│─────────────────────────────────────>│ │
│ │ │ Confirme sur Wave │
│ │ │─────────────────>│
│ │◄─ Webhook interne ──────────────────│
│◄─ POST notify_url│ │ │
Dans les deux modes, le webhook vers notify_url est la source de vérité pour la confirmation de paiement.
Utilisez GET /api/v1/session/{id} uniquement comme vérification de secours si le webhook n'arrive pas.