Checkify
Documents du développeur

Vérifiez sur votre backend

Une fois l'intégration du navigateur terminée, votre serveur doit vérifier le résultat avec une clé de site API avant d'autoriser l'inscription, le paiement ou toute action protégée.

Vérification du serveur en 5 minutes

  1. Ajoutez le module d'intégration pour navigateur Checkify à votre page.
  2. Le module intégré lance la session Checkify et inscrit la référence de vérification dans votre formulaire.
  3. Votre système backend lit la valeur du champ caché.
  4. Votre serveur envoie cette valeur à POST /v1/qr/results/verify en tant que request_id.
  5. Si les demandes requises sont approuvées, autorisez l'action protégée.
  6. Ne vous fiez jamais uniquement à l'état de l'interface utilisateur.

Le champ de formulaire caché peut être nommé checkify_token, mais sa valeur est le request_id Checkify.

Flux de bout en bout

1. Créer un site Clé API

Dans le tableau de bord de votre entreprise, ouvrez Développeur et créez une clé de site API pour le site que vous intégrez. Stockez-le uniquement dans les variables d'environnement du serveur - ne l'envoyez jamais au navigateur.

Utilisation de l'interface SDK ?

Il n'est pas nécessaire d'appeler manuellement la requête GET /v1/qr/pass/{PASS_ID}/start. Le module intégré Checkify JavaScript démarre la session, reçoit l'identifiant de requête et l'inscrit automatiquement dans votre formulaire.

Votre serveur dorsal n'a besoin que de :

2. Récupérez l'identifiant de la requête sur votre serveur.

L'interface utilisateur (SDK) enregistre l'identifiant de requête (Checkify) dans un champ caché du formulaire une fois la vérification effectuée par l'utilisateur. Le nom par défaut de ce champ est « checkify_token » ; il s'agit du nom du champ et non d'un type de jeton distinct. Envoyez la valeur de ce champ au point de terminaison de vérification en tant qu'identifiant de requête.

Le transfert depuis une application mobile peut renvoyer checkify_request_id dans l'URL de la page. Le SDK le lit au chargement ; votre serveur vérifie toujours la même valeur de request_id.

Formulaire POST depuis votre interface utilisateur

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

Vérifiez la requête provenant de votre serveur.

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

Intégration manuelle du frontend uniquement

3. Tests manuels avec cURL

Les développeurs backend n'utilisent généralement pas la commande `/start`. Utilisez cette section uniquement lors de la création d'une interface personnalisée ou lors de tests sans intégration. Dans zsh/bash, placez les URL entre guillemets afin que le caractère `?` ne soit pas interprété comme un glob.

L'en-tête Origin est requis pour /start

La commande « Pass start » ne fonctionne qu'à partir d'un nom de domaine enregistré. Les navigateurs envoient automatiquement l'origine ; cURL, non. Envoyez l'origine (ou X-Checkify-URL-du-site) avec un nom d'hôte figurant dans la section « Sites » → « Domaines autorisés ». Le nom d'hôte doit correspondre exactement : « checkify.me » et « www.checkify.me » sont différents.

Problème de test le plus courant

Si la commande /start renvoie une erreur HTTP 403, votre identifiant de mot de passe peut néanmoins être valide. Cela est généralement dû au fait que le domaine demandé ne figure pas dans la liste des domaines autorisés, ou que www.example.com a été enregistré mais que example.com a été utilisé (ou inversement).

Utilisez un site de test dédié et transmettez votre tableau de bord Checkify pour les tests d'intégration. Les clés du site API utilisent le préfixe csk_ ; il n'existe pas de format de clé de test spécifique. Ne réalisez pas de tests sur l'environnement de production tant que vous n'avez pas validé les scénarios de succès et d'échec.

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

Utilisez votre clé API uniquement lors de l'appel de vérification. Finalisez la vérification dans l'application avant d'appeler pour vérifier votre demande ; sinon, le statut restera « en attente ».

Revendications requises par cas d'utilisation

Configurez les revendications requises pour qu'elles correspondent aux preuves nécessaires à votre action protégée. Les noms des revendications doivent correspondre à ceux approuvés par Checkify pour cette session de vérification. Les contrôles d'âge utilisent age_over_{N} (par exemple, age_over_18). Les seuils dynamiques de 10 à 110 sont pris en charge lorsque l'intégration demande le type de requête correspondant.

Cas d'utilisation revendications_requises suggérées Notes
Remplacement du robot / CAPTCHA ["human_verified"] Confirme qu'un utilisateur réel a terminé le flux Checkify.
Contenu destiné aux 13 ans et plus ou produits destinés aux jeunes ["age_over_13"] À utiliser lorsque votre Pass requiert l'âge de plus de 13 ans.
Contenu réservé aux adultes (16+) ou soumis à des règles d'âge régionales ["age_over_16"] À utiliser lorsque votre Pass requiert l'âge de plus de 16 ans.
Vape, alcool ou caisse réservée aux personnes de plus de 18 ans ["age_over_18"] Adaptez le seuil d'âge à votre produit et à votre marché.
Produits réservés aux personnes de 21 ans et plus (le cas échéant) ["age_over_21"] À utiliser lorsque votre Pass requiert l'âge de plus de 21 ans.
Défiez 25 ou une politique de vente au détail plus stricte ["age_over_25"] À utiliser lorsque votre Pass requiert l'âge de plus de 25 ans.
Seuil d'âge personnalisé ["age_over_N"] Utilisez age_over_N où N est compris entre 10 et 110, en accord avec votre type de requête d'intégration.

Type de requête d'intégration → revendication du serveur

Le type de requête du navigateur doit correspondre à l'affirmation que vous vérifiez côté serveur.

Type de requête d'intégrationrevendications_obligatoires
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)

champs obligatoires facultatifs

Outre required_claims, vous pouvez exiger des champs d’identité approuvés spécifiques (par ex. pays ou tranche d’âge) lorsque votre intégration les a collectés. Passez les noms dans required_fields — s’ils manquent dans le résultat approuvé, verify renvoie missing_required_fields avec missing_fields dans error.details.

4. Appelez la vérification sur votre serveur

Effectuez une requête POST /v1/qr/results/verify avec votre clé API avant d'accorder l'accès. Considérez la référence du navigateur (request_id ou jeton d'interrogation hérité) comme non fiable jusqu'à ce que Checkify confirme le résultat.

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
}

Vous pouvez également envoyer token au lieu de request_id. La clé API est limitée à votre site Checkify — vous n'envoyez pas site_id dans le corps de la requête.

Exemples de mise en œuvre

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

Quand utiliser consommer

Utilisez consume: true pour les actions protégées finales — Paiement, inscription, réinitialisation du mot de passe, achat soumis à une restriction d'âge, accès au contenu protégé

Utilisez consume: false uniquement pour — tests, débogage ou vérifications non finales où le résultat doit être vérifié ultérieurement

Pour les actions réglementées ou à haut risque, privilégiez consumer: true afin que le même résultat de vérification ne puisse pas être réutilisé pour plusieurs décisions protégées.

Échec de la fermeture pour les actions réglementées

Si votre serveur ne peut pas atteindre Checkify, n'autorisez pas les paiements réservés aux personnes majeures, l'accès aux jeux d'argent, l'accès au contenu pour adultes, l'achat de cigarettes électroniques ou d'alcool, ni d'autres actions protégées sans un résultat confirmé côté serveur.

Utilisez des délais d'attente HTTP courts (par exemple, 10 secondes). En cas d'erreur 5xx ou d'erreur réseau transitoire, réessayez une ou deux fois, puis refusez l'accès. Consignez les incidents côté serveur et affichez des messages sécurisés pour l'utilisateur. Ne divulguez pas les détails des erreurs internes Checkify aux clients.

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.",
  });
}

Serveur SDKs et outils

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 est disponible sur npm. Le package Python checkify-server est inclus dans le monorepo Checkify SDK.

fenêtre d'expiration des résultats

Les vérifications effectuées expirent après QR_RESULT_MAX_AGE_SECONDS (par défaut 900 secondes / 15 minutes). Après expiration, la vérification renvoie result_expired ; l’utilisateur est alors invité à vérifier à nouveau.

Points de terminaison d'interrogation d'état (interfaces personnalisées)

Les classes JavaScript et SDK gèrent l'état de session pour les applications intégrées standard. Utilisez-les uniquement lorsque vous créez une interface personnalisée qui appelle manuellement la fonction GET /v1/qr/pass/{pass_id}/start.

Traitement de la réponse

En cas de succès, Checkify renvoie HTTP 200 avec success: true et status: completed. L'accès n'est autorisé que si les revendications requises sont présentes (par exemple, 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"
  }
}

Résultat signé

L’objet signed_result permet à votre backend de conserver une trace d’audit inviolable indiquant que Checkify a approuvé le claim requis au moment de la vérification. La plupart des intégrations n’ont besoin que de approved_claims. Les entreprises réglementées ou à haut risque peuvent aussi stocker signed_result. proof_metadata imbriqué peut contenir des preuves cryptographiques ou opérationnelles (métadonnées d’assurance, types de preuves ou hachages de consentement) — pas de documents d’identité ni de date de naissance brute. Ne traitez pas les champs d’assurance imbriqués comme une certification ou une garantie de confiance ; vérifiez certification_status et votre propre politique. Ne stockez pas plus de données personnelles que nécessaire.

Si le client n'a pas encore terminé dans l'application, Checkify renvoie HTTP 200 avec success: false et status: pending. Refusez les actions protégées et demandez à l'utilisateur de terminer la vérification.

{
  "success": false,
  "status": "pending",
  "message": "Verification is not completed yet",
  "request_id": "56a57761-ff5b-42f0-9c97-6c13e223e017",
  "approved_claims": {},
  "signed_result": null
}
ChampSignification
successtrue lorsque la vérification est terminée et que les exigences correspondent
statuscompleted ou pending
approved_claimsRéclamations Checkify approuvées, par ex. human_verified: true
signed_resultCharge utile signée en option pour les pistes d'audit

JSON charges utiles d'erreur

En cas d'échec de la vérification, Checkify renvoie une réponse HTTP 4xx/5xx avec un corps structuré JSON. Vérifiez le code d'erreur et consignez les détails de l'erreur côté serveur. Affichez des messages génériques aux utilisateurs.

{
  "success": false,
  "error": {
    "code": "verification_failed",
    "message": "The verification did not include all required claims.",
    "details": {
      "missing_claims": ["age_over_18"]
    }
  }
}
Code HTTP Signification Action recommandée
missing_authorization401Aucun en-tête d'autorisation n'a été envoyé.Envoyer l'autorisation : Bearer VOTRE_SITE_API_KEY uniquement depuis le code côté serveur.
invalid_token401Jeton porteur manquant, mal formé ou clé de site API non valide.Vérifiez la clé dans votre tableau de bord d'entreprise et stockez-la dans les variables d'environnement.
expired_token401La clé du site API a été révoquée.Créez une nouvelle clé de site API et faites-la tourner sur vos serveurs.
missing_required_field400 / 422L'identifiant de requête ou le jeton est manquant dans le corps JSON.Transmettez l'identifiant de requête (request_id) depuis votre champ de formulaire caché, ou le jeton d'interrogation si votre intégration l'utilise encore.
invalid_request_id400La référence n'a pas pu être analysée ou est vide après normalisation.Assurez-vous que votre interface soumette l'identifiant de requête Checkify sans modification.
result_not_found404Aucune demande de vérification n'existe pour cette référence.Rejetez l'action. L'utilisateur a peut-être modifié le champ caché ou soumis une ancienne session.
result_expired410La vérification date de trop longtemps pour qu'on puisse se fier à cette action.Demandez à l'utilisateur de scanner à nouveau et appelez la fonction de vérification avec le nouvel identifiant de requête (request_id).
verification_failed403 / 409Incohérence site/entreprise, résultat déjà consommé (HTTP 409), ou échec générique de vérification.Refusez l’accès. Inspectez error.details. Pour les manques de claims/champs, voir missing_required_claims et 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_operational403Le compte professionnel est verrouillé, archivé ou non opérationnel.Contactez le propriétaire de l'entreprise ou le support Checkify. N'autorisez aucune action protégée tant que le compte n'est pas actif.
validation_errors422Le corps JSON n'a pas pu être validé selon le schéma (HTTP 422).Examinez les erreurs de validation (error.details.validation_errors) pour identifier les messages d'erreur au niveau des champs. Corrigez les types request_id, required_claims ou required_fields avant de réessayer.
rate_limited429Trop d'appels de vérification en peu de temps.Réessayer avec un délai exponentiel. Vérifier uniquement lors d'actions protégées, et non à chaque affichage de page.
server_error500+Checkify n'a pas pu terminer la vérification en raison d'un problème temporaire de serveur.Réessayez une ou deux fois, puis fermez le ticket en cas d'échec et consignez l'incident.

Webhooks et vérification asynchrone

Aujourd'hui, la vérification côté serveur est synchrone : votre système vérifie l'identifiant de requête (request_id) lorsque l'utilisateur effectue l'action protégée. Cette approche est recommandée pour les processus de paiement, d'inscription et de contrôle d'accès. Les webhooks de vérification génériques ne sont pas nécessaires pour les intégrations standard. GoHighLevel et d'autres partenaires peuvent utiliser une configuration de webhook sortant distincte dans le tableau de bord métier.

Erreurs courantes

Rappel de sécurité

Traitez le champ caché comme une référence non fiable, et non comme une preuve. Vérifiez toujours avec la clé API de votre site sur le serveur avant d'accorder l'accès. Utilisez consume: true pour des actions ponctuelles telles que l'inscription ou la réinitialisation du mot de passe.

Prochaines étapes