Download OpenAPI specification:
Accepter les paiements PI-SPI (demandes de paiement) depuis un site ou une application.
API marchand de CajouPay. Ce contrat est la source de vérité : le code Java du backend et le client TypeScript sont générés à partir de lui.
Authorization: Bearer <clé secrète>. La clé détermine l'environnement :
sk_test_… (mode test, simulateur) ou sk_live_… (production).32500 signifie 32 500 FCFA.2026-10-11T17:42:08Z).POST /payments accepte l'en-tête Idempotency-Key. Même clé et même corps :
même réponse. Même clé et corps différent : erreur 409 idempotency_key_reused. Les clés sont
conservées 24 heures.tx_id. Un refus ou une expiration de tentative ne change
pas le statut du paiement tant qu'un nouvel essai reste possible.amount - fee_amount).
Le solde est retiré vers le compte de retrait du marchand, automatiquement chaque jour ou à
la demande (POST /payouts).duplicate,
n'est jamais créditée au marchand et est remboursée automatiquement à l'acheteur.| Alias | Comportement du simulateur |
|---|---|
+225 0000000001 |
accepte et paie immédiatement |
+225 0000000002 |
refuse |
+225 0000000003 |
ignore, la demande expire |
+225 0000000004 |
accepte et paiera plus tard (déclenchable depuis le tableau de bord) |
+225 0000000005 |
alias inconnu (erreur alias_unknown) |
Crée un paiement et renvoie l'URL de la page de paiement hébergée (checkout_url) vers
laquelle rediriger l'acheteur. Si customer_alias est fourni, la demande de paiement part
immédiatement vers la banque de l'acheteur et la page de paiement s'ouvre directement sur
l'écran d'attente.
| Idempotency-Key | string [ 1 .. 255 ] characters Clé unique choisie par le marchand (UUID recommandé), conservée 24 heures. |
| amount required | integer <int64> (Amount) >= 1 Montant en francs CFA, entier (pas de décimales). |
| currency | string (Currency) Default: "XOF" Value: "XOF" Devise. Seul le franc CFA (XOF) est accepté. |
| mode | string (PaymentMode) Default: "immediate" Enum: "immediate" "on_delivery"
|
| expires_at | string or null <date-time> Date limite de paiement. Obligatoire si |
| reference | string or null <= 100 characters Référence de commande du marchand, affichée à l'acheteur. |
| description | string or null <= 140 characters Motif affiché à l'acheteur et transmis à sa banque. |
| customer_alias | string or null <= 40 characters Alias PI-SPI de l'acheteur, s'il est déjà connu. La demande part immédiatement. Deux formats sont acceptés :
|
| return_url required | string <uri> Page du marchand où revient l'acheteur après le paiement. |
| cancel_url | string or null <uri> Page du marchand où revient l'acheteur s'il abandonne. |
object (Metadata) <= 20 properties Paires clé-valeur libres du marchand (20 clés maximum, valeurs de 500 caractères maximum). |
{- "amount": 32500,
- "currency": "XOF",
- "mode": "immediate",
- "reference": "CMD-20481",
- "description": "Commande Awa Mode",
- "metadata": {
- "order_id": "20481"
}
}{- "id": "pay_8Kq2xVt41N",
- "object": "payment",
- "status": "created",
- "amount": 32500,
- "currency": "XOF",
- "fee_amount": null,
- "net_amount": null,
- "mode": "immediate",
- "reference": "CMD-20481",
- "description": "Commande Awa Mode",
- "tx_id": null,
- "payer_alias_masked": null,
- "expires_at": "2026-10-11T17:47:00Z",
- "created_at": "2026-10-11T17:42:00Z",
- "livemode": false,
- "metadata": {
- "order_id": "20481"
}, - "attempts": [ ]
}Liste paginée, du plus récent au plus ancien.
| status | string (PaymentStatus) Enum: "created" "request_sent" "accepted_deferred" "succeeded" "declined" "expired" "canceled" "failed" Ne renvoyer que les paiements dans ce statut. |
| reference | string <= 100 characters Référence de commande du marchand (correspondance exacte). |
| created_from | string <date-time> Créés à partir de cette date (incluse). |
| created_to | string <date-time> Créés avant cette date (exclue). |
| limit | integer [ 1 .. 100 ] Default: 20 Nombre de résultats par page. |
| starting_after | string Identifiant du dernier élément de la page précédente. |
{- "object": "list",
- "data": [
- {
- "id": "pay_8Kq2xVt41N",
- "object": "payment",
- "status": "created",
- "amount": 32500,
- "currency": "XOF",
- "fee_amount": 0,
- "net_amount": 0,
- "mode": "immediate",
- "reference": "string",
- "description": "string",
- "tx_id": "CJT0KQ3VZ8M2XH7RP4DW",
- "payer_alias_masked": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "livemode": true,
- "metadata": {
- "property1": "string",
- "property2": "string"
}, - "attempts": [
- {
- "id": "att_5Hn2Wc8RtY",
- "object": "payment_attempt",
- "tx_id": "CJT0KQ3VZ8M2XH7RP4DW",
- "status": "request_sent",
- "payer_alias_masked": "+225 07 •• •• 42",
- "failure_code": "string",
- "duplicate": true,
- "refund_status": "pending",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
]
}
], - "has_more": true
}Renvoie le paiement et ses tentatives. Utilisable en polling pour suivre le statut.
| id required | string^pay_[A-Za-z0-9]+$ Identifiant du paiement ( |
{- "id": "pay_8Kq2xVt41N",
- "object": "payment",
- "status": "created",
- "amount": 32500,
- "currency": "XOF",
- "fee_amount": 0,
- "net_amount": 0,
- "mode": "immediate",
- "reference": "string",
- "description": "string",
- "tx_id": "CJT0KQ3VZ8M2XH7RP4DW",
- "payer_alias_masked": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "livemode": true,
- "metadata": {
- "property1": "string",
- "property2": "string"
}, - "attempts": [
- {
- "id": "att_5Hn2Wc8RtY",
- "object": "payment_attempt",
- "tx_id": "CJT0KQ3VZ8M2XH7RP4DW",
- "status": "request_sent",
- "payer_alias_masked": "+225 07 •• •• 42",
- "failure_code": "string",
- "duplicate": true,
- "refund_status": "pending",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
]
}Annule un paiement qui n'est pas encore dans un statut final. Une demande déjà envoyée ne
peut pas être retirée de l'application bancaire de l'acheteur : s'il la valide malgré
l'annulation, il est remboursé automatiquement. Un paiement déjà réglé ne peut pas être
annulé (409 payment_already_final).
| id required | string^pay_[A-Za-z0-9]+$ Identifiant du paiement ( |
| Idempotency-Key | string [ 1 .. 255 ] characters Clé unique choisie par le marchand (UUID recommandé), conservée 24 heures. |
{- "id": "pay_8Kq2xVt41N",
- "object": "payment",
- "status": "created",
- "amount": 32500,
- "currency": "XOF",
- "fee_amount": 0,
- "net_amount": 0,
- "mode": "immediate",
- "reference": "string",
- "description": "string",
- "tx_id": "CJT0KQ3VZ8M2XH7RP4DW",
- "payer_alias_masked": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "livemode": true,
- "metadata": {
- "property1": "string",
- "property2": "string"
}, - "attempts": [
- {
- "id": "att_5Hn2Wc8RtY",
- "object": "payment_attempt",
- "tx_id": "CJT0KQ3VZ8M2XH7RP4DW",
- "status": "request_sent",
- "payer_alias_masked": "+225 07 •• •• 42",
- "failure_code": "string",
- "duplicate": true,
- "refund_status": "pending",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
]
}Mouvements du compte (paiements, frais, retraits), du plus récent au plus ancien.
| type | string (BalanceTransactionType) Enum: "payment" "fee" "payout" "payout_reversal" "adjustment" Ne renvoyer que les mouvements de ce type. |
| created_from | string <date-time> Créés à partir de cette date (incluse). |
| created_to | string <date-time> Créés avant cette date (exclue). |
| limit | integer [ 1 .. 100 ] Default: 20 Nombre de résultats par page. |
| starting_after | string Identifiant du dernier élément de la page précédente. |
{- "object": "list",
- "data": [
- {
- "id": "txn_2Lp8Rw4QsA",
- "object": "balance_transaction",
- "type": "payment",
- "amount": 32500,
- "currency": "XOF",
- "source_id": "string",
- "description": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "livemode": true
}
], - "has_more": true
}Crée un retrait vers le compte de retrait enregistré du marchand (modifiable uniquement
depuis le tableau de bord). Sans amount, tout le solde disponible est retiré. Le montant
est réservé immédiatement et recrédité si le virement échoue.
| Idempotency-Key | string [ 1 .. 255 ] characters Clé unique choisie par le marchand (UUID recommandé), conservée 24 heures. |
Amount (integer) or null Montant à retirer ; tout le solde disponible si absent. |
{- "amount": 32500
}{- "id": "po_7Tg3Kd9VbN",
- "object": "payout",
- "amount": 32500,
- "currency": "XOF",
- "status": "pending",
- "method": "automatic",
- "destination": {
- "type": "bank_account",
- "label": "Ecobank CI •••• 4821"
}, - "failure_code": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "paid_at": "2019-08-24T14:15:22Z",
- "livemode": true
}Liste paginée, du plus récent au plus ancien.
| status | string (PayoutStatus) Enum: "pending" "paid" "failed" Ne renvoyer que les retraits dans ce statut. |
| created_from | string <date-time> Créés à partir de cette date (incluse). |
| created_to | string <date-time> Créés avant cette date (exclue). |
| limit | integer [ 1 .. 100 ] Default: 20 Nombre de résultats par page. |
| starting_after | string Identifiant du dernier élément de la page précédente. |
{- "object": "list",
- "data": [
- {
- "id": "po_7Tg3Kd9VbN",
- "object": "payout",
- "amount": 32500,
- "currency": "XOF",
- "status": "pending",
- "method": "automatic",
- "destination": {
- "type": "bank_account",
- "label": "Ecobank CI •••• 4821"
}, - "failure_code": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "paid_at": "2019-08-24T14:15:22Z",
- "livemode": true
}
], - "has_more": true
}| id required | string^po_[A-Za-z0-9]+$ Identifiant du retrait ( |
{- "id": "po_7Tg3Kd9VbN",
- "object": "payout",
- "amount": 32500,
- "currency": "XOF",
- "status": "pending",
- "method": "automatic",
- "destination": {
- "type": "bank_account",
- "label": "Ecobank CI •••• 4821"
}, - "failure_code": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "paid_at": "2019-08-24T14:15:22Z",
- "livemode": true
}CajouPay envoie un POST à l'URL de webhook du marchand à chaque changement de statut d'un
paiement. Le marchand doit répondre par un code 2xx en moins de 10 secondes ; sinon
CajouPay relance après 1 min, 5 min, 30 min, 2 h puis 12 h.
Signature : l'en-tête CajouPay-Signature vaut t=<horodatage>,v1=<signature>, où
<signature> est le HMAC-SHA256 en hexadécimal de <horodatage>.<corps brut> calculé avec
le secret de l'endpoint. Le marchand vérifie la signature et rejette un horodatage de plus
de 5 minutes.
Le même événement peut être reçu plusieurs fois : le traiter de façon idempotente avec son
id.
| CajouPay-Signature required | string Examples: t=1791747728,v1=5f8a… |
| id required | string Identifiant de l'événement, à utiliser pour l'idempotence. |
| object required | string Value: "event" |
| type required | string (EventType) Enum: "payment.request_sent" "payment.accepted_deferred" "payment.succeeded" "payment.declined" "payment.expired" "payment.canceled" "payment.failed" "payment.duplicate_refunded" |
| created_at required | string <date-time> |
| livemode required | boolean |
required | object |
{- "id": "evt_3Fz9Qm2LkP",
- "object": "event",
- "type": "payment.succeeded",
- "created_at": "2026-10-11T17:42:08Z",
- "livemode": false,
- "data": {
- "object": {
- "id": "pay_8Kq2xVt41N",
- "object": "payment",
- "status": "succeeded",
- "amount": 32500,
- "currency": "XOF",
- "mode": "immediate",
- "reference": "CMD-20481",
- "description": "Commande Awa Mode",
- "fee_amount": 488,
- "net_amount": 32012,
- "tx_id": "CJT0KQ3VZ8M2XH7RP4DW",
- "payer_alias_masked": "+225 07 •• •• 42",
- "expires_at": "2026-10-11T17:47:00Z",
- "created_at": "2026-10-11T17:42:00Z",
- "livemode": false,
- "metadata": {
- "order_id": "20481"
}, - "attempts": [
- {
- "id": "att_5Hn2Wc8RtY",
- "object": "payment_attempt",
- "tx_id": "CJT0KQ3VZ8M2XH7RP4DW",
- "status": "succeeded",
- "payer_alias_masked": "+225 07 •• •• 42",
- "failure_code": null,
- "duplicate": false,
- "refund_status": null,
- "created_at": "2026-10-11T17:42:31Z",
- "updated_at": "2026-10-11T17:42:08Z"
}
]
}
}
}Envoyé quand un retrait est versé (payout.paid) ou échoue (payout.failed). Même URL,
même signature et mêmes relances que les événements de paiement.
| CajouPay-Signature required | string |
| id required | string |
| object required | string Value: "event" |
| type required | string (PayoutEventType) Enum: "payout.paid" "payout.failed" |
| created_at required | string <date-time> |
| livemode required | boolean |
required | object |
{- "id": "evt_9Rk4Np7XwE",
- "object": "event",
- "type": "payout.paid",
- "created_at": "2019-08-24T14:15:22Z",
- "livemode": true,
- "data": {
- "object": {
- "id": "po_7Tg3Kd9VbN",
- "object": "payout",
- "amount": 32500,
- "currency": "XOF",
- "status": "pending",
- "method": "automatic",
- "destination": {
- "type": "bank_account",
- "label": "Ecobank CI •••• 4821"
}, - "failure_code": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "paid_at": "2019-08-24T14:15:22Z",
- "livemode": true
}
}
}