Checkify
Documenti per sviluppatori

Verifica sul tuo backend

Una volta completato l'incorporamento nel browser, il tuo server deve verificare il risultato con una chiave API del sito prima di consentire la registrazione, il pagamento o qualsiasi azione protetta.

Verifica del server in 5 minuti

  1. Aggiungi il componente aggiuntivo del browser Checkify alla tua pagina.
  2. L'incorporamento avvia la sessione Checkify e scrive il riferimento di verifica nel tuo modulo.
  3. Il tuo backend legge il valore del campo nascosto.
  4. Il tuo backend invia quel valore a POST /v1/qr/results/verify come request_id.
  5. Se le richieste necessarie vengono approvate, autorizzare l'azione protetta.
  6. Non affidarti mai esclusivamente allo stato del frontend.

Il campo nascosto del modulo può essere denominato checkify_token, ma il suo valore è Checkify request_id.

Flusso end-to-end

1. Crea una chiave API del sito

Nella dashboard aziendale, apri Sviluppatore e crea una chiave API del sito per il sito che stai integrando. Memorizzalo solo nelle variabili di ambiente del server: non inviarlo mai al browser.

Utilizzi il frontend SDK?

Non è necessario chiamare manualmente GET /v1/qr/pass/{PASS_ID}/start. L'embed Checkify JavaScript avvia la sessione, riceve il request_id e lo scrive automaticamente nel modulo.

Il tuo backend deve solo:

2. Ricevi il request_id sul tuo server

Il frontend SDK scrive il request_id Checkify in un campo modulo nascosto dopo che l'utente ha completato la verifica. Il nome del campo predefinito è checkify_token, ovvero il nome del campo, non un tipo di token separato. Invia il valore del campo all'endpoint di verifica come request_id.

Il passaggio di consegne tramite app mobile potrebbe restituire checkify_request_id nell'URL della pagina. Il componente SDK lo legge al caricamento; il server verifica comunque lo stesso valore di request_id.

Invia il modulo POST dal tuo frontend

{
  "email": "user@example.com",
  "checkify_token": "56a57761-ff5b-42f0-9c97-6c13e223e017"
}

Verifica la richiesta dal tuo backend

{
  "request_id": "56a57761-ff5b-42f0-9c97-6c13e223e017",
  "required_claims": ["human_verified"],
  "required_fields": [],
  "consume": true
}

Integrazione manuale del frontend

3. Test manuale con cURL

Gli sviluppatori backend normalmente non chiamano /start. Utilizzare questa sezione solo quando si crea un frontend personalizzato o si esegue il test senza l'embed. Gli URL in zsh/bash sono racchiusi tra virgolette in modo che ? non venga trattato come un carattere jolly.

L'intestazione Origin è necessaria per /start

L'avvio del passaggio funziona solo da un dominio web registrato. I browser inviano automaticamente l'origine; cURL no. Invia l'origine (o X-Checkify-Site-Url) con un nome host elencato in Siti → domini consentiti. Il nome host deve corrispondere esattamente: checkify.me e www.checkify.me sono diversi.

Il problema più comune durante i test

Se la richiesta /start restituisce un errore HTTP 403, il tuo Pass ID potrebbe comunque essere valido. La causa più comune è che il dominio della richiesta non è presente nell'elenco dei domini consentiti, oppure che è stato registrato www.example.com ma è stato utilizzato example.com (o viceversa).

Utilizza un sito di test dedicato e Pass nella tua dashboard Checkify per i test di integrazione. Le chiavi del sito API utilizzano il prefisso csk_; non esiste un formato di chiave di test separato. Non eseguire test sul checkout di produzione finché non hai confermato sia i flussi di successo che quelli di rifiuto.

# Step A — start a session (replace PASS_ID and YOUR_REGISTERED_DOMAIN)
curl -sS \
  -H "Accept: application/json" \
  -H "Origin: https://YOUR_REGISTERED_DOMAIN" \
  "https://checkify.me/v1/qr/pass/chk_live_YOUR_PASS_ID/start?request_type=human"

# Response includes request_id and qr_url — open qr_url and complete verification

# Step B — verify on your server (after the user completes verification)
curl -sS -X POST "https://checkify.me/v1/qr/results/verify" \
  -H "Authorization: Bearer $CHECKIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "request_id": "PASTE_request_id_FROM_STEP_A",
    "required_claims": ["human_verified"],
    "consume": true
  }'

Utilizza la chiave del tuo sito API solo durante la chiamata di verifica. Completa la verifica nell'app prima di chiamare per la verifica, altrimenti lo stato sarà in sospeso.

Dichiarazioni richieste per caso d'uso

Imposta required_claims in modo che corrisponda alla prova necessaria per la tua azione protetta. I nomi delle attestazioni devono corrispondere a quelli approvati da Checkify per quella sessione di verifica. I controlli dell'età utilizzano age_over_{N} (ad esempio age_over_18). Sono supportate soglie dinamiche da 10 a 110 quando l'embed richiede il tipo di richiesta corrispondente.

Caso d'uso Richieste di informazioni richieste suggerite Note
Sostituzione del bot / CAPTCHA ["human_verified"] Conferma che un utente reale ha completato il flusso Checkify.
Contenuti adatti a un pubblico di età superiore ai 13 anni o prodotti destinati ai giovani. ["age_over_13"] Da utilizzare quando il tuo Pass richiede un'età superiore ai 13 anni.
Contenuti per maggiori di 16 anni o norme regionali sull'età ["age_over_16"] Da utilizzare quando il tuo Pass richiede età superiore a 16 anni.
Vietato l'acquisto di sigarette elettroniche, alcolici o prodotti per maggiori di 18 anni. ["age_over_18"] Adatta la soglia di età al tuo prodotto e al tuo mercato.
Prodotti soggetti a restrizioni di età pari o superiore a 21 anni (ove applicabile) ["age_over_21"] Da utilizzare quando il tuo Pass richiede un'età superiore ai 21 anni.
Sfida dei 25 anni o una politica di vendita al dettaglio più rigorosa ["age_over_25"] Da utilizzare quando il tuo Pass richiede un'età superiore ai 25 anni.
Soglia di età personalizzata ["age_over_N"] Utilizza age_over_N dove N è compreso tra 10 e 110, in linea con il tipo di richiesta di incorporamento.

Tipo di richiesta di incorporamento → richiesta del server

Il tipo di richiesta del browser deve corrispondere all'asserzione che verifichi lato server.

Tipo di richiesta di incorporamentorichieste_richieste
human["human_verified"]
age_over_13["age_over_13"]
age_over_16["age_over_16"]
age_over_18["age_over_18"]
age_over_21["age_over_21"]
age_over_25["age_over_25"]
age_over_N["age_over_N"] (N = 10–110)

Campi obbligatori facoltativi

Oltre a required_claims, puoi richiedere campi di identità approvati specifici (ad es. paese o fascia di età) se la tua integrazione li ha raccolti. Passa i nomi in required_fields — se mancano nel risultato approvato, verify restituisce missing_required_fields con missing_fields in error.details.

4. Esegui la chiamata verifica sul tuo server

Effettua una chiamata POST a /v1/qr/results/verify con la chiave API del tuo sito prima di concedere l'accesso. Considera il riferimento del browser (request_id o token di polling legacy) come non attendibile finché Checkify non conferma il risultato.

POST https://checkify.me/v1/qr/results/verify
Authorization: Bearer YOUR_SITE_API_KEY
Content-Type: application/json

{
  "request_id": "56a57761-ff5b-42f0-9c97-6c13e223e017",
  "required_claims": ["human_verified"],
  "consume": true
}

Puoi anche inviare token invece di request_id. La chiave API è associata al tuo sito Checkify: non devi inviare site_id nel corpo della richiesta.

Esempi di implementazione

# checkify_token from your form POST is sent as request_id
curl -sS -X POST "https://checkify.me/v1/qr/results/verify" \
  -H "Authorization: Bearer $CHECKIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "request_id": "56a57761-ff5b-42f0-9c97-6c13e223e017",
    "required_claims": ["human_verified"],
    "consume": true
  }'

Quando usare consumare

Utilizzare consume: true per le azioni protette finali — Pagamento, registrazione, reimpostazione password, acquisto con restrizioni di età, accesso a contenuti protetti

Utilizzare consume: false solo per — test, debug o verifiche non definitive in cui il risultato deve essere verificato nuovamente in seguito

Per le azioni regolamentate o ad alto rischio, è preferibile utilizzare `consume: true` in modo che lo stesso risultato della verifica non possa essere riutilizzato per più decisioni protette.

Mancata chiusura per azioni regolamentate

Se il tuo backend non riesce a raggiungere Checkify, non consentire il checkout con restrizioni di età, l'accesso al gioco d'azzardo, l'accesso a contenuti per adulti, l'acquisto di sigarette elettroniche o alcolici o altre azioni protette senza una conferma lato server.

Utilizzare timeout HTTP brevi (ad esempio 10 secondi). Riprovare una o due volte in caso di errori 5xx o di rete temporanei, quindi negare l'accesso. Registrare gli incidenti lato server e mostrare messaggi sicuri per l'utente. Non divulgare ai clienti i dettagli interni degli errori Checkify.

try {
  const verdict = await verifyCheckifyResult(requestId);

  if (!verdict.allow) {
    return res.status(403).json({ error: "Verification required" });
  }

  // Continue protected action
} catch (err) {
  console.error("Checkify verification unavailable", err);

  return res.status(403).json({
    error: "Verification is temporarily unavailable. Please try again.",
  });
}

Server SDKs e strumenti

The Checkify monorepo includes @checkify/server (Node.js) and checkify-server (Python) packages for server-side verify calls. There is no published OpenAPI spec or Postman collection yet — use the examples on this page and POST /v1/qr/results/verify directly.

@checkify/server v1.0.0 è pubblicato su npm. Il pacchetto Python checkify-server è incluso nel monorepo Checkify SDK.

Finestra di scadenza dei risultati

Le verifiche completate scadono dopo QR_RESULT_MAX_AGE_SECONDS (valore predefinito 900 secondi / 15 minuti). Dopo la scadenza, la verifica restituisce result_expired: chiedi all'utente di verificare nuovamente.

Endpoint per il polling dello stato (frontend personalizzati)

I parametri JavaScript e SDK gestiscono lo stato della sessione per gli embed standard. Utilizzali solo quando crei un frontend personalizzato che chiama manualmente GET /v1/qr/pass/{pass_id}/start.

Gestione della risposta

In caso di successo, Checkify restituisce HTTP 200 con success: true e status: completed. Consenti l'accesso solo quando sono presenti le attestazioni richieste (ad esempio human_verified: true).

{
  "success": true,
  "status": "completed",
  "message": "Verification result confirmed",
  "request_id": "56a57761-ff5b-42f0-9c97-6c13e223e017",
  "site_id": "YOUR_SITE_ID",
  "business_id": "YOUR_BUSINESS_ID",
  "approved_claims": {
    "human_verified": true
  },
  "approved_fields": [],
  "signed_result": {
    "payload": { "...": "..." },
    "signature": "...",
    "signature_algorithm": "EdDSA",
    "key_id": "checkify:default"
  }
}

Risultato firmato

L’oggetto signed_result consente al backend di conservare un record di audit a prova di manomissione che Checkify ha approvato il claim richiesto al momento della verifica. La maggior parte delle integrazioni necessita solo di approved_claims. Aziende regolamentate o ad alto rischio possono anche memorizzare signed_result. proof_metadata annidato può includere evidenza crittografica od operativa (metadati di assurance, tipi di evidence o hash di consenso) — non documenti di identità né data di nascita grezza. Non trattare i campi di assurance annidati come certificazione o garanzia di fiducia; controlla certification_status e la tua policy. Non memorizzare più dati personali del necessario.

Se il cliente non ha ancora terminato nell'app, Checkify restituisce HTTP 200 con success: false e status: pending. Nega le azioni protette e chiedi all'utente di completare la verifica.

{
  "success": false,
  "status": "pending",
  "message": "Verification is not completed yet",
  "request_id": "56a57761-ff5b-42f0-9c97-6c13e223e017",
  "approved_claims": {},
  "signed_result": null
}
CampoSignificato
successtrue quando la verifica è completata e requisiti Rivendicazioni corrispondenti
statuscompleted o pending
approved_claimsCheckify approvate, ad es. human_verified: true
signed_resultPayload firmato opzionale per audit trail

JSON payload di errore

Quando la verifica non può procedere, Checkify restituisce HTTP 4xx/5xx con un corpo JSON strutturato. Controlla error.code e registra error.details lato server. Restituisci messaggi generici agli utenti finali.

{
  "success": false,
  "error": {
    "code": "verification_failed",
    "message": "The verification did not include all required claims.",
    "details": {
      "missing_claims": ["age_over_18"]
    }
  }
}
Codice AMD Senso Azione consigliata
missing_authorization401Non è stata inviata alcuna intestazione di autorizzazione.Invia autorizzazione: Bearer YOUR_SITE_API_KEY solo dal codice lato server.
invalid_token401Token di appartenenza mancante, malformato o non valido per il sito API.Verifica la chiave nella dashboard aziendale e memorizzala nelle variabili d'ambiente.
expired_token401La chiave del sito API è stata revocata.Crea una nuova chiave per il sito API e ruotala sui tuoi server.
missing_required_field400 / 422Il campo request_id o token non è presente nel corpo della richiesta JSON.Passa l'ID della richiesta (request_id) dal campo nascosto del modulo, oppure il token di sondaggio se la tua integrazione lo utilizza ancora.
invalid_request_id400Impossibile analizzare il riferimento oppure il riferimento risulta vuoto dopo la normalizzazione.Assicurati che il tuo frontend invii il request_id Checkify senza modifiche.
result_not_found404Non esiste alcuna richiesta di verifica per quel riferimento.Rifiuta l'azione. L'utente potrebbe aver manomesso il campo nascosto o aver inviato una sessione precedente.
result_expired410La verifica è stata completata troppo tempo fa per potersi fidare di questa azione.Chiedi all'utente di eseguire nuovamente la scansione e di chiamare la funzione di verifica con il nuovo request_id.
verification_failed403 / 409Mismatch di sito/business, risultato già consumato (HTTP 409) o errore generico di verifica.Nega l’accesso. Ispeziona error.details. Per lacune di claim/campi vedi missing_required_claims e missing_required_fields.
missing_required_claims403developers_server.err_missing_required_claims_meaningdevelopers_server.err_missing_required_claims_action
missing_required_fields403developers_server.err_missing_required_fields_meaningdevelopers_server.err_missing_required_fields_action
unknown_required_attributes400developers_server.err_unknown_required_attributes_meaningdevelopers_server.err_unknown_required_attributes_action
business_not_operational403L'account aziendale è bloccato, archiviato o non operativo.Contatta il titolare dell'attività o l'assistenza di Checkify. Non consentire azioni protette finché l'account non è attivo.
validation_errors422Il corpo JSON non ha superato la convalida dello schema (HTTP 422).Esamina error.details.validation_errors per individuare messaggi a livello di campo. Correggi i tipi request_id, required_claims o required_fields prima di riprovare.
rate_limited429Troppe chiamate di verifica in un breve lasso di tempo.Riprova con un intervallo di tempo esponenziale. Verifica solo in corrispondenza delle azioni protette, non a ogni visualizzazione di pagina.
server_error500+Checkify non è riuscito a completare la verifica a causa di un problema temporaneo del server.Riprova una o due volte, poi chiudi la segnalazione di errore e registra l'incidente.

Webhook e verifica asincrona

Attualmente, la verifica del server è sincrona: il backend verifica il request_id quando l'utente invia l'azione protetta. Questo è l'approccio consigliato per i flussi di checkout, registrazione e controllo degli accessi. I webhook di verifica generici non sono necessari per le integrazioni standard. GoHighLevel e le integrazioni di altri partner possono utilizzare una configurazione separata per i webhook in uscita nella dashboard aziendale.

Errori comuni

Promemoria di sicurezza

Tratta il campo nascosto come un riferimento non attendibile, non come una prova. Verifica sempre la chiave API del tuo sito sul server prima di concedere l'accesso. Utilizzo consume: true per azioni una tantum come la registrazione o la reimpostazione della password.

Prossimi passi