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

# Configuration des webhooks

> Guide pas-à-pas pour configurer, sécuriser et monitorer vos webhooks Finkare.

## Vue d'ensemble

Les webhooks Finkare vous notifient en temps réel de chaque événement de recouvrement. Les payloads sont signés via HMAC-SHA256 pour garantir leur authenticité.

## Étape 1 — Créer un endpoint

Créez un endpoint HTTPS sur votre serveur qui accepte les requêtes POST :

```typescript theme={null}
// Express.js
import express from 'express';
import crypto from 'crypto';

const app = express();
app.use(express.json({ limit: '1mb' }));

app.post('/webhooks/finkare', (req, res) => {
  // 1. Vérifier la signature
  const signature = req.headers['x-finkare-signature'] as string;
  const payload = JSON.stringify(req.body);
  const expected = crypto
    .createHmac('sha256', process.env.FINKARE_WEBHOOK_SECRET!)
    .update(payload)
    .digest('hex');

  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
    console.error('Signature invalide');
    return res.status(401).json({ error: 'Invalid signature' });
  }

  // 2. Traiter l'événement
  const { event, data, timestamp } = req.body;

  switch (event) {
    case 'payment.received':
      console.log(`Paiement reçu : ${data.amountCents / 100} EUR pour ${data.invoiceId}`);
      // Mettre à jour votre système comptable
      break;

    case 'invoice.status_changed':
      console.log(`Facture ${data.invoiceId} : ${data.previousStatus} → ${data.newStatus}`);
      break;

    case 'workflow.action_triggered':
      console.log(`Action ${data.action} sur ${data.invoiceId} via ${data.channel}`);
      break;

    default:
      console.log(`Événement non géré : ${event}`);
  }

  // 3. Répondre 200 rapidement
  res.status(200).json({ received: true });
});

app.listen(3000);
```

<Warning>
  Répondez toujours avec un code HTTP **2xx** dans les **5 secondes**. Si votre traitement est long, acquittez d'abord le webhook puis traitez en arrière-plan (queue).
</Warning>

## Étape 2 — Enregistrer le webhook

```bash theme={null}
curl -X POST https://api.finkare.io/api/v1/webhooks \
  -H "X-API-Key: fk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://api.votre-entreprise.fr/webhooks/finkare",
    "events": [
      "payment.received",
      "invoice.status_changed",
      "workflow.action_triggered",
      "workflow.completed"
    ],
    "description": "Production — ERP sync"
  }'
```

Sauvegardez le `secret` retourné dans vos variables d'environnement :

```bash theme={null}
export FINKARE_WEBHOOK_SECRET="whsec_a1b2c3d4e5f6..."
```

## Étape 3 — Format des payloads

Chaque événement est envoyé avec cette structure :

```json theme={null}
{
  "id": "evt_a1b2c3d4",
  "event": "payment.received",
  "data": {
    "invoiceId": "c3d4e5f6-a1b2-7890-cdef-1234567890ab",
    "amountCents": 150000,
    "currency": "EUR",
    "method": "card",
    "paidAt": "2026-04-08T14:22:00Z"
  },
  "timestamp": "2026-04-08T14:22:01Z",
  "webhookId": "e5f6a7b8-c1d2-9012-ef01-345678901bcd"
}
```

### Headers envoyés

| Header                  | Description                                    |
| ----------------------- | ---------------------------------------------- |
| `Content-Type`          | `application/json`                             |
| `X-Finkare-Signature`   | Signature HMAC-SHA256 du body                  |
| `X-Finkare-Event`       | Type d'événement (ex : `payment.received`)     |
| `X-Finkare-Delivery-Id` | ID unique de la livraison (pour déduplication) |

## Vérification de signature

<CodeGroup>
  ```typescript Node.js theme={null}
  import crypto from 'crypto';

  function verifySignature(payload: string, signature: string, secret: string): boolean {
    const expected = crypto.createHmac('sha256', secret).update(payload).digest('hex');
    return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
  }
  ```

  ```python Python theme={null}
  import hmac
  import hashlib

  def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
      expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
      return hmac.compare_digest(signature, expected)
  ```

  ```java Java theme={null}
  import javax.crypto.Mac;
  import javax.crypto.spec.SecretKeySpec;

  public boolean verifySignature(String payload, String signature, String secret) throws Exception {
      Mac mac = Mac.getInstance("HmacSHA256");
      mac.init(new SecretKeySpec(secret.getBytes(), "HmacSHA256"));
      String expected = bytesToHex(mac.doFinal(payload.getBytes()));
      return MessageDigest.isEqual(expected.getBytes(), signature.getBytes());
  }
  ```
</CodeGroup>

## Politique de retry

| Tentative | Délai       | Timeout |
| --------- | ----------- | ------- |
| 1         | Immédiat    | 5s      |
| 2         | 30 secondes | 5s      |
| 3         | 5 minutes   | 5s      |
| 4         | 30 minutes  | 5s      |
| 5         | 2 heures    | 5s      |

Après 5 échecs consécutifs, le webhook est **automatiquement désactivé**. Vous recevez un email de notification à l'adresse associée à votre compte.

## Monitoring

Consultez l'historique des deliveries via l'API :

```bash theme={null}
curl -H "X-API-Key: fk_live_xxx" \
  https://api.finkare.io/api/v1/webhooks/e5f6a7b8-c1d2-9012-ef01-345678901bcd/deliveries
```

## Bonnes pratiques

1. **Répondre vite** : acquittez le webhook en \< 5s, traitez en async
2. **Déduplication** : utilisez le `X-Finkare-Delivery-Id` pour éviter les doublons
3. **Idempotence** : votre handler doit supporter les re-livraisons sans effet de bord
4. **Rotation régulière** : faites tourner le secret via `POST /webhooks/:id/rotate-secret`
5. **Alerting** : surveillez les erreurs 4xx/5xx dans vos logs pour détecter les problèmes rapidement
