# Documentation d'intégration — API Marchande Redacok

*Version du 08/10/2026. Document public destiné aux développeurs qui intègrent la solution de paiement des applications marchandes Redacok. Il ne contient aucune clé ni information confidentielle.*

Adresse de ce document : `https://redacok.com/documentation-api` (page) et `https://redacok.com/documentation-api.md` (texte brut Markdown).

URL de base : `https://redacok.com/api/applications-marchandes`

Cette documentation est complète : en la lisant de bout en bout, vous savez créer une application, encaisser, envoyer de l'argent, suivre vos soldes, comprendre les frais, gérer les erreurs et passer en production.

---

## 1. Vue d'ensemble

Une **application marchande** est créée par un membre de type Établissement, Entreprise, Organisation/Association ou Coopérative, depuis son tableau de bord Redacok (onglet API Marchande). Redacok propose deux familles d'opérations :

| Famille | Sens | Ce que fait votre application | Moyens possibles |
|---|---|---|---|
| **Recevoir des paiements** (partie 4) | Entrant | Vos clients vous paient | Mobile Money, cartes Visa et Mastercard, compte Redacok |
| **Envoyer de l'argent** (partie 5) | Sortant | Vous payez vos utilisateurs, vendeurs ou livreurs | Compte Redacok, Mobile Money (les cartes bancaires ne s'appliquent pas aux envois) |

Chaque application possède :

| Élément | Rôle |
|---|---|
| **Clé publique** (`pk_…`) | identifie l'application ; peut apparaître dans les URL de consultation de statut |
| **Clé secrète** (`sk_…`) | authentifie vos appels serveur-à-serveur ; **ne jamais l'exposer côté navigateur ou mobile** |
| **Secret de webhook** | sert uniquement à vérifier la signature des notifications que Redacok vous envoie |
| **Un wallet** | solde « disponible » (argent encaissé en mode Réel, utilisable pour vos envois et retraits) et solde « en cours » (séquestre du mode Sandbox) |

La clé secrète est affichée à la création (et consultable tant que l'application est en mode Sandbox). Elle est effacée quand le passage en mode Réel est approuvé : **conservez-la dans un coffre de secrets dès sa création**. Si vous la perdez ou si elle a pu être exposée, régénérez-en une depuis le tableau de bord (voir partie 11).

---

## 2. Démarrage en 7 étapes

1. Créez votre application dans le tableau de bord Redacok (onglet API Marchande) et notez la clé publique, la clé secrète et le secret de webhook.
2. Renseignez l'adresse de votre webhook (`https://…`) et, si vous le souhaitez, l'e-mail des notifications.
3. Activez, dans le tableau de bord, les moyens de paiement que vous voulez proposer (case par moyen).
4. Faites vos essais en **Sandbox** (partie 9) : 3 paiements de test réussis sont nécessaires pour demander le passage en Réel.
5. Demandez le passage en **Réel** depuis le tableau de bord. La demande est validée par la direction de Redacok.
6. **Après le passage en production, contactez toujours le support Redacok** (messagerie du tableau de bord) pour faire activer, un à un, tous les moyens de paiement dont vous avez besoin, par pays.
7. Mettez à jour vos clés de production sur votre serveur et suivez vos soldes dans le tableau de bord.

---

## 3. Conventions générales

- **Format** : toutes les requêtes sont en JSON (`Content-Type: application/json`), méthode `POST` sauf indication contraire.
- **Authentification** : `clePublique` et `cleSecrete` sont envoyées dans le **corps JSON** de chaque requête (pas d'en-tête Authorization). La consultation d'un statut n'utilise que la clé publique.
- **Montant** : chaîne de chiffres, jusqu'à 2 décimales (`"5000"`, `"1500.50"`), strictement positive.
- **Devise** : `XAF` par défaut. Une autre devise est convertie en XAF par Redacok ; si votre plateforme convertit déjà, envoyez `"XAF"`. Les soldes et frais sont exprimés en FCFA (XAF).
- **Numéro de téléphone Mobile Money** : format international, chiffres seulement, sans « + » ni espaces (ex. `237670000000`). Pour un numéro camerounais de 9 chiffres commençant par 6, Redacok ajoute l'indicatif 237 si vous l'oubliez. Un numéro invalide est refusé immédiatement par l'opérateur : rien n'est débité.
- **Numéro de compte Redacok** : le numéro complet du compte (ex. `CM10000000010000100000170`).
- **Erreurs** : une réponse HTTP 4xx contient un champ `message` en français avec la raison (liste complète en partie 12).
- **Délai d'attente conseillé** pour vos appels : 30 secondes.
- **Usage raisonnable** : pour suivre un paiement, interrogez le statut toutes les 5 à 10 secondes, pendant 5 minutes au maximum.

---

## 4. Recevoir des paiements : `POST /paiement/initier`

```json
{
  "clePublique": "pk_...",
  "cleSecrete": "sk_...",
  "montant": "5000",
  "devise": "XAF",
  "referenceMarchand": "VOTRE-REFERENCE-UNIQUE",
  "moyenPaiement": "MTN_MOMO",
  "numeroCompteClient": "237670000000",
  "idempotency_key": "cle-unique-optionnelle"
}
```

| Champ | Détail |
|---|---|
| `montant` | voir partie 3 |
| `devise` | `XAF` par défaut |
| `referenceMarchand` | votre identifiant de commande, conservé avec le paiement. Redacok ne l'impose pas unique : pour éviter les doublons, utilisez une clé d'idempotence |
| `moyenPaiement` | un code de la liste de la partie 7 |
| `numeroCompteClient` | Mobile Money : numéro du client (partie 3). `REDACOK_INTERNE` : numéro de compte Redacok du client. Inutile pour `VISA` et `MASTERCARD` |
| `idempotency_key` | optionnel, voir partie 10 (peut aussi être envoyée dans l'en-tête `Idempotency-Key`) |
| `urlSucces`, `urlAnnulation`, `urlEchec` | optionnels, pour `VISA` et `MASTERCARD` : adresses vers lesquelles le client est renvoyé après la page de carte |

**Réponse** : `{ "paiementId": "uuid" }`. Pour `VISA` et `MASTERCARD`, la réponse contient aussi `"paymentUrl"` : ouvrez ce lien dans le navigateur du client (sur Android, préférez le navigateur du téléphone à une WebView) pour qu'il saisisse sa carte sur la page sécurisée du partenaire de paiement.

### Cycle de vie d'un paiement

| Statut | Signification |
|---|---|
| `EN_ATTENTE` | créé, le client n'a pas encore payé |
| `APPROUVE` | payé ; le montant (moins les frais si vous les assumez) est crédité sur le wallet. Un paiement approuvé ne change plus de statut |
| `REJETE` | refusé par le partenaire de paiement ou par le client |
| `EXPIRE` | **non payé au bout de 5 minutes** |

Chaque paiement est valable **5 minutes**, validation chez l'opérateur ou saisie de la carte comprises. Un paiement `EXPIRE` ne peut plus être validé : créez-en un nouveau.

### Comment le client paie selon le moyen

- **Mobile Money** : le client reçoit une demande de confirmation sur son téléphone et saisit son code secret. Le numéro est vérifié par l'opérateur dès la demande.
- **Cartes Visa et Mastercard** : le client saisit sa carte sur la page sécurisée (`paymentUrl`), puis est renvoyé vers votre application.
- **`REDACOK_INTERNE`** : le client reçoit la demande dans son application Redacok, choisit son compte (Courant ou Épargne) et saisit le **code PIN de ce compte**.

### Retour du client après un paiement par carte

Après la saisie de sa carte, le client est renvoyé vers votre application :

- paiement validé : `urlSucces` ;
- paiement annulé par le client : `urlAnnulation` ;
- paiement refusé ou échoué : `urlEchec` (à défaut, `urlAnnulation`).

Chaque adresse commence par `https://` (ou est le lien d'ouverture de votre application mobile, par exemple `monapp://paiement`), sans identifiant ni mot de passe, 500 caractères au maximum. Redacok y ajoute les paramètres `redacok_paiement` (le `paiementId`), `redacok_resultat` (`succes`, `annulation` ou `echec`), `redacok_statut` (statut connu à cet instant) et `redacok_reference` (votre `referenceMarchand`). Le paramètre `redacok_statut` n'est qu'une indication : confirmez toujours le paiement par le webhook ou par la consultation du statut. Sans adresse fournie, le client voit une page de confirmation Redacok neutre.

### Consulter un paiement : `GET /paiement/{paiementId}/statut?clePublique=pk_...`

Réponse : `{ "statut": "APPROUVE", "montant": "5000.00", "reference": "VOTRE-REFERENCE" }`.

Pour les paiements Mobile Money et carte encore `EN_ATTENTE`, cet appel interroge aussi le partenaire de paiement : c'est le **filet de sécurité** si un webhook n'arrive pas.

---

## 5. Envoyer de l'argent depuis votre wallet

Les trois appels ci-dessous débitent le **wallet disponible** de l'application (jamais négatif). Mêmes clés dans le corps JSON. Ils servent à payer vos utilisateurs, vendeurs ou livreurs. Les cartes Visa et Mastercard ne s'appliquent pas aux envois.

| Appel | Usage | Champs |
|---|---|---|
| `POST /paiement/verifier-destinataire` | connaître le nom du titulaire d'un compte Redacok avant d'envoyer (ne fonctionne pas pour un numéro Mobile Money) | `clePublique`, `cleSecrete`, `numeroCompteDestinataire` |
| `POST /paiement/envoyer` | payer un compte Redacok | `clePublique`, `cleSecrete`, `montant`, `numeroCompteDestinataire`, `referenceMarchand`, `devise`, `idempotency_key` |
| `POST /paiement/envoyer-externe` | envoyer vers un numéro Mobile Money | `clePublique`, `cleSecrete`, `montant`, `telephone`, `moyenPaiement`, `referenceMarchand`, `devise`, `idempotency_key` |

**Moyens d'envoi (`moyenPaiement` de `envoyer-externe`)** : `MTN_MOMO`, `ORANGE_MONEY`, `EXPRESS_UNION`, `AIRTEL_MONEY`, `AFRICELL_MONEY`, `TELMA`, `LONESTAR_MTN`, `MOOV_MONEY`, `MOOV_AFRICA`, selon le pays de l'opérateur. Le moyen doit être activé sur votre application (voir partie 7).

**Réponses**

- `verifier-destinataire` : `{ "nomComplet": "Nom du titulaire" }`.
- `envoyer` : `{ "verdict": "PAIEMENT_ENVOYE", "message": "…", "nomDestinataire": "…" }`.
- `envoyer-externe` : `{ "verdict": "ENVOI_EFFECTUE", "message": "…" }`. Le message contient le montant envoyé, les frais d'envoi éventuels et la référence de l'opérateur.

**Comportement**

- Le traitement est **immédiat** : la réponse vous dit tout de suite si l'envoi est parti ou refusé. Il n'y a pas de traitement par lots ni d'horaires imposés par Redacok.
- Si l'opérateur refuse ou n'aboutit pas, le wallet est **recrédité intégralement**, tout de suite, et l'appel renvoie une erreur.
- Une opération partie ne peut pas être annulée par API. Un envoi n'a que deux issues : `ENVOYE` (parti) ou refusé (erreur, wallet recrédité).
- Plafonds quotidiens : voir la partie 17.
- Il n'y a pas de webhook pour les envois : la réponse de l'appel fait foi. Retrouvez chaque envoi dans l'historique de votre application (tableau de bord), par l'appel `/paiement/historique` ou par l'appel `/paiement/statut-envoi` avec votre `referenceMarchand` (partie 16).
- Wallet insuffisant : erreur 400 avec le message « Solde du Wallet insuffisant pour cet envoi. » (ou « …pour ce paiement. » pour `envoyer`). Le montant à couvrir inclut les frais d'envoi si vous les assumez.

---

## 6. Wallet, soldes et retraits

- **Disponible** : argent encaissé en mode Réel, utilisable pour vos envois et vos retraits. Un paiement approuvé en mode Réel est crédité tout de suite (moins les frais si vous les assumez).
- **En cours (séquestre)** : en mode Sandbox, les montants encaissés restent en séquestre ; ils sont libérés vers le disponible à l'approbation du passage en Réel. En mode Réel, les encaissements d'un moyen de paiement pour lequel Redacok a configuré un **délai de disponibilité** (par exemple 24 h, 48 h ou plusieurs jours) restent dans le solde « en cours » pendant ce délai, puis passent automatiquement au solde « disponible » (vérification toutes les 10 minutes). Sans délai configuré, l'argent est disponible tout de suite. Le délai dépend du moyen de paiement, du pays et de l'application ; le support vous le communique.
- **Consultation** : les soldes, l'historique complet des paiements, des envois et des frais se consultent dans le tableau de bord (onglet API Marchande, un bouton par application). Pour votre serveur, trois appels par clés existent : le solde du wallet, l'historique complet et le statut d'un envoi (partie 16). Ils servent à votre rapprochement comptable, en plus de vos webhooks.
- **Recharger le wallet** : depuis le tableau de bord, transférez des fonds de votre Compte Courant Redacok vers le wallet.
- **Retirer vos fonds** : depuis le tableau de bord, faites une demande de retrait. Elle est vérifiée puis validée par l'équipe habilitée de Redacok ; vous êtes notifié du résultat.
- Le wallet de chaque application est un compte distinct, séparé des autres wallets et des comptes des clients.

---

## 7. Moyens de paiement par pays

Redacok propose les moyens ci-dessous pour les paiements de vos clients. Le **pays est celui du marchand** (dossier de vérification). À la création de l'application, seul `REDACOK_INTERNE` est activé ; vous activez ensuite les autres dans le tableau de bord (case par moyen). **Après le passage en production, contactez le support Redacok pour faire activer, par pays, tous les moyens dont vous avez besoin.** Le support vous confirme en privé les moyens ouverts pour votre application.

| Pays | Moyens de paiement |
|---|---|
| Cameroun (CM) | `REDACOK_INTERNE`, `ORANGE_MONEY`, `MTN_MOMO`, `EXPRESS_UNION`, `VISA`, `MASTERCARD` |
| Côte d'Ivoire (CI) | `REDACOK_INTERNE`, `ORANGE_MONEY`, `WAVE`, `MTN_MOMO`, `MOOV_MONEY`, `VISA`, `MASTERCARD` |
| Sénégal (SN) | `REDACOK_INTERNE`, `ORANGE_MONEY`, `WAVE`, `FREE_MONEY`, `VISA`, `MASTERCARD` |
| Mali (ML) | `REDACOK_INTERNE`, `ORANGE_MONEY`, `MOOV_MONEY`, `WAVE`, `VISA`, `MASTERCARD` |
| Burkina Faso (BF) | `REDACOK_INTERNE`, `ORANGE_MONEY`, `MOOV_MONEY`, `WAVE`, `VISA`, `MASTERCARD` |
| Niger (NE) | `REDACOK_INTERNE`, `ORANGE_MONEY`, `MOOV_MONEY`, `AIRTEL_MONEY`, `VISA`, `MASTERCARD` |
| Togo (TG) | `REDACOK_INTERNE`, `MOOV_MONEY`, `T_MONEY`, `VISA`, `MASTERCARD` |
| Bénin (BN) | `REDACOK_INTERNE`, `MTN_MOMO`, `MOOV_MONEY`, `VISA`, `MASTERCARD` |
| Guinée (GN) | `REDACOK_INTERNE`, `MTN_MOMO`, `ORANGE_MONEY`, `VISA`, `MASTERCARD` |
| Gabon (GA) | `REDACOK_INTERNE`, `MOOV_AFRICA`, `AIRTEL_MONEY`, `VISA`, `MASTERCARD` |
| Congo (CG) | `REDACOK_INTERNE`, `MTN_MOMO`, `AIRTEL_MONEY`, `VISA`, `MASTERCARD` |
| Tchad (TD) | `REDACOK_INTERNE`, `AIRTEL_MONEY`, `MOOV_AFRICA`, `VISA`, `MASTERCARD` |
| République centrafricaine (CF) | `REDACOK_INTERNE`, `ORANGE_MONEY`, `MOOV_AFRICA`, `VISA`, `MASTERCARD` |
| RD Congo (CD) | `REDACOK_INTERNE`, `ORANGE_MONEY`, `AIRTEL_MONEY`, `AFRICELL_MONEY`, `MPESA`, `VISA`, `MASTERCARD` |
| Madagascar (MG) | `REDACOK_INTERNE`, `TELMA`, `ORANGE_MONEY`, `AIRTEL_MONEY`, `VISA`, `MASTERCARD` |
| Libéria (LR) | `REDACOK_INTERNE`, `LONESTAR_MTN`, `ORANGE_MONEY`, `VISA`, `MASTERCARD` |
| Ouganda (UG) | `REDACOK_INTERNE`, `MTN_MOMO`, `AIRTEL_MONEY`, `WAVE`, `VISA`, `MASTERCARD` |
| Rwanda (RW) | `REDACOK_INTERNE`, `MTN_MOMO`, `AIRTEL_MONEY`, `VISA`, `MASTERCARD` |
| Kenya (KE) | `REDACOK_INTERNE`, `MPESA`, `AIRTEL_MONEY`, `VISA`, `MASTERCARD` |
| Tanzanie (TZ) | `REDACOK_INTERNE`, `MPESA`, `AIRTEL_MONEY`, `VISA`, `MASTERCARD` |
| Zambie (ZM) | `REDACOK_INTERNE`, `MTN_MOMO`, `AIRTEL_MONEY`, `VISA`, `MASTERCARD` |
| Ghana (GH) | `REDACOK_INTERNE`, `MTN_MOMO`, `VISA`, `MASTERCARD` |
| Autres pays d'Afrique et du monde | `REDACOK_INTERNE`, `VISA`, `MASTERCARD`, et les moyens locaux de votre pays sur demande au support |

Descriptions des moyens : `ORANGE_MONEY` (Orange Money), `MTN_MOMO` (MTN Mobile Money), `MOOV_MONEY` et `MOOV_AFRICA` (Moov), `AIRTEL_MONEY` (Airtel Money), `AFRICELL_MONEY` (Africell), `WAVE` (Wave), `FREE_MONEY` (Free Money), `T_MONEY` (T-Money), `MPESA` (M-Pesa), `TELMA` (Telma MVola), `LONESTAR_MTN` (Lonestar MTN), `EXPRESS_UNION` (Express Union), `VISA` et `MASTERCARD` (cartes bancaires, encaissement uniquement), `REDACOK_INTERNE` (compte Redacok, encaissement et envoi).

---

## 8. Frais

Les frais dépendent du **sens** (encaissement ou envoi), du **pays** et du **moyen de paiement**.

**Règle de calcul** (identique pour les encaissements et pour les envois) :

1. si des frais ont été configurés **sur votre application** pour ce moyen et ce sens (pourcentage ou montant fixe, ou « aucun frais »), ce sont **ces frais seuls** qui s'appliquent ;
2. sinon, ce sont les **frais généraux** de la plateforme pour ce pays, ce moyen et ce sens (taux du partenaire de paiement + marge de la plateforme + TVA lorsqu'elle s'applique) ; à défaut de ligne pour votre pays, la ligne « tous pays » s'applique.

Le barème applicable à votre application vous est communiqué par le support Redacok et peut être personnalisé pour votre application, séparément pour l'encaissement et pour l'envoi.

**Qui assume les frais** : réglage « Qui assume les frais » du tableau de bord, par application.

| Exemple avec 1 % de frais sur 10 000 FCFA | Marchand assume | Client (ou destinataire) assume |
|---|---|---|
| Encaissement | le client paie 10 000 ; le wallet reçoit 9 900 | le client paie 10 100 ; le wallet reçoit 10 000 |
| Envoi | le destinataire reçoit 10 000 ; le wallet est débité de 10 100 | le destinataire reçoit 9 900 ; le wallet est débité de 10 000 |

Autres règles :

- Les montants sont à 2 décimales au maximum ; les frais sont arrondis au centième. Les opérateurs travaillent en FCFA entiers.
- Si les frais à la charge du destinataire sont supérieurs ou égaux au montant envoyé, l'envoi est refusé (« Montant trop faible : il ne couvre pas les frais d'envoi. »).
- Il n'y a ni abonnement, ni frais fixe mensuel, ni minimum mensuel pour une application.
- Un paiement refusé, expiré ou un envoi refusé par l'opérateur n'entraîne aucun frais.

---

## 9. Mode Sandbox et mode Réel

1. Toute application démarre en **Sandbox** (essais). **Le Sandbox utilise de l'argent réel** : chaque transaction de test, entrante ou sortante, est limitée à **200 FCFA** (un montant supérieur est refusé).
2. Il faut au moins **3 paiements de test réussis** (tous moyens de paiement confondus) pour pouvoir demander le passage en Réel.
3. La demande est validée manuellement par la direction de Redacok. À l'approbation, les fonds de test en séquestre sont libérés vers le wallet disponible.
4. En mode Réel : plus de limite de test (les plafonds des opérateurs et des banques restent applicables), la clé secrète n'est plus consultable (conservez-la) et la liste blanche d'IP (si définie) s'applique à vos appels.
5. Une application en mode Réel **ne peut pas revenir en Sandbox**. Pour séparer test et production, créez deux applications.
6. Après le passage en Réel, contactez le support pour activer tous les moyens de paiement nécessaires (partie 2, étape 6).

---

## 10. Webhooks et idempotence

### Webhooks (notification automatique des paiements reçus)

L'URL (obligatoirement en `https://`) se configure dans le tableau de bord, section de l'application. Une seule adresse par application.

**Requête envoyée par Redacok** : `POST` JSON avec les en-têtes `X-Redacok-Timestamp` (secondes Unix) et `X-Redacok-Signature`.

```json
{ "paiementId": "uuid", "statut": "APPROUVE", "montant": "5000.00", "applicationId": "uuid" }
```

`statut` vaut `APPROUVE` (payé), `REJETE` (refusé) ou `EXPIRE` (paiement non validé dans les 5 minutes). Pour un paiement Mobile Money ou carte que l'opérateur n'a pas encore confirmé, aucun webhook n'est envoyé tant que le résultat n'est pas connu : utilisez la consultation de statut (partie 4).

**Vérification de la signature — HMAC-SHA256**

```
signature = HMAC_SHA256( cle = secret_de_webhook,
                         message = timestamp + "." + corps_brut_de_la_requete )
```

Résultat encodé en **hexadécimal minuscule**. Utilisez le **corps brut exact** reçu (pas un JSON reconstruit).

Exemple Node.js (Express) :

```js
const crypto = require('crypto');
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const ts = req.header('X-Redacok-Timestamp');
  const recu = req.header('X-Redacok-Signature') || '';
  const attendu = crypto.createHmac('sha256', process.env.REDACOK_SECRET_WEBHOOK)
    .update(ts + '.' + req.body.toString('utf8')).digest('hex');
  const ok = recu.length === attendu.length &&
    crypto.timingSafeEqual(Buffer.from(recu), Buffer.from(attendu));
  if (!ok || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return res.sendStatus(401);
  const evenement = JSON.parse(req.body.toString('utf8'));
  // traiter evenement.paiementId / evenement.statut (de façon idempotente)
  res.sendStatus(200);
});
```

Bonnes pratiques :

- rejetez les requêtes dont le timestamp s'écarte de plus de 5 minutes (anti-rejeu, à implémenter de votre côté) ;
- répondez vite (`200`) : Redacok attend **10 secondes au maximum** votre réponse ;
- **Renvoi automatique** : si votre serveur ne répond pas `2xx` dans les 10 secondes (ou est injoignable), Redacok réessaie après 1 minute, 5 minutes, 30 minutes puis 2 heures (5 tentatives au total, chacune re-signée avec un timestamp neuf), puis abandonne. Votre traitement doit donc être **idempotent** ;
- il n'y a pas de rejeu manuel : la consultation de statut reste votre filet de sécurité ;
- ne marquez une commande comme payée que sur `APPROUVE` (webhook vérifié ou consultation du statut), jamais sur la seule redirection du navigateur du client.

### Idempotence (éviter les doubles opérations)

Pour `initier`, `envoyer` et `envoyer-externe`, envoyez une clé unique par opération (en-tête `Idempotency-Key` ou champ `idempotency_key`).

- Même clé et mêmes paramètres : vous recevez le **même résultat** sans nouvelle opération.
- Même clé avec des paramètres différents : erreur `409`.
- Même clé pendant qu'une première requête est encore en cours : erreur `409`, réessayez un peu plus tard.

---

## 11. Sécurité

- **Liste blanche d'IP** (optionnelle, mode Réel) : ajoutez l'adresse IPv4 publique de votre serveur dans le tableau de bord (vous pouvez aussi en retirer). Elle s'applique à `initier`, `envoyer` et `envoyer-externe`. Liste vide : aucune restriction. Si elle contient au moins une adresse, tout appel venant d'une autre IP reçoit une erreur `403` : vos appels doivent alors partir d'une IP fixe.
- **Rotation des clés** : « Régénérer la clé secrète » et « Régénérer le secret de webhook » (tableau de bord) fonctionnent à tout moment, même après le passage en Réel. L'ancienne valeur est invalidée immédiatement : préparez la mise à jour de votre serveur avant de régénérer.
- Gardez la clé secrète côté serveur uniquement.
- Vérifiez **toujours** la signature des webhooks et le timestamp avant de livrer une commande.
- Redacok contrôle la signature d'un paiement par le PIN du compte du client : vous ne manipulez jamais de code PIN.

---

## 12. Erreurs

Une erreur renvoie un code HTTP et un champ `message`.

| Code | Message (début) | Cause et action |
|---|---|---|
| 401 | « Cle publique invalide… » / « Cle secrete invalide. » | clés erronées (attention aux espaces) |
| 403 | « Cette application a ete desactivee. » | application désactivée : contactez le support |
| 403 | « Adresse IP non autorisee pour cette application. » | liste blanche d'IP : ajoutez l'IP de votre serveur |
| 400 | « Montant invalide. » | format du montant (partie 3) |
| 400 | « Le moyen de paiement X n est pas active pour cette application. » | activez ce moyen dans le tableau de bord |
| 400 | « Le moyen de paiement X est momentanement indisponible pour cette application. Aucun montant n'a ete debite… » | le moyen n'est pas encore ouvert pour votre application, ou l'opérateur refuse la demande (numéro invalide, solde insuffisant du client, plafond). Vérifiez le numéro puis contactez le support si cela persiste. Rien n'est débité |
| 400 | « Aucun fournisseur actif ne supporte l'envoi pour ce moyen de paiement. » | ce moyen d'envoi n'est pas encore activé pour votre pays : contactez le support |
| 400 | « Solde du Wallet insuffisant pour cet envoi. » | rechargez le wallet (frais d'envoi compris si vous les assumez) |
| 400 | « Montant trop faible : il ne couvre pas les frais d'envoi. » | augmentez le montant |
| 400 | « Numero de compte destinataire introuvable. » | vérifiez le numéro avec `verifier-destinataire` |
| 400 | « Montant trop faible… » / « Montant trop élevé… » / « Plafond atteint… » / « Plafond journalier atteint… » | une règle de la partie 17 est dépassée (montant minimum ou maximum, plafond par jour). Rien n'est débité |
| 400 | message sur la limite du Sandbox | en Sandbox, 200 FCFA maximum par transaction |
| 409 | « …cle d'idempotence… » | même clé avec d'autres paramètres, ou opération encore en cours |

---

## 13. Questions fréquentes

**Faut-il refaire une demande pour chaque moyen de paiement ?** Non : activez-les dans le tableau de bord, puis, après le passage en production, demandez au support de confirmer ceux dont vous avez besoin par pays.

**Un client peut-il payer deux fois la même référence ?** La référence n'est pas imposée unique. Utilisez une clé d'idempotence par opération et gardez votre propre contrôle de doublon sur `referenceMarchand`.

**Que se passe-t-il si le client valide après 5 minutes ?** Le paiement est `EXPIRE` et ne peut plus être validé : créez-en un nouveau. Si un client a été débité chez son opérateur alors que le paiement est expiré, contactez le support avec la référence.

**Comment rembourser un client ?** Il n'y a pas d'appel de remboursement par API. Contactez le support avec le `paiementId` : le remboursement est traité par l'équipe habilitée. Vous pouvez aussi renvoyer de l'argent à un compte Redacok avec `envoyer`, ou à un numéro Mobile Money avec `envoyer-externe`.

**Les paiements par carte passent-ils par 3D Secure ?** La saisie de la carte se fait sur la page sécurisée du partenaire de paiement, qui applique ses protections. Pour les litiges de cartes, contactez le support.

**Quelles devises ?** Vous envoyez en `XAF`, ou dans une autre devise convertie en XAF par Redacok.

**Peut-on utiliser un lien d'application mobile pour le retour de carte ?** Oui : `monapp://paiement` est accepté dans `urlSucces`, `urlAnnulation` et `urlEchec`.

**Comment savoir qu'un envoi Mobile Money est bien parti ?** La réponse de `envoyer-externe` le confirme tout de suite (`ENVOI_EFFECTUE` avec la référence de l'opérateur). En cas d'échec, vous recevez une erreur et le wallet est recrédité.

**Où voir mes paiements, envois et frais ?** Dans l'historique de chaque application, dans le tableau de bord (onglet API Marchande). Un résumé horaire des opérations vous est aussi envoyé par notification.

**Comment connaître mon solde ou rapprocher ma comptabilité ?** Par `/paiement/solde` et `/paiement/historique` (partie 16), ou dans le tableau de bord.

**Comment vérifier un envoi après coup ?** Par `/paiement/statut-envoi` avec votre `referenceMarchand` (partie 16).

**Y a-t-il des limites de montant, des plafonds par jour ou un délai avant que l'argent soit disponible ?** Oui, ils sont configurés par Redacok par pays, moyen de paiement et application : voir la partie 17 et la partie 6.

**Existe-t-il un environnement de test sans argent réel ?** Le Sandbox utilise de l'argent réel, limité à 200 FCFA par transaction.

---

## 14. Notifications côté marchand

Chaque application peut avoir sa propre adresse e-mail pour les notifications de transactions (onglet API Marchande). Pour ne pas vous inonder : les 5 premières transactions de chaque heure sont notifiées une par une ; un résumé horaire (nombre et montants reçus, échoués, envoyés, retraits, clients ayant essayé) est ensuite envoyé par notification push.

---

## 15. Aide, support et mise en production

Pour toute question d'intégration, pour faire activer un moyen de paiement ou un pays, pour un remboursement, un retrait ou un incident (paiement approuvé mais non crédité, envoi bloqué), contactez le support Redacok depuis votre tableau de bord (espace Messagerie). Indiquez le nom de l'application, le `paiementId` ou la référence concernée et l'heure approximative.

**Après chaque passage en production : contactez le support pour activer tous vos moyens de paiement.**

---

## 16. Solde, historique et statut d'un envoi par API

Ces trois appels sont destinés à **votre serveur** (clés dans le corps JSON, mêmes règles que les autres appels : liste blanche d'IP incluse). Aucune clé secrète ne doit être utilisée côté navigateur ou mobile.

### `POST /paiement/solde` — solde du wallet

```json
{ "clePublique": "pk_...", "cleSecrete": "sk_..." }
```

Réponse : `{ "disponible": "125000.00", "enCours": "0.00", "devise": "XAF", "mode": "REEL" }`. `disponible` est utilisable pour vos envois et retraits ; `enCours` est le séquestre du mode Sandbox. Montants en FCFA.

### `POST /paiement/historique` — toutes les opérations

```json
{ "clePublique": "pk_...", "cleSecrete": "sk_...", "sens": "SORTANT", "statut": "ENVOYE", "depuis": "2026-10-01", "jusqua": "2026-10-31", "page": 1, "limite": 50 }
```

Tous les champs après les clés sont optionnels : `sens` (`ENTRANT` pour les paiements reçus, `SORTANT` pour les envois), `statut` (`EN_ATTENTE`, `APPROUVE`, `REJETE`, `EXPIRE` pour les paiements reçus ; `ENVOYE`, `ECHEC` pour les envois), `depuis` et `jusqua` (dates `AAAA-MM-JJ`, heure du Cameroun), `page` (à partir de 1) et `limite` (50 par défaut, 200 au maximum).

Réponse : `{ "page": 1, "limite": 50, "total": 132, "operations": [ … ] }`, les plus récentes d'abord. Chaque opération contient : `id`, `sens`, `moyen` (moyen de paiement des encaissements), `montant`, `frais`, `statut`, `referenceMarchand`, `destinataire` (envois uniquement ; les numéros de téléphone sont masqués sauf les 4 derniers chiffres) et `creeLe` (date ISO). Utilisez-la pour votre rapprochement comptable. Dans le tableau de bord, l'historique de chaque application affiche les numéros complets (client, destinataire) et permet de rechercher par numéro de téléphone, numéro de compte, nom ou référence, et de filtrer par jour ou par mois.

### `POST /paiement/statut-envoi` — retrouver un envoi

```json
{ "clePublique": "pk_...", "cleSecrete": "sk_...", "referenceMarchand": "VOTRE-REFERENCE" }
```

Réponse : `{ "envois": [ { "id": "uuid", "statut": "ENVOYE", "montant": "5000.00", "frais": "0.00", "destinataire": "*****0000", "creeLe": "…" } ] }`. Le statut vaut `ENVOYE` (l'argent est parti) ou `ECHEC` (refusé par l'opérateur, wallet recrédité). Un envoi refusé avant exécution (clé invalide, solde insuffisant, plafond atteint, montant invalide) n'est pas enregistré : l'appel renvoie alors « Aucun envoi trouvé pour cette référence ». Si votre appel d'envoi a expiré chez vous sans réponse, utilisez cet appel avant de réessayer, ou renvoyez la même clé d'idempotence.

---

## 17. Limites, plafonds et délais configurables

Redacok configure, **par pays, par moyen de paiement et, si besoin, pour une application précise**, les règles suivantes. Elles peuvent être modifiées à tout moment et s'appliquent aux opérations suivantes ; la règle la plus précise l'emporte (application, puis plateforme ; pays, puis tous pays ; moyen précis, puis Mobile Money en général, puis tous les moyens).

| Règle | Effet |
|---|---|
| Montant minimum et maximum par transaction | encaissements et envois, par moyen de paiement |
| Plafond par jour et par numéro Mobile Money (SIM) | envois vers un même numéro, tous envois confondus |
| Plafond par jour et par application | envois de votre application, vers des numéros Mobile Money ou vers des comptes Redacok |
| Délai de disponibilité | durée pendant laquelle un encaissement reste dans le solde « en cours » avant de passer au solde « disponible » (partie 6) |

Le jour s'entend à l'heure du Cameroun (minuit à minuit). Les montants sont exprimés dans la monnaie du pays concerné.

**Valeurs au lancement** (modifiables par Redacok, le support vous communique celles qui s'appliquent à votre application) :

- envois vers un numéro Mobile Money : **500 000 par numéro (SIM) et par jour**, dans la monnaie du pays (par exemple 500 000 FCFA au Cameroun), quel que soit l'opérateur ;
- envois vers des comptes Redacok : **5 000 000 FCFA par jour et par application** en traitement automatique ; au-delà, l'opération doit être **vérifiée et les fonds justifiés** par le support Redacok.

Quand une règle est dépassée, l'appel est refusé avec un message explicite (« Montant trop faible », « Montant trop élevé », « Plafond atteint »…). Rien n'est alors débité.

Les plafonds propres aux opérateurs et aux banques (encaissements, cartes) s'ajoutent à ceux de Redacok.
