ffacturifirma

Documentazione

Webhooks

Ricevi notifiche HTTP firmate nei tuoi sistemi ogni volta che un documento cambia in facturifirma.ro.

Registrare un webhook

Dall'app: pagina Webhooks (menu amministrazione) — aggiungi l'URL di destinazione e un segreto di firma. Il segreto è write-only: non può essere riletto dopo il salvataggio.

Via API, con una chiave API amministratore:

curl -X POST https://app.facturifirma.ro/api/v1/webhooks \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/webhook", "secret": "<SIGNING_SECRET>"}'

Eventi

Attualmente viene inviato un solo tipo di evento:

document.changedqualsiasi modifica di un documento — creazione, modifica, emissione, incasso, storno, annullamento o eliminazione, per ogni tipo di documento (fattura, proforma, ricevuta, DDT, ordine, nota di credito).

Nuovi tipi di evento saranno aggiunti nel tempo; tratta il campo "event" come estensibile e ignora i tipi sconosciuti.

Payload

Ogni consegna è una POST con corpo JSON:

POST https://example.com/webhook

{
  "event": "document.changed",
  "documentId": "8b1f7c02-4c33-4a6e-9f0d-2f6f6f0a9d11",
  "at": "2026-07-15T09:30:00Z"
}

Header

Ogni richiesta include il tipo di evento e la firma del corpo:

Content-Type: application/json
X-Facturifirma-Event: document.changed
X-Facturifirma-Signature: sha256=<hex(HMAC-SHA256(secret, body))>

Verificare la firma

La firma è HMAC-SHA256 sul corpo grezzo della richiesta con il tuo segreto, nel formato "sha256=<hex>". Confrontala in tempo costante:

import crypto from "node:crypto";

function verify(rawBody, signatureHeader, secret) {
  const expected = "sha256=" +
    crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signatureHeader), Buffer.from(expected));
}

Consegna e retry

Le consegne partono da una coda di job con retry automatici (at-least-once, nessuna garanzia di ordine). Il tuo endpoint deve rispondere 2xx; qualsiasi altra risposta conta come errore e viene ritentata.

Sicurezza

Sono accettati solo URL http(s) assoluti che risolvono verso indirizzi pubblici (protezione SSRF). Il segreto di firma è cifrato at-rest e non viene mai restituito dall'API.