Aller au contenu
LinkProfit

Webhooks

Livraisons d’événements signées : événements disponibles, vérification de X-LinkProfit-Signature en JavaScript et Python, reprises et état de défaillance.

Mis à jour le 13 août 2026

Les webhooks poussent les événements vers votre endpoint sous forme de requêtes POST en JSON — sans interrogation régulière. Enregistrez les endpoints dans le tableau de bord (Réglages → Webhooks) ou via POST /v1/webhooks ; le secret de signature est affiché une seule fois, à la création.

Événements

| Événement | Se déclenche quand | Disponible pour | |---|---|---| | link.created / link.updated / link.deleted | Un lien change — via le tableau de bord, l’API ou un import en masse | endpoints d’espace de travail et partenaires | | domain.pending_ssl | DNS vérifié, certificat en cours d’émission | espace de travail et partenaire | | domain.activated | Le domaine sert du trafic | espace de travail et partenaire | | domain.error | Le provisionnement a échoué ; détails à l’intérieur | espace de travail et partenaire | | click.threshold | 80 % / 100 % de la limite mensuelle de clics suivis | espace de travail et partenaire | | conversion.created | Une conversion a été enregistrée : une commande, une inscription ou un objectif personnalisé attribué à un clic | espace de travail et partenaire | | workspace.subscribed | Un client a payé la première facture d’un abonnement | partenaire uniquement | | workspace.past_due | Le paiement d’un client a échoué | partenaire uniquement | | workspace.suspended | Un client a été suspendu (relance ou action manuelle) | partenaire uniquement | | payment.succeeded | Un paiement client a été réglé, avec le détail des frais | partenaire uniquement | | payment.refunded | Un paiement a été remboursé | partenaire uniquement |

La livraison

POST /your/endpoint HTTP/1.1
Content-Type: application/json
X-LinkProfit-Event: link.created
X-LinkProfit-Delivery: dlv_8Yq2…
X-LinkProfit-Signature: t=1755081600,v1=5f8a2c…
{
  "id": "dlv_8Yq2…",
  "type": "link.created",
  "created_at": "2026-08-13T10:00:00.000Z",
  "data": { "id": "lnk_…", "domain": "go.your-brand.com", "slug": "x7f2q1z", "url": "https://example.com" }
}

Répondez par n’importe quel 2xx en moins de 10 secondes. Tout le reste — y compris un délai dépassé — compte comme un échec et programme une reprise. Les livraisons peuvent arriver dans le désordre et, rarement, deux fois : dédupliquez par id.

Vérifier la signature

La signature est un HMAC-SHA256 sur `${t}.${rawBody}` avec le secret de votre endpoint, encodé en hexadécimal. Vérifiez toujours contre le corps de requête brut, avant tout parsing JSON, et rejetez les horodatages de plus de 5 minutes.

import { createHmac, timingSafeEqual } from "node:crypto";

function verifySignature(secret, rawBody, header, toleranceSeconds = 300) {
  const parts = Object.fromEntries(
    header.split(",").map((piece) => piece.split("=", 2)),
  );
  if (!parts.t || !parts.v1) return false;
  if (Math.abs(Date.now() / 1000 - Number(parts.t)) > toleranceSeconds) return false;

  const expected = createHmac("sha256", secret)
    .update(`${parts.t}.${rawBody}`)
    .digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(parts.v1);
  return a.length === b.length && timingSafeEqual(a, b);
}
import hashlib
import hmac
import time


def verify_signature(secret: str, raw_body: bytes, header: str, tolerance: int = 300) -> bool:
    parts = dict(piece.split("=", 1) for piece in header.split(",") if "=" in piece)
    timestamp, signature = parts.get("t"), parts.get("v1")
    if not timestamp or not signature:
        return False
    if abs(time.time() - int(timestamp)) > tolerance:
        return False

    expected = hmac.new(
        secret.encode(), f"{timestamp}.".encode() + raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

Reprises et état de défaillance

La première tentative est immédiate. Les échecs sont retentés selon un calendrier fixe : 1 min → 5 min → 30 min → 2 h → 12 h. Après la cinquième reprise, l’endpoint est marqué failing, cesse de recevoir de nouveaux événements et son propriétaire reçoit un e-mail.

Corrigez l’endpoint, puis réactivez-le dans le tableau de bord ou avec PATCH /v1/webhooks/{id} et {"status": "active"}. Les événements manqués ne sont pas rejoués automatiquement — le journal de livraison (GET /v1/webhooks/{id}/deliveries ou le tableau de bord) montre chaque charge utile pour que vous puissiez faire le rapprochement.

Une livraison réussie remet à zéro la série d’échecs.

Tester

Le bouton Envoyer un test (ou POST /v1/webhooks/{id}/test) livre un vrai événement signé, avec "data": { "test": true }, par la même chaîne que les événements de production — le journal de livraison affiche la réponse de votre endpoint.