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

# Gérer les webhooks

> Recevez les événements de paiement et de payout, vérifiez leur signature et traitez-les une seule fois.

Mercy Pay envoie un événement à votre serveur à chaque changement de statut d'un paiement ou d'un payout. C'est la seule source sur laquelle vous pouvez vraiment vous appuyer pour confirmer un encaissement, bien plus fiable qu'une redirection navigateur.

<Steps>
  <Step title="Déclarez l'endpoint">
    Depuis **Webhooks** dans votre tableau de bord, ajoutez une URL HTTPS publique et cochez les événements voulus. Mercy Pay affiche alors le **secret de signature** (`whsec_…`) : copiez-le immédiatement, il ne sera plus affiché.
  </Step>

  <Step title="Vérifiez la signature">
    Chaque requête porte l'en-tête `X-MercyPay-Signature`, égal au HMAC-SHA256 en hexadécimal du **corps brut** de la requête, calculé avec votre secret. Voir [Sécurité des webhooks](/webhooks/security).

    ```javascript theme={null}
    import crypto from 'node:crypto';

    export function isAuthentic(rawBody, signatureHeader, secret) {
      const expected = crypto
        .createHmac('sha256', secret)
        .update(rawBody)
        .digest('hex');

      return crypto.timingSafeEqual(
        Buffer.from(expected),
        Buffer.from(signatureHeader ?? ''),
      );
    }
    ```

    Vérifiez le corps tel qu'il est reçu, avant tout `JSON.parse`.
  </Step>

  <Step title="Répondez vite, traitez après">
    Répondez `2xx` dès que la signature est validée, avant de lancer un traitement lourd. Mercy Pay n'attend que 10 secondes. Passé ce délai, ou sur une réponse qui n'est pas `2xx`, la livraison est considérée en échec et reprise plus tard.

    | Tentative | Délai après l'échec |
    | - | - |
    | 1 | immédiate |
    | 2 | 1 minute |
    | 3 | 5 minutes |
    | 4 | 15 minutes |
    | 5 | 1 heure |

    Après 5 tentatives infructueuses, Mercy Pay abandonne. À ce stade, l'information reste consultable via l'API : rien n'est perdu, mais vous ne serez plus relancé.
  </Step>

  <Step title="Dédupliquez par identifiant">
    Une même livraison peut vous arriver deux fois. Un réseau qui coupe juste après votre `2xx` suffit à le provoquer. Chaque événement porte un `id` (`evt_…`) : enregistrez ceux que vous avez déjà traités et ignorez les doublons.
  </Step>
</Steps>

## Exemple d'événement

```json theme={null}
{
  "id": "evt_01J9Z4K2M8TQ5VX3WB7NRY6HDA",
  "type": "payment.succeeded",
  "data": {
    "uuid": "5e0c8a7b-3d1f-4a2e-9c64-8b7f0d2e1a93",
    "checkout_session": "01J9Z3V8QK4M2XW7R6TB5N0HYD",
    "gross_amount": 15000,
    "psp_fee_amount": 300,
    "platform_fee_amount": 450,
    "net_amount_to_merchant": 14250,
    "currency": "XAF",
    "payment_method": "mobile_money",
    "mobile_money_country": "CMR",
    "mobile_money_provider": "MTN_MOMO_CMR",
    "psp_reference": "3a7f1e2c-8b4d-4e9a-a6f0-1d5c9e7b2f48",
    "status": "succeeded",
    "failure_reason": null,
    "created_at": "2026-10-03T10:20:00+00:00"
  }
}
```


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