Controleer
Documenten voor ontwikkelaars

Verifieer op uw backend

Nadat het insluiten van de browser is voltooid, moet uw server het resultaat verifiëren met een site-API-sleutel voordat u zich kunt aanmelden, afrekenen of een beschermde actie kunt uitvoeren.

Serververificatie in 5 minuten

  1. Voeg de Checkify-browserinsluiting toe aan uw pagina.
  2. De embed start de Checkify-sessie en schrijft de verificatiereferentie in uw formulier.
  3. Uw backend leest de verborgen veldwaarde.
  4. Uw backend verzendt die waarde naar POST /v1/qr/results/verify als request_id.
  5. Als de vereiste claims zijn goedgekeurd, staat u de beschermde actie toe.
  6. Vertrouw nooit alleen op de frontend-status.

Het verborgen formulierveld mag checkify_token heten, maar de waarde ervan is de Checkify request_id.

Eind-tot-eind stroom

1. Maak een site-API-sleutel

Open in uw bedrijfsdashboard Ontwikkelaar en maak een site-API-sleutel voor de site die u integreert. Bewaar het alleen in serveromgevingsvariabelen; stuur het nooit naar de browser.

De frontend-SDK gebruiken?

U hoeft GET /v1/qr/pass/{PASS_ID}/start niet handmatig aan te roepen. De Checkify JavaScript-embed start de sessie, ontvangt de request_id en schrijft deze automatisch in uw formulier.

Uw backend hoeft alleen maar:

2. Ontvang de request_id op uw server

De frontend-SDK schrijft de Checkify request_id naar een verborgen formulierveld nadat de gebruiker de verificatie heeft voltooid. De standaardveldnaam is checkify_token, dat is de veldnaam en geen afzonderlijk tokentype. Stuur de veldwaarde naar het verificatie-eindpunt als request_id.

Handoff van mobiele app kan checkify_request_id retourneren in de pagina-URL. De SDK leest het tijdens het laden; uw server verifieert nog steeds dezelfde request_id-waarde.

Formulier POST vanaf uw frontend

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

Verifieer het verzoek van uw backend

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

Alleen handmatige frontend-integratie

3. Handmatig testen met cURL

Backend-ontwikkelaars bellen normaal gesproken niet /start. Gebruik deze sectie alleen als u een aangepaste frontend bouwt of test zonder de insluiting. Citeer URL's in zsh/bash dus? wordt niet als een klodder behandeld.

Origin-header is vereist voor /start

Pass start werkt alleen vanaf een geregistreerd websitedomein. Browsers verzenden Origin automatisch; krul niet. Stuur Origin (of X-Checkify-Site-Url) met een hostnaam vermeld onder Sites → toegestane domeinen. De hostnaam moet exact overeenkomen: checkify.me en www.checkify.me zijn verschillend.

Meest voorkomende testprobleem

Als /start HTTP 403 retourneert, is uw Pass-ID mogelijk nog steeds geldig. De gebruikelijke oorzaak is dat het aanvraagdomein niet in de toegestane domeinen staat, of dat www.example.com geregistreerd was maar example.com werd gebruikt (of omgekeerd).

Gebruik een speciale testsite en slaag in uw Checkify-dashboard voor integratietesten. Site-API-sleutels gebruiken het voorvoegsel csk_; er is geen afzonderlijk testsleutelformaat. Voer geen tests uit aan de hand van de productieafrekening totdat u zowel de succes- als de weigeringsstromen hebt bevestigd.

# 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
  }'

Gebruik de API-sleutel van uw site alleen tijdens de verificatieaanroep. Voltooi de verificatie in de app voordat u verificatie aanroept. Anders krijgt u de status In behandeling.

Vereiste claims per gebruiksscenario

Stel require_claims in zodat deze overeenkomen met het bewijs dat uw beschermde actie nodig heeft. Claimnamen moeten overeenkomen met wat Checkify heeft goedgekeurd voor die verificatiesessie. Leeftijdscontroles gebruiken age_over_{N} (bijvoorbeeld age_over_18). Dynamische drempelwaarden van 10 tot en met 110 worden ondersteund wanneer de insluiting het overeenkomende verzoektype aanvraagt.

Gebruiksgeval Voorgestelde vereiste_claims Opmerkingen
Bot / CAPTCHA-vervanging ["human_verified"] Bevestigt dat een echte gebruiker de Checkify-stroom heeft voltooid.
13+ inhoud of op jongeren gerichte producten ["age_over_13"] Gebruik deze als je Pas een leeftijd van 13 jaar of ouder aanvraagt.
16+ inhoud of regionale leeftijdsregels ["age_over_16"] Gebruik deze als je Pas een leeftijd van 16 jaar of ouder aanvraagt.
Vapen, alcohol of 18+ afrekenen ["age_over_18"] Stem de leeftijdsgrens af op uw product en markt.
21+ beperkte producten (waar van toepassing) ["age_over_21"] Gebruik deze als je Pas een leeftijd van 21 jaar of ouder aanvraagt.
Challenge 25 of strenger retailbeleid ["age_over_25"] Gebruik deze als je Pas een leeftijd van 25 jaar of ouder aanvraagt.
Aangepaste leeftijdsdrempel ["age_over_N"] Gebruik age_over_N waarbij N 10–110 is, afgestemd op uw type insluitingsverzoek.

Type verzoek insluiten → serverclaim

Het browserverzoektype moet overeenkomen met de claim die u aan de serverzijde verifieert.

Verzoektype insluitenvereiste_claims
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)

Optioneel verplichte_velden

Naast verplichte_claims heeft u mogelijk specifieke goedgekeurde identiteitsvelden nodig (bijvoorbeeld land of leeftijdscategorie) toen uw integratie deze verzamelde. Geef veldnamen door in verplichte_velden. Als er ontbreken in het goedgekeurde resultaat, verifieer dan de retourzendingen verificatie_failed met ontbrekende_velden in error.details.

4. Roep verificatie op uw server aan

Roep POST /v1/qr/results/verify aan met de API-sleutel van uw site voordat u toegang verleent. Behandel de browserreferentie (request_id of verouderd poll-token) als niet-vertrouwd totdat Checkify het resultaat bevestigt.

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
}

Je kunt ook verzenden token in plaats van request_id. De API-sleutel is gericht op uw Checkify-site; u verzendt geen site_id in de hoofdtekst van het verzoek.

Implementatievoorbeelden

# 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
  }'

Wanneer consumeren gebruiken?

Gebruik consumeren: waar voor definitieve beschermde acties — afrekenen, aanmelden, wachtwoord opnieuw instellen, aankoop met leeftijdsbeperking, beveiligde toegang tot inhoud

Gebruik consumer: false alleen voor — testen, debuggen of niet-eindcontroles waarbij het resultaat later opnieuw moet worden geverifieerd

Voor gereguleerde of risicovolle acties geeft u de voorkeur aan consumer: true, zodat hetzelfde verificatieresultaat niet kan worden hergebruikt voor meerdere beschermde beslissingen.

Failclosed voor gereguleerde acties

Als uw backend Checkify niet kan bereiken, sta dan geen leeftijdsgebonden afrekenen, goktoegang, toegang tot inhoud voor volwassenen, aankoop van vape of alcohol of andere beschermde acties toe zonder een bevestigd server-side resultaat.

Gebruik korte HTTP-time-outs (bijvoorbeeld 10 seconden). Probeer het een of twee keer opnieuw voor tijdelijke 5xx- of netwerkfouten en weiger vervolgens de toegang. Registreer incidenten op de server en toon gebruikersveilige berichten. Stel interne Checkify-foutdetails niet bloot aan klanten.

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-SDK's en tooling

Gebruik @checkify/server (npm) of checkify-server (Python) voor getypte verificatiehelpers, of roep POST /v1/qr/results/verify rechtstreeks aan. Er is nog geen OpenAPI-specificatie gepubliceerd. Gebruik de voorbeelden op deze pagina.

@checkify/server v1.0.0 is gepubliceerd op npm. Het Python checkify-server-pakket wordt geleverd in de Checkify SDK-monorepo.

Resultaatvervalperiode

Voltooide verificaties verlopen na QR_RESULT_MAX_AGE_SECONDS (standaard 900 seconden / 15 minuten). Na de vervaldatum verifieert u het resultaat result_expired: vraag de gebruiker om opnieuw te verifiëren.

Eindpunten voor statusonderzoek (aangepaste frontends)

De JavaScript SDK verwerkt de sessiestatus voor standaard insluitingen. Gebruik deze alleen wanneer u een aangepaste frontend bouwt die GET /v1/qr/pass/{pass_id}/start handmatig aanroept.

Reactieafhandeling

Bij succes retourneert Checkify HTTP 200 met succes: waar en status: voltooid. Sta alleen toegang toe als er vereiste claims aanwezig zijn (bijvoorbeeld 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"
  }
}

Ondertekend resultaat

Met het object Signed_result kan uw backend een fraudebestendige auditregistratie bijhouden waaruit blijkt dat Checkify de vereiste claim op het verificatietijdstip heeft goedgekeurd. Voor de meeste integraties zijn alleen goedgekeurde_claims nodig. Gereguleerde bedrijven of bedrijven met een hoog risico kunnen ook ondertekende resultaten opslaan voor controle. Bewaar niet meer persoonlijke informatie dan nodig is.

Als de klant nog niet klaar is in de app, retourneert Checkify HTTP 200 met succes: false en status: in behandeling. Weiger beschermde acties en vraag de gebruiker om de verificatie te voltooien.

{
  "success": false,
  "status": "pending",
  "message": "Verification is not completed yet",
  "request_id": "56a57761-ff5b-42f0-9c97-6c13e223e017",
  "approved_claims": {},
  "signed_result": null
}
VeldBetekenis
successtrue wanneer de verificatie is voltooid en de vereisten overeenkomen
statuscompleted of pending
approved_claimsClaims Checkify goedgekeurd, b.v. human_verified: true
signed_resultOptionele ondertekende payload voor audittrails

JSON-foutpayloads

Wanneer de verificatie niet kan doorgaan, retourneert Checkify HTTP 4xx/5xx met een gestructureerde JSON-body. Controleer error.code en log error.details op de server. Retourneer generieke berichten naar eindgebruikers.

{
  "success": false,
  "error": {
    "code": "verification_failed",
    "message": "The verification did not include all required claims.",
    "details": {
      "missing_claims": ["age_over_18"]
    }
  }
}
Code HTTP Betekenis Aanbevolen actie
missing_authorization401Er is geen autorisatieheader verzonden.Autorisatie verzenden: Bearer YOUR_SITE_API_KEY alleen vanaf code aan de serverzijde.
invalid_token401Bearer-token ontbreekt, heeft een onjuiste indeling of heeft geen geldige site-API-sleutel.Verifieer de sleutel in uw bedrijfsdashboard en sla deze op in omgevingsvariabelen.
expired_token401De API-sleutel van de site is ingetrokken.Maak een nieuwe site-API-sleutel en roteer deze op uw servers.
missing_required_field400 / 422request_id of token ontbreekt in de JSON-hoofdtekst.Geef de request_id uit uw verborgen formulierveld door, of de poll-token als uw integratie deze nog steeds gebruikt.
invalid_request_id400De verwijzing kon niet worden geparseerd of is leeg na normalisatie.Zorg ervoor dat uw frontend de Checkify request_id ongewijzigd indient.
result_not_found404Er bestaat geen verificatieverzoek voor die referentie.De actie afwijzen. Mogelijk heeft de gebruiker met het verborgen veld geknoeid of een oude sessie ingediend.
result_expired410De verificatie is te lang geleden voltooid om deze actie te kunnen vertrouwen.Vraag de gebruiker om opnieuw te scannen en bel verificatie aan met de nieuwe request_id.
verification_failed403 / 409De verificatie is voltooid, maar voldoet niet aan de vereiste claims/velden, behoort tot een andere site of is al gebruikt.Toegang weigeren. Inspecteer error.details op ontbrekende_claims, ontbrekende_velden of reden.
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_operational403Het zakelijke account is vergrendeld, gearchiveerd of niet operationeel.Neem contact op met de bedrijfseigenaar of met Checkify-ondersteuning. Sta geen beschermde acties toe totdat het account actief is.
validation_errors422De JSON-hoofdtekst is niet in staat om het schema te valideren (HTTP 422).Inspecteer error.details.validation_errors voor berichten op veldniveau. Corrigeer de typen request_id, require_claims of require_fields voordat u het opnieuw probeert.
rate_limited429Te veel verificatieoproepen in een kort tijdsbestek.Probeer het opnieuw met exponentieel uitstel. Verifieer alleen bij beveiligde acties, niet bij elke paginaweergave.
server_error500+Checkify kon de verificatie niet voltooien vanwege een tijdelijk serverprobleem.Probeer het een of twee keer opnieuw, sluit vervolgens de fout en registreer het incident.

Webhooks en asynchrone verificatie

Tegenwoordig is serververificatie synchroon: uw backend verifieert de request_id wanneer de gebruiker de beschermde actie indient. Voor betaal-, aanmeldings- en toegangscontrolestromen is dit de aanbevolen aanpak. Algemene verificatiewebhooks zijn niet vereist voor standaardintegraties. GoHighLevel en andere partnerintegraties kunnen een afzonderlijke uitgaande webhookconfiguratie gebruiken in het bedrijfsdashboard.

Veel voorkomende fouten

Beveiligingsherinnering

Behandel het verborgen veld als een niet-vertrouwde referentie, niet als bewijs. Verifieer altijd met de API-sleutel van uw site op de server voordat u toegang verleent. Gebruik consume: true voor eenmalige acties zoals aanmelden of wachtwoord opnieuw instellen.

Volgende stappen