API CajouPay (1.0.0-draft)

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.

Principes

  • Authentification : Authorization: Bearer <clé secrète>. La clé détermine l'environnement : sk_test_… (mode test, simulateur) ou sk_live_… (production).
  • Montants : entiers en francs CFA (XOF), sans décimales. 32500 signifie 32 500 FCFA.
  • Dates : ISO 8601 en UTC (2026-10-11T17:42:08Z).
  • Idempotence : 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.
  • Paiement et tentatives : un paiement peut connaître plusieurs tentatives (une par alias saisi). Chaque tentative a son propre tx_id. Un refus ou une expiration de tentative ne change pas le statut du paiement tant qu'un nouvel essai reste possible.
  • Compte marchand : CajouPay est un établissement de monnaie électronique. Un paiement réussi crédite le compte CajouPay du marchand de son montant net (amount - fee_amount). Le solde est retiré vers le compte de retrait du marchand, automatiquement chaque jour ou à la demande (POST /payouts).
  • Paiements en double : une demande de paiement envoyée ne peut pas être annulée. Si l'acheteur valide deux tentatives du même paiement, la seconde est marquée duplicate, n'est jamais créditée au marchand et est remboursée automatiquement à l'acheteur.

Alias de test (mode test uniquement)

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)

Paiements

Créer et suivre des paiements PI-SPI.

Créer un paiement

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.

Authorizations:
secretKey
header Parameters
Idempotency-Key
string [ 1 .. 255 ] characters

Clé unique choisie par le marchand (UUID recommandé), conservée 24 heures.

Request Body schema: application/json
required
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"
  • immediate : l'acheteur valide tout de suite (délai de quelques minutes).
  • on_delivery : l'acheteur valide à la réception du colis, avant expires_at.
expires_at
string or null <date-time>

Date limite de paiement. Obligatoire si mode vaut on_delivery.

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 :

  • numéro de téléphone international : + suivi de l'indicatif à 3 chiffres et de 8 à 10 chiffres, espaces, points et tirets ignorés (ex. +225 07 00 00 00 42) ;
  • identifiant (adresse de paiement) : 1 à 36 lettres, chiffres ou tirets (ex. f3b2c9d0-11aa-4c3e-9e2f-7a6b5c4d3e21).
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).

Responses

Request samples

Content type
application/json
Example
{}

Response samples

Content type
application/json
{
  • "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": {
    },
  • "attempts": [ ]
}

Lister les paiements

Liste paginée, du plus récent au plus ancien.

Authorizations:
secretKey
query Parameters
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.

Responses

Response samples

Content type
application/json
{
  • "object": "list",
  • "data": [
    ],
  • "has_more": true
}

Consulter un paiement

Renvoie le paiement et ses tentatives. Utilisable en polling pour suivre le statut.

Authorizations:
secretKey
path Parameters
id
required
string^pay_[A-Za-z0-9]+$

Identifiant du paiement (pay_…).

Responses

Response samples

Content type
application/json
{
  • "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",
  • "checkout_url": "http://example.com",
  • "return_url": "http://example.com",
  • "cancel_url": "http://example.com",
  • "expires_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z",
  • "livemode": true,
  • "metadata": {
    },
  • "attempts": [
    ]
}

Annuler un paiement

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).

Authorizations:
secretKey
path Parameters
id
required
string^pay_[A-Za-z0-9]+$

Identifiant du paiement (pay_…).

header Parameters
Idempotency-Key
string [ 1 .. 255 ] characters

Clé unique choisie par le marchand (UUID recommandé), conservée 24 heures.

Responses

Response samples

Content type
application/json
{
  • "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",
  • "checkout_url": "http://example.com",
  • "return_url": "http://example.com",
  • "cancel_url": "http://example.com",
  • "expires_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z",
  • "livemode": true,
  • "metadata": {
    },
  • "attempts": [
    ]
}

Solde

Solde et mouvements du compte CajouPay du marchand.

Consulter le solde

Solde du compte CajouPay du marchand dans l'environnement de la clé utilisée.

Authorizations:
secretKey

Responses

Response samples

Content type
application/json
{
  • "object": "balance",
  • "available": 0,
  • "pending_payout": 0,
  • "currency": "XOF",
  • "livemode": true
}

Lister les mouvements du compte

Mouvements du compte (paiements, frais, retraits), du plus récent au plus ancien.

Authorizations:
secretKey
query Parameters
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.

Responses

Response samples

Content type
application/json
{
  • "object": "list",
  • "data": [
    ],
  • "has_more": true
}

Retraits

Retraits du solde vers le compte de retrait du marchand.

Retirer des fonds

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.

Authorizations:
secretKey
header Parameters
Idempotency-Key
string [ 1 .. 255 ] characters

Clé unique choisie par le marchand (UUID recommandé), conservée 24 heures.

Request Body schema: application/json
optional
Amount (integer) or null

Montant à retirer ; tout le solde disponible si absent.

Responses

Request samples

Content type
application/json
{
  • "amount": 32500
}

Response samples

Content type
application/json
{
  • "id": "po_7Tg3Kd9VbN",
  • "object": "payout",
  • "amount": 32500,
  • "currency": "XOF",
  • "status": "pending",
  • "method": "automatic",
  • "destination": {
    },
  • "failure_code": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "paid_at": "2019-08-24T14:15:22Z",
  • "livemode": true
}

Lister les retraits

Liste paginée, du plus récent au plus ancien.

Authorizations:
secretKey
query Parameters
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.

Responses

Response samples

Content type
application/json
{
  • "object": "list",
  • "data": [
    ],
  • "has_more": true
}

Consulter un retrait

Authorizations:
secretKey
path Parameters
id
required
string^po_[A-Za-z0-9]+$

Identifiant du retrait (po_…).

Responses

Response samples

Content type
application/json
{
  • "id": "po_7Tg3Kd9VbN",
  • "object": "payout",
  • "amount": 32500,
  • "currency": "XOF",
  • "status": "pending",
  • "method": "automatic",
  • "destination": {
    },
  • "failure_code": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "paid_at": "2019-08-24T14:15:22Z",
  • "livemode": true
}

Événement de paiement Webhook

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.

header Parameters
CajouPay-Signature
required
string
Examples: t=1791747728,v1=5f8a…
Request Body schema: application/json
required
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

Responses

Request samples

Content type
application/json
{
  • "id": "evt_3Fz9Qm2LkP",
  • "object": "event",
  • "type": "payment.succeeded",
  • "created_at": "2026-10-11T17:42:08Z",
  • "livemode": false,
  • "data": {
    }
}

Événement de retrait Webhook

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.

header Parameters
CajouPay-Signature
required
string
Request Body schema: application/json
required
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

Responses

Request samples

Content type
application/json
{
  • "id": "evt_9Rk4Np7XwE",
  • "object": "event",
  • "type": "payout.paid",
  • "created_at": "2019-08-24T14:15:22Z",
  • "livemode": true,
  • "data": {
    }
}