Utilizzo di CertivantLive ID e sviluppatoriWebhook

Webhook

Ricevere eventi Certivant in tempo reale nei propri sistemi quando le verifiche cambiano stato. Copre configurazione, verifica della firma HMAC, pianificazione dei nuovi tentativi e riferimento completo dei tipi di evento.

Who can do this:Org ownerOrg admin— I membri hanno bisogno del permesso api.webhooks per visualizzare; la configurazione richiede il ruolo di amministratore.

La pagina Eventi webhook con la cronologia delle consegne in uscita: tipo di evento, URL di destinazione, stato della consegna, tentativi, codice di risposta e orario.

Cosa fa

Un webhook è un URL a cui inviamo una richiesta POST ogni volta che accade qualcosa nella propria organizzazione Certivant. Invece di interrogare la nostra API per sapere se qualcosa è cambiato ("la verifica è già terminata?"), si fornisce un URL e lo si avvisa nel momento in cui succede. Gli eventi webhook servono a tenere sincronizzati i propri sistemi: flussi di onboarding dei clienti, database dei rischi AML, tag nel CRM, cruscotti interni di conformità.

Dove si trova

KYC → Webhook nella barra laterale sinistra. (Gli eventi KYB vengono inviati agli stessi endpoint webhook: non esiste una configurazione separata per il KYB.)

Configurazione

Scegliere un URL dal proprio lato

Il proprio endpoint deve:

  • Accettare richieste POST HTTPS con Content-Type: application/json.
  • Rispondere rapidamente con 2xx (entro 5 secondi) per confermare la ricezione.
  • Verificare l'intestazione della firma (passaggio successivo) prima di fidarsi del payload.

Aggiungere l'URL a Certivant

KYC → Webhook → Aggiungi endpoint. Si apre un campo sul posto: incollare l'URL e fare clic su Salva (lo stesso URL può essere modificato in seguito in Impostazioni → KYC/B). La scheda Endpoint webhook mostra l'endpoint predefinito dell'organizzazione, gli eventuali endpoint per modulo e il segreto di firma.

La scheda Endpoint webhook: l'endpoint predefinito dell'organizzazione con il link Aggiungi endpoint, gli endpoint per modulo e il segreto di firma con il pulsante Ruota segreto.

Copiare il segreto di firma

Dopo il salvataggio viene mostrato un segreto di firma visualizzato una sola volta. Copiarlo subito: non viene più mostrato. Se lo si perde, occorre ruotarlo per ottenerne uno nuovo.

Verificare le firme dal proprio lato

Ogni richiesta ha un'intestazione X-Certivant-Signature-V2 nella forma t=<unix time>,v1=<hex>. Il valore v1 è l'HMAC-SHA256 del tempo unix, di un punto e del corpo grezzo della richiesta, firmato con il segreto appena copiato. Verificarlo, e rifiutare gli eventi il cui orario differisce di più di cinque minuti dal proprio orologio, prima di analizzare il payload. La procedura, con il codice in diversi linguaggi, è nella guida per sviluppatori.

La vecchia intestazione X-KYC-Signature-Legacy, che firmava solo il corpo, non viene più inviata (è stata rimossa il 24 ottobre 2026). Se il proprio ricevitore la controlla ancora, ogni evento fallirà la verifica: passare a X-Certivant-Signature-V2.

Pseudocodice:

const sig = req.headers["x-certivant-signature"];
const expected = hmac("sha256", secret).update(rawBody).digest("hex");
if (!timingSafeEqual(sig, expected)) return 401;

Non saltare questo passaggio. Senza la verifica della firma, chiunque indovini l'URL dell'endpoint può inviare eventi falsi.

Testare dalla dashboard

Nella pagina Sviluppatore, aprire la sezione Eventi webhook. Scegliere un evento nel menu Evento di prova: kyc.webhook.test (predefinito), kyc.request.created, kyc.request.approved, kyc.request.rejected oppure kyc.request.escalated, quindi fare clic su Invia un evento di prova. Certivant invia un evento sintetico al proprio endpoint, firmato esattamente come uno reale (X-Certivant-Signature-V2, con il proprio segreto webhook) e con test: true per distinguerlo. Verificare che l'endpoint risponda con un 2xx.

La sezione Eventi webhook della pagina Sviluppatore: l'elenco dei tipi di evento con una breve descrizione, il menu Evento di prova e il pulsante Invia un evento di prova.

Tipi di evento

EventoQuando
kyc.request.createdQualcuno ha creato una richiesta di verifica (dashboard, API o modulo pubblico).
kyc.request.documents_readyIl richiedente ha caricato tutti i documenti richiesti; l'elaborazione è iniziata.
kyc.request.approvedLo stato finale è APPROVED (automatico o manuale).
kyc.request.rejectedLo stato finale è REJECTED.
kyc.request.escalatedInviata alla revisione manuale.
kyc.request.cancelledUn revisore ha annullato la richiesta prima del completamento.
kyb.*Stessa struttura di kyc.*, ma per le verifiche aziendali.
monitoring.alert.createdÈ scattato un nuovo avviso di monitoraggio su un richiedente già approvato.
monitoring.alert.resolvedUn revisore ha risolto un avviso.
form.submittedUn invio tramite modulo pubblico. Utile quando si usa il modulo per raccogliere dati non KYC.
webhook.testL'evento di prova sintetico inviato con il pulsante Testa. Viene sempre inviato, indipendentemente dagli abbonamenti.

L'elenco completo e i payload JSON sono documentati in KYC → Sviluppatore → Eventi webhook.

Struttura del payload

Ogni evento ha la stessa struttura di base:

{
  "id": "evt_2k3f9a...",
  "type": "kyc.request.approved",
  "createdAt": "2026-05-27T14:30:00Z",
  "organizationId": "org_abc123",
  "data": { /* event-specific payload */ }
}

Il campo data varia a seconda del tipo di evento. Per esempio, kyc.request.approved invia:

{
  "request": { "id": "kyr_...", "status": "APPROVED", "type": "INDIVIDUAL", ... },
  "applicant": { "id": "ka_...", "fullName": "Jane Doe", "email": "...", ... },
  "decision": { "by": "auto" | "manual", "reviewerId": "user_..." | null, "note": "..." | null },
  "policy": {
    "id": "pol_..." | null,
    "name": "default-kyc-policy",
    "version": 3 | null,
    "isDefault": true,
    "decision": "approve" | "reject" | "escalate" | "live_verification",
    "rulesFired": ["tier1-disqualified", "approve-by-score"],
    "reason": "High-risk country",
    "liveVerificationRequired": true
  }
}

Il blocco policy (su kyc.request.approved / rejected / escalated) indica quale criterio di rischio ha deciso la richiesta e quali regole sono scattate. isDefault: true significa che è stato eseguito il criterio predefinito di Certivant (id/version sono la riga del criterio predefinito dell'organizzazione, oppure null se non è ancora stata creata); un criterio personalizzato riporta il proprio id, name e version memorizzati. rulesFired elenca gli id delle regole che hanno corrisposto, nell'ordine di valutazione: usarli per instradare i workflow a valle. reason è la motivazione della regola vincente, quando ne ha una. decision: "live_verification" (con liveVerificationRequired: true, su kyc.request.escalated) indica che il criterio richiede una verifica dell'identità dal vivo prima della decisione finale: la richiesta attende nella revisione manuale finché la chiamata non decide. Consultare Progettazione di un criterio di rischio.

Se si opera in modalità partner (un'organizzazione che serve molti clienti finali), ogni envelope dell'evento riporta anche subTenantName e subTenantExternalId, i tag impostati sulla richiesta quando è stata creata via API, così il proprio gestore può instradare il risultato al cliente finale corretto. Per la posizione esatta dei campi consultare il riferimento webhook per sviluppatori.

Nuovi tentativi

Se l'endpoint restituisce un valore diverso da 2xx (o va in timeout), ritentiamo con un backoff esponenziale:

tentativo 1: immediato
tentativo 2: 30 secondi dopo
tentativo 3: 5 minuti dopo
tentativo 4: 30 minuti dopo
tentativo 5: 2 ore dopo
tentativo 6: 6 ore dopo
tentativo 7: 24 ore dopo

Dopo 7 tentativi falliti l'evento viene contrassegnato come permanently_failed e non si ritenta più. Gli eventi falliti compaiono nella dashboard dei webhook con il loro ultimo errore; è possibile rilanciarne manualmente uno qualsiasi con Riprova.

Il proprio endpoint deve essere idempotente. Non deduplichiamo i nuovi tentativi lato nostro: il proprio endpoint vedrà lo stesso evento più volte se i primi tentativi sono andati in timeout ma alla fine sono riusciti. Basarsi sull'id dell'evento e saltarlo se è già stato elaborato.

Endpoint multipli

È possibile registrare più endpoint (per esempio uno per il CRM e uno per il data lake AML). Ognuno può abbonarsi a un insieme diverso di tipi di evento. I segreti di firma sono per endpoint: ruotarne uno non interrompe gli altri.

Webhook per modulo

Il webhook a livello di organizzazione si attiva per ogni evento rilevante. I moduli pubblici possono AVERE anche un URL webhook per modulo nelle proprie impostazioni: utile quando un modulo alimenta un sistema separato. I webhook per modulo si eseguono in aggiunta a quelli a livello di organizzazione.

La pagina KYC → Webhook ora elenca entrambi in un unico punto: l'URL webhook dell'organizzazione in alto e una riga per l'URL webhook di ciascun modulo sotto, così si vede ogni destinazione di consegna senza cercare nelle impostazioni dei singoli moduli.

La dashboard dei webhook

KYC → Webhook elenca ogni endpoint con:

  • URL dell'endpoint e nome descrittivo.
  • Stato: attivo / in pausa / in errore.
  • Ultima consegna: quando è stato inviato l'ultimo evento.
  • Tasso di successo: % dei tentativi che hanno restituito 2xx negli ultimi 7 giorni.
  • Consegne recenti: tabella degli eventi recenti con codice di stato, latenza e corpo della risposta.

Mettere in pausa un endpoint per interrompere le consegne senza perdere la configurazione.

Risoluzione dei problemi

Il mio endpoint riceve un volume di richieste eccessivo

Gli endpoint vengono chiamati una volta per evento, ma un'organizzazione molto attiva può generare decine di eventi al minuto. Rendere il proprio endpoint asincrono: accettare il POST, rispondere subito con 2xx ed elaborare il payload al di fuori del ciclo di vita della richiesta. Se serve rallentare l'invio, impostare l'opzione per endpoint Consegne simultanee massime.

La verifica della firma continua a fallire

Tre cause comuni:

  1. Analizzare il corpo prima di verificare la firma. Usare i byte grezzi. Per chi usa Express + body-parser: impostare bodyParser.raw({ type: 'application/json' }) specificamente per la rotta del webhook.
  2. Segreto sbagliato. Ruotarlo e incollarlo di nuovo.
  3. Modifica o trasformazione del corpo in un middleware (gzip, BOM, codifica). La firma è calcolata sui byte esatti che abbiamo inviato.

Gli eventi sembrano duplicati

Nuovi tentativi causati da risposte lente. Basarsi sull'event.id per l'idempotenza.

L'ordine degli eventi è importante, ma li ricevo fuori sequenza

Non garantiamo un ordine rigoroso tra tipi di evento diversi. Per l'ordine per singolo richiedente usare il campo createdAt dell'evento; l'ordine all'interno del ciclo di vita di un singolo richiedente è monotono.