> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mercy-pay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Demander un retrait

> Demande un versement de votre solde vers un compte mobile money. Clé live seulement. La demande est validée avant d'être envoyée à l'opérateur.

> [!NOTE]
>
> En live, il faut que votre vérification d'identité soit approuvée. En sandbox, le retrait part tout de suite depuis votre solde de test, vers un numéro Mobile Money de test.

La demande n'est pas exécutée tout de suite : elle est d'abord validée, puis envoyée à l'opérateur. Suivez-la avec les webhooks `payout.*`. Voir [Demander un retrait](https://docs.mercy-pay.com/payouts/request-a-payout.md).

| Erreur | Cause |
| - | - |
| `422` `Solde disponible insuffisant pour ce montant.` | Le solde du pays et de l'opérateur ne couvre pas le retrait |
| `422` `Opérateur Mobile Money invalide pour ce pays.` | Code opérateur incohérent avec le pays |


## OpenAPI

````yaml POST /api/v1/payouts
openapi: 3.1.0
info:
  title: API Mercy Pay
  version: 1.0.0
  description: >-
    Encaissez par mobile money et par carte, facturez en récurrent et versez vos
    fonds. Les montants sont des entiers en unités mineures. Chaque réponse
    porte un en-tête `Request-Id`.
servers:
  - url: https://mercy-pay.com
    description: >-
      Production. La clé choisit l'environnement : `mp_sandbox_…` ou
      `mp_live_…`.
security:
  - bearerAuth: []
tags:
  - name: Compte
  - name: Sessions de paiement
  - name: Paiements
  - name: Remboursements
    description: Rendre un paiement au client, en entier.
  - name: Liens de paiement
  - name: Plans
  - name: Abonnements
  - name: Clients
  - name: Factures
  - name: Espace client
  - name: Soldes
  - name: Retraits
  - name: État des opérateurs
  - name: Événements
    description: Tout ce qui s'est passé sur le compte, envoyé ou non à un endpoint.
  - name: Endpoints de webhook
    description: Les URL de votre serveur qui reçoivent les événements.
paths:
  /api/v1/payouts:
    post:
      tags:
        - Retraits
      summary: Demander un retrait
      description: >-
        Demande un versement de votre solde vers un compte mobile money. Clé
        live seulement. La demande est validée avant d'être envoyée à
        l'opérateur.
      operationId: createPayout
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - amount
                - currency
              properties:
                amount:
                  type: integer
                  description: Montant débité de votre solde, en unités mineures
                  minimum: 1
                currency:
                  type: string
                  description: >-
                    Devise du solde source. Code devise ISO 4217 de 3 lettres,
                    par exemple `XAF`.
                  minLength: 3
                  maxLength: 3
                destination_id:
                  type: string
                  description: >-
                    Compte de retrait enregistré dans votre tableau de bord.
                    Remplace `destination`.
                  format: uuid
                destination:
                  type: object
                  description: Obligatoire sans `destination_id`.
                  required:
                    - type
                    - country
                    - provider
                    - phone
                  properties:
                    type:
                      type: string
                      description: Type
                      enum:
                        - mobile_money
                    country:
                      type: string
                      description: Pays ISO 3166-1 alpha-3, par exemple `CMR`.
                    provider:
                      type: string
                      description: >-
                        Code opérateur, par exemple `MTN_MOMO_CMR`. Voir [Pays
                        et opérateurs](/payments/overview#pays-et-operateurs).
                    phone:
                      type: string
                      description: Numéro avec indicatif, sans `+`
                      maxLength: 20
                metadata:
                  type: object
                  additionalProperties: true
                  description: >-
                    Vos données libres (jusqu'à 50 clés, valeurs de 500
                    caractères au plus), renvoyées dans les réponses et les
                    webhooks. Par exemple votre numéro de commande.
            example:
              amount: 4000
              currency: XAF
              destination:
                type: mobile_money
                country: CMR
                provider: MTN_MOMO_CMR
                phone: '237680000000'
      responses:
        '201':
          description: Retrait demandé
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Payout'
              example:
                data:
                  id: po_a9d4e6f21b3c4e5d8f702c9b6a1e3d48
                  object: payout
                  livemode: false
                  created: '2026-10-03T10:12:00+00:00'
                  amount: 4000
                  fee_amount: 80
                  net_amount: 3920
                  currency: XAF
                  destination:
                    type: mobile_money
                    country: CMR
                    provider: MTN_MOMO_CMR
                    phone: '237680000000'
                  status: requested
                  origin: api
                  failure_code: null
                  failure_reason: null
                  metadata: null
        '400':
          $ref: '#/components/responses/IdempotencyMissing'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          description: Solde insuffisant ou opérateur invalide
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: invalid_request_error
                  code: validation_failed
                  message: Solde disponible insuffisant pour ce montant.
                  param: amount
                  doc_url: >-
                    https://docs.mercy-pay.com/developers/errors#validation_failed
                  request_id: req_01jc8x4m2v7t9qk3n5w6y8z0ab
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  parameters:
    IdempotencyKeyRequired:
      name: Idempotency-Key
      in: header
      required: true
      schema:
        type: string
        maxLength: 255
      description: >-
        Obligatoire ici. Une clé unique par opération : la rejouer pendant 24
        heures renvoie la même réponse sans rien créer de plus. Voir
        [Idempotence](/developers/idempotency).
  schemas:
    Payout:
      type: object
      properties:
        id:
          type: string
          description: Identifiant du retrait (`po_…`)
        object:
          type: string
          const: payout
        livemode:
          type: boolean
          description: '`true` pour de l''argent réel (clé live), `false` en sandbox'
        created:
          type:
            - string
            - 'null'
          format: date-time
          description: Date de création, ISO 8601
        amount:
          type: integer
          description: Montant demandé, débité en totalité de votre solde.
        fee_amount:
          type: integer
          description: Commission Mercy Pay retenue, 2 % de `amount`.
        net_amount:
          type: integer
          description: Montant réellement envoyé (`amount` moins `fee_amount`).
        currency:
          type: string
          description: Devise du solde source
        destination:
          type: object
          properties:
            type:
              type: string
              description: Type de destination
              enum:
                - mobile_money
            country:
              type: string
              description: Pays ISO 3166-1 alpha-3, par exemple `CMR`.
            provider:
              type: string
              description: >-
                Code opérateur, par exemple `MTN_MOMO_CMR`. Voir [Pays et
                opérateurs](/payments/overview#pays-et-operateurs).
            phone:
              type: string
              description: Numéro avec indicatif, sans `+`
        status:
          type: string
          description: Voir [Retraits](/payouts/overview#statuts).
          enum:
            - requested
            - approved
            - processing
            - paid
            - failed
            - rejected
            - canceled
        status_detail:
          type:
            - string
            - 'null'
          description: >-
            Précise un retrait en cours. `delayed` : l'opérateur est
            indisponible et le retrait attend son retour, vous pouvez l'annuler.
            `pending_processing` : le retrait n'est pas encore parti, il partira
            automatiquement. `null` sinon.
          enum:
            - delayed
            - pending_processing
            - null
        origin:
          type:
            - string
            - 'null'
          description: >-
            D'où vient le retrait. Vide pour ceux créés avant le 7 novembre
            2026.
          enum:
            - dashboard
            - api
            - automatic
            - null
        failure_code:
          type:
            - string
            - 'null'
          description: >-
            Motif d'échec stable, par exemple `recipient_not_found`. Voir
            [Erreurs](/developers/errors)
        failure_reason:
          type:
            - string
            - 'null'
          description: Raison de l'échec ou du refus
        metadata:
          type:
            - object
            - 'null'
          additionalProperties: true
          description: Vos données libres. Voir [Metadata](/developers/metadata).
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            type:
              type: string
              enum:
                - authentication_error
                - invalid_request_error
                - idempotency_error
                - payment_error
                - rate_limit_error
                - api_error
            code:
              type: string
              description: Code stable, à tester dans votre code
            message:
              type: string
              description: Explication en français, pour un humain
            param:
              type:
                - string
                - 'null'
              description: Le premier champ en cause
            doc_url:
              type: string
              description: Explication de ce code
            request_id:
              type: string
              description: >-
                Identifiant de la requête (`req_…`), aussi dans l'en-tête
                `Request-Id`
            errors:
              type: object
              additionalProperties:
                type: array
                items:
                  type: string
              description: Détail par champ refusé, sur une erreur `422`
      required:
        - error
  responses:
    IdempotencyMissing:
      description: '`Idempotency-Key` absent'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: idempotency_error
              code: idempotency_key_missing
              message: L'en-tête Idempotency-Key est obligatoire.
              param: null
              doc_url: >-
                https://docs.mercy-pay.com/developers/errors#idempotency_key_missing
              request_id: req_01jc8x4m2v7t9qk3n5w6y8z0ab
    Unauthorized:
      description: Clé absente, invalide ou révoquée
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: authentication_error
              code: api_key_invalid
              message: Clé API invalide.
              param: null
              doc_url: https://docs.mercy-pay.com/developers/errors#api_key_invalid
              request_id: req_01jc8x4m2v7t9qk3n5w6y8z0ab
    Forbidden:
      description: Compte suspendu, ou clé live avant l'approbation du KYC
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: authentication_error
              code: live_mode_requires_kyc
              message: Le mode live demande un KYC approuvé.
              param: null
              doc_url: >-
                https://docs.mercy-pay.com/developers/errors#live_mode_requires_kyc
              request_id: req_01jc8x4m2v7t9qk3n5w6y8z0ab
    Conflict:
      description: Conflit avec l'état de la ressource, ou clé d'idempotence réutilisée
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: invalid_request_error
              code: conflict
              message: 'Cette ressource est utilisée : archivez-la.'
              param: null
              doc_url: https://docs.mercy-pay.com/developers/errors#conflict
              request_id: req_01jc8x4m2v7t9qk3n5w6y8z0ab
    RateLimited:
      description: Plus de 60 requêtes par minute avec cette clé
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: rate_limit_error
              code: rate_limited
              message: Trop de requêtes.
              param: null
              doc_url: https://docs.mercy-pay.com/developers/errors#rate_limited
              request_id: req_01jc8x4m2v7t9qk3n5w6y8z0ab
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Votre clé API. Utilisez une clé sandbox (`mp_sandbox_…`) pour essayer :
        aucun argent réel ne bouge.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.