Documentation /Programmer les retraits

Retraits programmés

Permettez à vos utilisateurs finaux de programmer et d’exécuter des retraits d'argent depuis votre compte, sans passer par l’espace partenaire OpenPay.

Intégrez les retraits dans votre app ou site : vos utilisateurs finaux n’ont pas besoin de l’espace partenaire OpenPay pour retirer de l’argent. Ils peuvent programmer un retrait vers leur mobile money, puis l’exécuter une fois approuvé par OpenPay.

Prérequis

Avant d’appeler ces endpoints, configurez votre plateforme depuis le tableau de bord partenaire (onglet IP autorisées).

  • Activer Retraits programmés pour vos clients.
  • Enregistrer au moins une adresse IPv4 autorisée.
  • Authentifier chaque requête avec le header XO-API-KEY (voir Authentification).
  • Configurer une callback URL pour être notifié à l’approbation (recommandé).

Flux recommandé

  1. Votre backend appelle POST/scheduled-cashout, le retrait passe en pending.
  2. OpenPay examine et approuve la demande, puis un POST est envoyé sur votre callback URL.
  3. Votre backend reçoit le callback ou interroge GET …/api/:reference jusqu’à obtenir approved.
  4. Vous appelez POST/scheduled-cashout/:reference/execute pour déclencher le virement vers le mobile money du bénéficiaire.

1. Créer un retrait programmé

POST https://api.openpay-cg.com/v1/scheduled-cashout

Paramètres du corps (JSON)

amountObligatoire

number

Montant du retrait en XAF

phone_numberObligatoire

string

Numéro bénéficiaire au format 242XXXXXXXXX

execution_dateObligatoire

string

Date et heure souhaitées du retrait au format ISO 8601. Doit être au minimum 24 h après l’instant de la requête. Exemple : 2026-10-20T08:00:00.000Z

providerOptionnel

string

Opérateur : MTN ou AIRTEL. Déduit automatiquement du numéro si omis.

origin_appObligatoire

string

Identifiant de votre application cliente (ex. nom de l’app mobile).

referenceObligatoire

string

Identifiant unique du retrait, généré par votre système (UUID v4). Sert à consulter, annuler et exécuter le retrait via l’API.

client_emailOptionnel

string

E-mail du client final. S’il est renseigné, OpenPay envoie un message lorsque le retrait passe au statut approved.

Exemple de requête

JSON body
{
  "amount": 50000,
  "phone_number": "242066203420",
  "provider": "MTN",
  "execution_date": "2026-10-20T08:00:00.000Z",
  "origin_app": "MonApp Mobile v2",
  "reference": "550e8400-e29b-41d4-a716-446655440000",
  "client_email": "client@exemple.cg"
}

Réponse de succès

JSON201 Created
{
  "success": true,
  "data": {
    "reference": "550e8400-e29b-41d4-a716-446655440000",
    "amount": "50000.00",
    "phone_number": "242066203420",
    "provider": "MTN",
    "status": "pending",
    "execution_date": "2026-10-20T08:00:00.000Z",
    "origin_app": "MonApp Mobile v2",
    "createdAt": "2026-10-13T14:00:00.000Z",
    "updatedAt": "2026-10-13T14:00:00.000Z"
  }
}

Callback à l’approbation

Dès qu’un retrait programmé est approuvé par OpenPay, nous envoyons un POST JSON vers le callback_url configuré sur votre plateforme (relances et timeout identiques aux callbacks paiement). Votre endpoint doit répondre HTTP 200.

Payload - event approvedPOST
{
  "reference": "550e8400-e29b-41d4-a716-446655440000",
  "amount": "50000.00",
  "currency": "XAF",
  "paymentPhoneNumber": "242066203420",
  "provider": "MTN",
  "type": "scheduled_cashout",
  "status": "approved",
  "message": "Retrait programmé approuvé. Vous pouvez déclencher l'exécution via l'API.",
  "metadata": {
    "event": "approved",
    "execution_date": "2026-10-20T08:00:00.000Z",
    "origin_app": "MonApp Mobile v2"
  }
}

2. Statuts d’un retrait

Le champ status évolue selon le cycle de vie suivant.

StatutSignificationAction côté intégration
pendingDemande enregistrée, en attente d’approbation OpenPayAttendre le passage au statut approved
approvedRetrait validé par OpenPayAppeler POST …/execute pour déclencher le virement
completedRetrait effectué avec succèsAucune action requise
cancelledDemande annulée (API ou partenaire)Créer une nouvelle demande si nécessaire
rejectedDemande refusée par OpenPayContacter le support ou reprogrammer

3. Consulter les retraits

GET https://api.openpay-cg.com/v1/scheduled-cashout

Retourne les 50 derniers retraits programmés de votre plateforme.

GET https://api.openpay-cg.com/v1/scheduled-cashout/:reference

Détail d’un retrait par son reference (UUID v4).

JSON200 OK
{
  "success": true,
  "data": {
    "reference": "550e8400-e29b-41d4-a716-446655440000",
    "status": "approved",
    "amount": "50000.00",
    "phone_number": "242066203420",
    "provider": "MTN",
    "execution_date": "2026-10-20T08:00:00.000Z",
    "origin_app": "MonApp Mobile v2"
  }
}

4. Exécuter un retrait approuvé

À n’appeler que lorsque le statut est approved. Le virement mobile money est alors initié vers le numéro enregistré.

POST https://api.openpay-cg.com/v1/scheduled-cashout/:reference/execute
JSON200 OK
{
  "success": true,
  "message": "Retrait effectué avec succès",
  "data": {
    "reference": "550e8400-e29b-41d4-a716-446655440000",
    "status": "completed",
    "amount": "50000.00",
    "phone_number": "242066203420",
    "provider": "MTN",
    "execution_date": "2026-10-20T08:00:00.000Z",
    "origin_app": "MonApp Mobile v2"
  }
}

En cas de statut autre que approved, l’API renvoie une erreur 400 avec le message indiquant que le retrait doit être approuvé avant exécution.

5. Annuler une demande

Uniquement tant que le retrait est encore en pending.

DELETE https://api.openpay-cg.com/v1/scheduled-cashout/:reference

Réponse attendue : { "success": true, "message": "Retrait annulé" }. Si le retrait n’est plus en attente, vous recevez une erreur 400.

Erreurs fréquentes

Code HTTPContexte
403 Option API non activée, plateforme bloquée, ou IP absente de la liste autorisée
400 Validation (ex. execution_date < 24 h), solde plateforme ou solde opérateur (MTN/Airtel) insuffisant pour le montant demandé
409reference déjà utilisée sur cette plateforme

Liste complète des codes : Codes de réponse et erreurs.