Introduction
L'API CowemaPay vous permet d'accepter des paiements Mobile Money (MTN MoMo, Airtel Money) dans vos applications. L'API suit les conventions REST et retourne du JSON.
URL de base :
https://pay.cowema.org/api/v1
https://pay.cowema.org/api/v1 si vous travaillez en local.
openapi.json dans Bruno, Postman ou Insomnia. Ou utilisez le fichier .http directement dans VS Code (REST Client) ou JetBrains.
Demarrage rapide
1. Creez votre compte
Rendez-vous sur le tableau de bord et creez un compte. Vous serez invite a creer une organisation.
2. Creez une application
Dans le menu Applications, cliquez sur New application. Donnez-lui un nom et configurez vos URLs de webhook si necessaire.
3. Generez vos cles API
Sur la liste des applications, cliquez sur l'icone cle a cote de votre application, puis Cles API (test). Une modale affichera vos cles :
| Cle | Prefixe | Visibilite |
|---|---|---|
| Cle publique | pk_test_... | Visible a tout moment dans le dashboard |
| Cle secrete | sk_test_... | Affichee une seule fois a la generation |
4. Faites votre premier appel
Testez avec un paiement sandbox :
curl -X POST https://pay.cowema.org/api/v1/payments \
-H "Authorization: Bearer sk_test_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"country": "CG",
"phone_number": "054553499",
"provider": "mtn_momo"
}'
Le numero 054553499 simule un paiement reussi en sandbox.
Flow de paiement API
Authentification
Toutes les requetes API doivent inclure votre cle secrete dans le header Authorization.
Authorization: Bearer sk_test_votre_cle_secrete
sk_). Elle donne un acces complet a votre compte. Utilisez la cle publique (pk_) cote frontend.
| Type de cle | Prefixe | Usage |
|---|---|---|
| Cle publique test | pk_test_ | Identification cote client (sandbox) |
| Cle secrete test | sk_test_ | Requetes API (sandbox) |
| Cle publique live | pk_live_ | Identification cote client (production) |
| Cle secrete live | sk_live_ | Requetes API (production) |
Mode sandbox
Les cles sk_test_ activent automatiquement le mode sandbox. Aucun appel reel n'est fait aux fournisseurs. Utilisez ces numeros de test :
Creer un paiement
Initie une demande de paiement Mobile Money. Le client recevra une notification sur son telephone pour confirmer.
Idempotency-Key pour eviter les doublons en cas de retry. En savoir plus| Parametre | Type | Description | |
|---|---|---|---|
amount | integer | requis | Montant en unite minimale (ex: 5000 = 5 000 XAF) |
country | string | requis | Code pays ISO 2 lettres (ex: CG) |
currency | string | optionnel | Code devise ISO (ex: XAF) -- deduit automatiquement du pays |
phone_number | string | requis | Numero de telephone du payeur |
provider | string | requis | mtn_momo ou airtel_money |
metadata | object | optionnel | Donnees personnalisees (ex: order_id) |
curl -X POST https://pay.cowema.org/api/v1/payments \
-H "Authorization: Bearer sk_test_VOTRE_CLE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: votre-cle-unique" \
-d '{
"amount": 5000,
"country": "CG",
"phone_number": "054553499",
"provider": "mtn_momo",
"metadata": {"order_id": "ORD-123"}
}'
201 -- Paiement cree
{
"data": {
"id": "9f8a2b3c-...",
"type": "collection",
"provider": "mtn_momo",
"amount": 5000,
"currency": "XAF",
"country": "CG",
"phone_number": "054553499",
"status": "pending",
"environment": "test",
"metadata": { "order_id": "ORD-123" },
"created_at": "2026-03-29T18:00:00+00:00"
}
}
401 -- Non authentifie
{
"error": "Missing API key.",
"code": "missing_api_key"
}
422 -- Erreur de validation
{
"message": "The amount field is required.",
"errors": {
"amount": ["The amount field is required."],
"provider": ["The selected provider is invalid."]
}
}
429 -- Rate limit depasse
{
"message": "Too Many Attempts."
}
Voir un paiement
Recupere les details d'un paiement par son identifiant.
curl https://pay.cowema.org/api/v1/payments/PAYMENT_UUID \ -H "Authorization: Bearer sk_test_VOTRE_CLE"
200 -- Paiement trouve
{
"data": {
"id": "9f8a2b3c-...",
"type": "collection",
"status": "successful",
// ... memes champs que la creation
}
}
404 -- Transaction introuvable
{
"error": "Transaction not found.",
"code": "not_found"
}
Lister les paiements
Retourne la liste paginee de vos paiements. Filtrable par statut, fournisseur et environnement.
| Parametre | Type | Description | |
|---|---|---|---|
status | string | filtre | pending, processing, successful, failed, cancelled |
provider | string | filtre | mtn_momo ou airtel_money |
environment | string | filtre | live ou test |
per_page | integer | filtre | Nombre de resultats (max 100) |
curl "https://pay.cowema.org/api/v1/payments?status=successful&per_page=10" \ -H "Authorization: Bearer sk_test_VOTRE_CLE"
200 -- Liste paginee
{
"data": [
{
"id": "9f8a2b3c-...",
"type": "collection",
"amount": 5000,
"status": "successful",
// ...
},
// ... autres transactions
],
"links": {
"first": "...?page=1",
"last": "...?page=3",
"prev": null,
"next": "...?page=2"
},
"meta": {
"current_page": 1,
"per_page": 10,
"total": 25,
"last_page": 3
}
}
422 -- Filtre invalide
{
"message": "The selected status is invalid.",
"errors": {
"status": ["The selected status is invalid."]
}
}
Creer un remboursement
Rembourse un paiement reussi. Le montant est reverse sur le compte Mobile Money du payeur.
Idempotency-Key pour eviter les doublons en cas de retry. En savoir plus| Parametre | Type | Description | |
|---|---|---|---|
payment_id | string | requis | UUID du paiement a rembourser |
amount | integer | requis | Montant a rembourser |
curl -X POST https://pay.cowema.org/api/v1/refunds \
-H "Authorization: Bearer sk_test_VOTRE_CLE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: votre-cle-unique" \
-d '{
"payment_id": "PAYMENT_UUID",
"amount": 5000
}'
201 -- Remboursement cree
{
"data": {
"id": "b7c4e1f2-...",
"type": "refund",
"status": "pending",
// ... memes champs qu'une transaction
}
}
422 -- Transaction non remboursable
{
"error": "Original transaction not found or not refundable.",
"code": "not_refundable"
}
Voir un remboursement
curl https://pay.cowema.org/api/v1/refunds/REFUND_UUID \ -H "Authorization: Bearer sk_test_VOTRE_CLE"
200 -- Remboursement trouve
{
"data": {
"id": "b7c4e1f2-...",
"type": "refund",
"provider": "mtn_momo",
"amount": 5000,
"currency": "XAF",
"status": "successful",
"environment": "test",
"created_at": "2026-03-29T18:05:00+00:00"
}
}
404 -- Remboursement introuvable
{
"error": "Refund not found.",
"code": "not_found"
}
Creer une session Checkout
Cree une session de paiement hebergee. Redirigez votre client vers l'URL retournee.
Idempotency-Key pour eviter les doublons en cas de retry. En savoir plus| Parametre | Type | Description | |
|---|---|---|---|
amount | integer | requis | Montant |
country | string | requis | Code pays ISO 2 lettres (ex: CG) |
currency | string | optionnel | Code devise -- deduit du pays si omis |
success_url | string | requis | URL de redirection apres succes |
cancel_url | string | requis | URL de redirection si annule |
description | string | optionnel | Description affichee au client |
metadata | object | optionnel | Donnees personnalisees (ex: order_id) |
curl -X POST https://pay.cowema.org/api/v1/checkout/sessions \
-H "Authorization: Bearer sk_test_VOTRE_CLE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: votre-cle-unique" \
-d '{
"amount": 10000,
"country": "CG",
"description": "Abonnement Premium",
"success_url": "https://votresite.com/success",
"cancel_url": "https://votresite.com/cancel"
}'
201 -- Session creee
{
"data": {
"id": "cs_abc123...",
"amount": 10000,
"currency": "XAF",
"country": "CG",
"url": "https://pay.cowema.org/checkout/cs_abc123",
"status": "open",
"expires_at": "2026-03-29T19:00:00+00:00"
}
}
422 -- Erreur de validation
{
"message": "The success url field is required.",
"errors": {
"success_url": ["The success url field is required."]
}
}
Voir une session checkout
Recupere le statut d'une session checkout. Utilisez cet endpoint pour verifier cote serveur si le paiement a abouti.
curl https://pay.cowema.org/api/v1/checkout/sessions/SESSION_UUID \ -H "Authorization: Bearer sk_test_VOTRE_CLE"
200 -- Session trouvee
{
"data": {
"id": "cs_abc123...",
"amount": 10000,
"currency": "XAF",
"description": "Abonnement Premium",
"url": "https://pay.cowema.org/checkout/cs_abc123",
"status": "completed",
"expires_at": "2026-03-29T19:00:00+00:00",
"metadata": null,
"created_at": "2026-03-29T18:00:00+00:00"
}
}
404 -- Session introuvable
{
"error": "Checkout session not found.",
"code": "not_found"
}
Flow d'integration Checkout
1. Creez une session cote serveur
Appelez POST /api/v1/checkout/sessions depuis votre backend avec votre cle secrete.
2. Redirigez le client
Envoyez votre client vers l'URL data.url retournee dans la reponse.
3. Le client paie
Sur la page CowemaPay, il choisit son fournisseur (MTN/Airtel), entre son numero, et confirme.
4. Redirection automatique
Apres paiement, le client est redirige vers votre success_url ou cancel_url.
5. Verifiez cote serveur
Utilisez GET /api/v1/checkout/sessions/{id} ou les webhooks pour confirmer le paiement.
Diagramme
Creer un decaissement
Initie un transfert d'argent vers un compte Mobile Money. Le montant est debite de votre solde marchand.
Idempotency-Key pour eviter les doublons en cas de retry. En savoir plus| Parametre | Type | Description | |
|---|---|---|---|
amount | integer | requis | Montant en unite minimale (ex: 5000 = 5 000 XAF) |
currency | string | requis | Code devise ISO (ex: XAF) |
country | string | requis | Code pays ISO 2 lettres (ex: CG) |
provider | string | requis | mtn_momo ou airtel_money |
phone_number | string | requis | Numero de telephone du beneficiaire |
metadata | object | optionnel | Donnees personnalisees (ex: order_id) |
Statuts d'un decaissement
| Statut | Description |
|---|---|
pending | Decaissement cree, en attente de validation |
approved | Decaissement approuve, pret a etre traite |
processing | Transfert en cours aupres du fournisseur |
completed | Transfert effectue avec succes |
failed | Le transfert a echoue |
rejected | Decaissement rejete |
curl -X POST https://pay.cowema.org/api/v1/payouts \
-H "Authorization: Bearer sk_test_VOTRE_CLE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: votre-cle-unique" \
-d '{
"amount": 5000,
"currency": "XAF",
"country": "CG",
"provider": "mtn_momo",
"phone_number": "066000001"
}'
201 -- Decaissement cree
{
"data": {
"id": "d4e5f6a7-...",
"type": "payout",
"provider": "mtn_momo",
"amount": 5000,
"currency": "XAF",
"country": "CG",
"phone_number": "066000001",
"status": "pending",
"environment": "test",
"metadata": null,
"created_at": "2026-03-31T10:00:00+00:00"
}
}
422 -- Solde insuffisant
{
"error": "Insufficient balance for this payout.",
"code": "insufficient_balance"
}
422 -- Erreur de validation
{
"message": "The amount field is required.",
"errors": {
"amount": ["The amount field is required."]
}
}
Lister les decaissements
Retourne la liste paginee de vos decaissements. Filtrable par statut.
| Parametre | Type | Description | |
|---|---|---|---|
status | string | filtre | pending, approved, processing, completed, failed, rejected |
per_page | integer | filtre | Nombre de resultats (max 100) |
curl "https://pay.cowema.org/api/v1/payouts?status=completed&per_page=10" \ -H "Authorization: Bearer sk_test_VOTRE_CLE"
200 -- Liste paginee
{
"data": [
{
"id": "d4e5f6a7-...",
"type": "payout",
"amount": 5000,
"status": "completed",
// ...
}
],
"links": { // ... pagination },
"meta": {
"current_page": 1,
"per_page": 10,
"total": 8,
"last_page": 1
}
}
Voir un decaissement
Recupere les details d'un decaissement par son identifiant.
curl https://pay.cowema.org/api/v1/payouts/PAYOUT_UUID \ -H "Authorization: Bearer sk_test_VOTRE_CLE"
200 -- Decaissement trouve
{
"data": {
"id": "d4e5f6a7-...",
"type": "payout",
"provider": "mtn_momo",
"amount": 5000,
"currency": "XAF",
"country": "CG",
"phone_number": "066000001",
"status": "completed",
"environment": "test",
"created_at": "2026-03-31T10:00:00+00:00"
}
}
404 -- Decaissement introuvable
{
"error": "Payout not found.",
"code": "not_found"
}
Solde marchand
Retourne le solde disponible de votre compte marchand, ventile par devise.
curl https://pay.cowema.org/api/v1/merchant/balance \ -H "Authorization: Bearer sk_test_VOTRE_CLE"
200 -- Solde recupere
{
"data": [
{
"currency": "XAF",
"available_balance": 15885960,
"pending_balance": 0
}
]
}
Idempotence
Tous les endpoints POST acceptent un header Idempotency-Key pour eviter les doublons en cas de retry reseau.
Idempotency-Key: votre-cle-unique-uuid
Fonctionnement
| Scenario | Comportement |
|---|---|
| Meme cle + meme body | Retourne la reponse mise en cache (validite 30 jours) |
| Meme cle + body different | Retourne une erreur 409 Conflict |
| Pas de header | Requete traitee normalement (pas d'idempotence) |
curl -X POST https://pay.cowema.org/api/v1/payments \
-H "Authorization: Bearer sk_test_VOTRE_CLE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{
"amount": 5000,
"country": "CG",
"phone_number": "054553499",
"provider": "mtn_momo"
}'
409 -- Conflit d'idempotence
{
"error": "A request with this idempotency key already exists with a different body.",
"code": "idempotency_conflict"
}
Idempotency-Key est optionnel. Utilisez un UUID v4 unique par requete pour garantir l'unicite.
Securite
CowemaPay propose plusieurs mecanismes de securite configurables par application.
IP Whitelisting
Vous pouvez restreindre les appels API a une liste d'adresses IP autorisees. Configurez les IPs dans le dashboard, sur la page d'edition de votre application.
403 -- IP non autorisee
{
"error": "Votre adresse IP n'est pas autorisée pour cette application.",
"code": "ip_not_whitelisted"
}
Rate Limiting
Par defaut, l'API autorise 100 requetes par minute par application. Cette limite est configurable par organisation.
| Header | Description |
|---|---|
X-RateLimit-Limit | Nombre maximum de requetes par minute |
X-RateLimit-Remaining | Nombre de requetes restantes |
Retry-After | Secondes avant la prochaine fenetre (si limite atteinte) |
KYC Gate
Le mode live necessite une verification KYC valide pour votre organisation. Les cles sk_live_ sont inutilisables tant que le KYC n'est pas approuve.
403 -- KYC requis
{
"error": "La vérification KYC est requise pour utiliser le mode live.",
"code": "kyc_verification_required"
}
Webhooks sortants
CowemaPay envoie des notifications HTTP (webhooks) vers votre webhook_url a chaque changement de statut d'un paiement ou d'un decaissement.
Signature
Chaque webhook inclut un header X-CowemaPay-Signature contenant un HMAC-SHA256 du body brut, signe avec votre webhook_secret.
// Verifiez toujours la signature avant de traiter l'evenement $payload = file_get_contents('php://input'); $signature = $_SERVER['HTTP_X_COWEMAPAY_SIGNATURE']; $secret = 'votre_webhook_secret'; $expected = hash_hmac('sha256', $payload, $secret); if (!hash_equals($expected, $signature)) { http_response_code(401); exit('Signature invalide'); } $event = json_decode($payload, true); // Traitez l'evenement...
Types d'evenements
| Evenement | Description |
|---|---|
payment.successful | Un paiement a ete confirme |
payment.failed | Un paiement a echoue |
refund.successful | Un remboursement a ete confirme |
refund.failed | Un remboursement a echoue |
payout.completed | Un decaissement a ete effectue |
payout.failed | Un decaissement a echoue |
Politique de retry
Si votre serveur ne repond pas avec un code 2xx, CowemaPay reessaie jusqu'a 3 fois avec un delai croissant :
| Tentative | Delai |
|---|---|
| 1er retry | 60 secondes |
| 2e retry | 5 minutes |
| 3e retry | 30 minutes |
Payload exemple
// Headers Content-Type: application/json X-CowemaPay-Signature: a1b2c3d4e5... X-CowemaPay-Event: payment.successful // Body { "event": "payment.successful", "data": { "id": "9f8a2b3c-...", "type": "collection", "amount": 5000, "currency": "XAF", "country": "CG", "phone_number": "054553499", "provider": "mtn_momo", "status": "successful", "environment": "test", "metadata": { "order_id": "ORD-123" }, "created_at": "2026-03-29T18:00:00+00:00" }, "timestamp": "2026-03-29T18:00:15+00:00" }
X-CowemaPay-Signature avant de traiter un webhook. Ne faites jamais confiance au contenu sans verification.
Solde fournisseur
Interroge directement le solde aupres du fournisseur Mobile Money.
curl "https://pay.cowema.org/api/v1/balance?provider=mtn_momo" \ -H "Authorization: Bearer sk_test_VOTRE_CLE"
200 -- Solde recupere
{
"data": {
"available": 1000000,
"currency": "XAF"
}
}
422 -- Fournisseur invalide
{
"message": "The selected provider is invalid.",
"errors": {
"provider": ["The selected provider is invalid."]
}
}
Webhooks
CowemaPay envoie des webhooks a l'URL configuree dans votre application lorsqu'un evenement se produit.
Configuration
Dans le dashboard, editez votre application et renseignez l'URL du webhook. Un webhook_secret est genere automatiquement -- vous le trouverez sur la page d'edition de l'application, dans le champ Secret du webhook.
Evenements
| Evenement | Description |
|---|---|
payment.successful | Un paiement a ete confirme |
payment.failed | Un paiement a echoue |
refund.successful | Un remboursement a ete confirme |
refund.failed | Un remboursement a echoue |
Verification de la signature
Chaque webhook inclut un header X-CowemaPay-Signature contenant un HMAC SHA-256 du body avec votre webhook_secret.
// Verifiez la signature du webhook $payload = file_get_contents('php://input'); $signature = $_SERVER['HTTP_X_COWEMAPAY_SIGNATURE']; $secret = 'votre_webhook_secret'; $expected = hash_hmac('sha256', $payload, $secret); if (hash_equals($expected, $signature)) { // Webhook valide $event = json_decode($payload, true); // Traitez l'evenement... }
Payload complet
Voici un exemple de payload envoye par CowemaPay :
// Headers Content-Type: application/json X-CowemaPay-Signature: a1b2c3d4e5... X-CowemaPay-Event: payment.successful // Body { "event": "payment.successful", "data": { "id": "9f8a2b3c-...", "type": "collection", "amount": 5000, "currency": "XAF", "country": "CG", "phone_number": "054553499", "provider": "mtn_momo", "status": "successful", "environment": "test", "metadata": { "order_id": "ORD-123" }, "created_at": "2026-03-29T18:00:00+00:00" }, "timestamp": "2026-03-29T18:00:15+00:00" }
Retries
Si votre serveur ne repond pas avec un code 2xx, CowemaPay reessaie jusqu'a 3 fois avec un delai croissant : 1 minute, 5 minutes, 30 minutes.
Erreurs
L'API utilise les codes HTTP standards :
| Code | Description |
|---|---|
200 | Succes |
201 | Ressource creee |
401 | Cle API manquante ou invalide |
403 | Acces interdit (IP non autorisee, KYC requis) |
404 | Ressource introuvable |
409 | Conflit d'idempotence |
422 | Erreur de validation / solde insuffisant |
429 | Trop de requetes (rate limit) |
500 | Erreur serveur |
{
"message": "The amount field is required.",
"errors": {
"amount": ["The amount field is required."]
}
}