Skip to main content
Tester en direct — Essayez ces endpoints dans la documentation interactive Scalar.

Lister les webhooks

Scope requis : webhooks:manage
curl -H "X-API-Key: fk_live_xxx" \
  https://api.finkare.io/api/v1/webhooks
{
  "success": true,
  "data": [
    {
      "id": "e5f6a7b8-c1d2-9012-ef01-345678901bcd",
      "url": "https://api.acme.fr/webhooks/finkare",
      "events": ["payment.received", "invoice.status_changed"],
      "description": "Webhook production ACME",
      "enabled": true,
      "created_at": "2026-03-01T10:00:00Z",
      "last_triggered_at": "2026-04-07T18:30:00Z"
    }
  ],
  "requestId": "req_wh_list_01",
  "timestamp": "2026-04-08T10:00:00Z"
}

Créer un webhook

Scope requis : webhooks:manage
url
string
required
URL de destination (HTTPS obligatoire)
events
array
required
Événements à écouter (voir tableau ci-dessous)
description
string
Description du webhook
enabled
boolean
default:"true"
Activer ou désactiver le webhook
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"
    ],
    "description": "Webhook principal production"
  }'
{
  "success": true,
  "data": {
    "id": "e5f6a7b8-c1d2-9012-ef01-345678901bcd",
    "url": "https://api.votre-entreprise.fr/webhooks/finkare",
    "events": ["payment.received", "invoice.status_changed", "workflow.action_triggered"],
    "enabled": true,
    "secret": "whsec_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6",
    "createdAt": "2026-04-08T10:00:00Z"
  },
  "message": "Webhook created. Save the secret - it will not be shown again.",
  "requestId": "req_wh_create_01",
  "timestamp": "2026-04-08T10:00:00Z"
}
Le secret de signature (whsec_...) est retourné une seule fois. Sauvegardez-le immédiatement. Il est utilisé pour vérifier l’authenticité des payloads via HMAC-SHA256.

Événements disponibles

ÉvénementDescription
invoice.createdNouvelle facture créée ou importée
invoice.updatedFacture mise à jour (metadata/notes)
invoice.status_changedChangement de statut d’une facture
payment.receivedPaiement reçu (total ou partiel)
payment.failedÉchec de paiement
workflow.startedWorkflow de recouvrement démarré
workflow.action_triggeredAction de recouvrement déclenchée (email, SMS, appel…)
workflow.completedWorkflow terminé (payé ou clôturé)
lrar.sentLRAR envoyée
lrar.deliveredLRAR distribuée (AR reçu)
debtor.contactedDébiteur contacté (email, SMS, appel)
debt.paidDossier marqué comme payé (preuve validée)
cascade.actionAction de cascade exécutée par Bob (pause, accélération)
judicial.startedProcédure judiciaire initiée
anr.createdAvis de Non Recouvrement généré

Récupérer un webhook

Scope requis : webhooks:manage
curl -H "X-API-Key: fk_live_xxx" \
  https://api.finkare.io/api/v1/webhooks/e5f6a7b8-c1d2-9012-ef01-345678901bcd

Mettre à jour un webhook

Scope requis : webhooks:manage
curl -X PUT https://api.finkare.io/api/v1/webhooks/e5f6a7b8-c1d2-9012-ef01-345678901bcd \
  -H "X-API-Key: fk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "events": ["payment.received", "invoice.status_changed", "debt.paid"],
    "description": "Webhook v2 — ajout événement debt.paid"
  }'

Supprimer un webhook

Scope requis : webhooks:manage
curl -X DELETE https://api.finkare.io/api/v1/webhooks/e5f6a7b8-c1d2-9012-ef01-345678901bcd \
  -H "X-API-Key: fk_live_xxx"
Retourne 204 No Content.

Régénérer le secret

Génère un nouveau secret et invalide l’ancien. Scope requis : webhooks:manage
curl -X POST https://api.finkare.io/api/v1/webhooks/e5f6a7b8-c1d2-9012-ef01-345678901bcd/rotate-secret \
  -H "X-API-Key: fk_live_xxx"
{
  "success": true,
  "data": {
    "secret": "whsec_nouveau_secret_genere_ici_abc123def456"
  },
  "message": "Secret rotated. Save the new secret - it will not be shown again."
}

Historique des deliveries

Consultez les tentatives de livraison (succès et échecs) pour un webhook. Scope requis : webhooks:manage
curl -H "X-API-Key: fk_live_xxx" \
  https://api.finkare.io/api/v1/webhooks/e5f6a7b8-c1d2-9012-ef01-345678901bcd/deliveries
{
  "success": true,
  "data": [
    {
      "id": "del_001",
      "eventType": "payment.received",
      "status": "delivered",
      "attempts": 1,
      "responseStatus": 200,
      "lastAttemptAt": "2026-04-07T18:30:00Z",
      "createdAt": "2026-04-07T18:30:00Z"
    },
    {
      "id": "del_002",
      "eventType": "invoice.status_changed",
      "status": "failed",
      "attempts": 3,
      "responseStatus": 500,
      "lastAttemptAt": "2026-04-07T19:15:00Z",
      "nextRetryAt": "2026-04-07T19:45:00Z",
      "createdAt": "2026-04-07T19:00:00Z"
    }
  ],
  "pagination": { "total": 2, "limit": 20, "offset": 0 }
}

Politique de retry

En cas d’échec de livraison (timeout ou code HTTP >= 400), Finkare retente automatiquement avec un backoff exponentiel :
TentativeDélai
1Immédiat
230 secondes
35 minutes
430 minutes
52 heures
Après 5 tentatives échouées, le webhook est automatiquement désactivé. Vous recevez une notification par email.

Vérification de signature

Chaque payload est signé via HMAC-SHA256. Vérifiez la signature pour garantir l’authenticité :
import crypto from 'crypto';

function verifyWebhookSignature(
  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),
  );
}

// Dans votre handler Express
app.post('/webhooks/finkare', (req, res) => {
  const signature = req.headers['x-finkare-signature'] as string;
  const isValid = verifyWebhookSignature(
    JSON.stringify(req.body),
    signature,
    process.env.FINKARE_WEBHOOK_SECRET!,
  );

  if (!isValid) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  // Traiter l'événement
  const { event, data } = req.body;
  console.log(`Événement reçu : ${event}`, data);

  res.status(200).json({ received: true });
});
Utilisez toujours timingSafeEqual (ou équivalent) pour la comparaison des signatures afin d’éviter les attaques timing.