Vai al contenuto
LinkProfit

Webhook

Consegne di eventi firmate: eventi disponibili, verifica di X-LinkProfit-Signature in JavaScript e Python, tentativi ripetuti e stato failing.

Aggiornato il 13 agosto 2026

I webhook inviano gli eventi al tuo endpoint come richieste POST in JSON: niente polling. Registra gli endpoint nella dashboard (Impostazioni → Webhook) o tramite POST /v1/webhooks; il segreto di firma viene mostrato una sola volta, al momento della creazione.

Eventi

| Evento | Si attiva quando | Disponibile per | |---|---|---| | link.created / link.updated / link.deleted | Un link cambia — dalla dashboard, dall'API o da un'importazione in blocco | endpoint di area di lavoro e partner | | domain.pending_ssl | Il DNS è verificato, il certificato è in emissione | area di lavoro e partner | | domain.activated | Il dominio serve traffico | area di lavoro e partner | | domain.error | Il provisioning non è riuscito; i dettagli sono all'interno | area di lavoro e partner | | click.threshold | 80% / 100% del limite mensile di clic tracciati | area di lavoro e partner | | conversion.created | Una conversione è stata registrata: un ordine, una registrazione o un obiettivo personalizzato attribuito a un clic | area di lavoro e partner | | workspace.subscribed | Un cliente ha pagato la prima fattura di un abbonamento | solo partner | | workspace.past_due | Il pagamento di un cliente non è andato a buon fine | solo partner | | workspace.suspended | Un cliente è stato sospeso (dunning o manualmente) | solo partner | | payment.succeeded | Un pagamento di un cliente è stato incassato, con il dettaglio delle commissioni | solo partner | | payment.refunded | Un pagamento è stato rimborsato | solo partner |

La consegna

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" }
}

Rispondi con un qualsiasi 2xx entro 10 secondi. Qualunque altra cosa — timeout compreso — conta come errore e programma un nuovo tentativo. Le consegne possono arrivare fuori ordine e, raramente, due volte: deduplica in base a id.

Verificare la firma

La firma è un HMAC-SHA256 calcolato su `${t}.${rawBody}` con il segreto del tuo endpoint, codificato in esadecimale. Verificala sempre sul corpo grezzo della richiesta, prima di qualsiasi parsing JSON, e rifiuta i timestamp più vecchi di 5 minuti.

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)

Tentativi ripetuti e stato failing

Il primo tentativo è immediato. In caso di errore, i tentativi seguono una pianificazione fissa: 1 min → 5 min → 30 min → 2 h → 12 h. Dopo il quinto tentativo l'endpoint viene contrassegnato come failing, smette di ricevere nuovi eventi e il proprietario riceve un'email.

Sistema l'endpoint, poi riattivalo dalla dashboard o con PATCH /v1/webhooks/{id} e {"status": "active"}. Gli eventi persi non vengono riconsegnati automaticamente: il log delle consegne (GET /v1/webhooks/{id}/deliveries o la dashboard) mostra ogni payload, così puoi fare la riconciliazione.

Una consegna riuscita azzera la serie di errori.

Test

Il pulsante Invia test (o POST /v1/webhooks/{id}/test) consegna un evento reale e firmato, con "data": { "test": true }, attraverso la stessa pipeline degli eventi di produzione: il log delle consegne mostra la risposta del tuo endpoint.