Checkify
Документы разработчика

Проверка на вашей серверной части

После завершения внедрения браузера ваш сервер должен проверить результат с помощью ключа сайта API, прежде чем разрешить регистрацию, оформление заказа или любое защищенное действие.

Проверка сервера за 5 минут

  1. Добавьте встраиваемый элемент браузера Checkify на свою страницу.
  2. Встроенный модуль запускает сессию Checkify и записывает проверочный код в вашу форму.
  3. Ваш бэкэнд считывает значение скрытого поля.
  4. Ваш бэкэнд отправляет это значение в POST-запрос /v1/qr/results/verify в качестве request_id.
  5. Если необходимые заявки будут одобрены, разрешите осуществление защищаемого действия.
  6. Никогда не полагайтесь исключительно на состояние фронтенда.

Скрытое поле формы может называться checkify_token, но его значением будет request_id (идентификатор запроса) в формате Checkify.

Сквозной поток

1. Создайте сайт. Ключ API

В панели управления вашего бизнеса откройте Разработчик. и создайте ключ API для сайта, который вы интегрируете. Храните его только в переменных среды сервера — никогда не отправляйте его в браузер.

Используете интерфейс SDK?

Вам не нужно вручную вызывать GET /v1/qr/pass/{PASS_ID}/start. Встроенный модуль Checkify JavaScript запускает сессию, получает request_id и автоматически записывает его в вашу форму.

Вашей серверной части достаточно выполнить лишь следующее:

2. Получите request_id на вашем сервере.

Фронтенд SDK записывает Checkify request_id в скрытое поле формы после завершения пользователем верификации. Имя поля по умолчанию — checkify_token — это имя поля, а не отдельный тип токена. Значение поля отправляется на конечную точку проверки в качестве request_id.

В адресе страницы при передаче данных в мобильном приложении может возвращаться значение checkify_request_id. SDK считывает его при загрузке; ваш сервер по-прежнему проверяет то же значение request_id.

Отправьте POST-запрос из вашего фронтенда.

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

Проверьте запрос из вашей серверной части.

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

Только ручная интеграция фронтенда

3. Ручное тестирование с помощью cURL

Разработчики бэкенда обычно не вызывают /start. Используйте этот раздел только при создании собственного фронтенда или тестировании без встраивания. Заключайте URL-адреса в кавычки в zsh/bash, чтобы знак вопроса (?) не рассматривался как шаблон.

Для /start требуется заголовок Origin.

Команда `pass start` работает только с зарегистрированного домена веб-сайта. Браузеры автоматически отправляют Origin; cURL этого не делает. Отправьте Origin (или X-Checkify-Site-Url) с именем хоста, указанным в разделе «Сайты» → «Разрешенные домены». Имя хоста должно совпадать точно — checkify.me и www.checkify.me — разные домены.

Наиболее распространенная проблема при тестировании

Если /start возвращает HTTP 403, ваш Pass ID может быть всё ещё действителен. Обычно это происходит из-за того, что запрашиваемый домен не указан в списке разрешенных доменов, или был зарегистрирован www.example.com, но использовался example.com (или наоборот).

Используйте выделенный тестовый сайт и пройдите тестирование в панели мониторинга Checkify для интеграционного тестирования. Ключи сайта API используют префикс csk_; отдельного формата тестового ключа нет. Не проводите тестирование на рабочей версии, пока не подтвердите как успешные, так и неудачные сценарии.

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

Используйте ключ API вашего сайта только при вызове проверки. Завершите проверку в приложении перед вызовом проверки — в противном случае вы получите статус «ожидание».

Обязательные утверждения для каждого варианта использования

Установите параметр required_claims в соответствии с требованиями к подтверждению, необходимым для вашего защищаемого действия. Названия утверждений должны совпадать с тем, что было одобрено Checkify для данной сессии проверки. Для проверки возраста используется age_over_{N} (например, age_over_18). Поддерживаются динамические пороговые значения от 10 до 110, если встраивание запрашивает соответствующий тип запроса.

Вариант использования Предложенные обязательные утверждения Примечания
Замена бота / CAPTCHA ["human_verified"] Подтверждает, что реальный пользователь завершил процесс Checkify.
Контент 13+ или продукция, ориентированная на молодежь ["age_over_13"] Используйте, если ваш пропуск запрашивает возраст старше 13 лет.
Контент 16+ или региональные возрастные ограничения ["age_over_16"] Используйте, если ваш пропуск запрашивает возраст старше 16 лет.
Электронные сигареты, алкоголь или касса для лиц старше 18 лет. ["age_over_18"] Сопоставьте возрастной порог с вашим продуктом и рынком.
Товары, продажа которых ограничена для лиц старше 21 года (где это применимо). ["age_over_21"] Используйте, если ваш пропуск запрашивает возраст старше 21 года.
Правила розничной торговли, требующие соответствия требованиям для лиц старше 25 лет или более строгих требований. ["age_over_25"] Используйте, если ваш пропуск запрашивает возраст старше 25 лет.
Пользовательский возрастной порог ["age_over_N"] Используйте age_over_N, где N — это значение от 10 до 110, соответствующее типу вашего запроса на встраивание.

Тип запроса на встраивание → утверждение сервера

Тип запроса браузера должен совпадать с утверждением, которое вы проверяете на стороне сервера.

тип запроса на встраиваниеrequired_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)

Необязательные обязательные поля

Помимо required_claims вы можете требовать конкретные одобренные поля идентичности (например страну или возрастную группу), если интеграция их собрала. Передайте имена в required_fields — если их нет в одобренном результате, verify возвращает missing_required_fields с missing_fields в error.details.

4. Выполните проверку на вашем сервере.

Перед предоставлением доступа вызовите POST-запрос /v1/qr/results/verify, указав ключ API вашего сайта. Считайте ссылку на браузер (request_id или устаревший токен опроса) недоверенной до тех пор, пока Checkify не подтвердит результат.

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
}

Вы также можете отправить token вместо request_id. Ключ API ограничен областью действия вашего сайта Checkify — в теле запроса не нужно отправлять site_id.

Примеры реализации

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

Когда использовать consume

Используйте consume: true для окончательных защищенных действий. — Оформление заказа, регистрация, сброс пароля, покупка с возрастным ограничением, доступ к защищенному контенту.

Используйте consume: false только для — тестирование, отладка или незавершенные проверки, результат которых необходимо будет подтвердить позже.

Для регулируемых или высокорискованных действий предпочтительнее использовать параметр consume: true, чтобы один и тот же результат проверки не мог быть использован для нескольких защищаемых решений.

Отказ закрыт для регулируемых действий.

Если ваш бэкэнд не может связаться с Checkify, не разрешайте оформление заказа с возрастными ограничениями, доступ к азартным играм, доступ к контенту для взрослых, покупку электронных сигарет или алкоголя, а также другие защищенные действия без подтвержденного результата на стороне сервера.

Используйте короткие тайм-ауты HTTP (например, 10 секунд). Повторяйте попытку один или два раза при временных ошибках 5xx или сетевых ошибках, затем откажите в доступе. Регистрируйте инциденты на стороне сервера и отображайте безопасные для пользователя сообщения. Не раскрывайте клиентам подробности внутренних ошибок 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.",
  });
}

Сервер SDKs и инструменты

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 опубликован на npm. Пакет Python checkify-server входит в монорепозиторий Checkify SDK.

Срок действия результатов

Срок действия завершенных проверок истекает через QR_RESULT_MAX_AGE_SECONDS (по умолчанию 900 секунд / 15 минут). По истечении этого срока проверка возвращает result_expired — пользователю предлагается пройти повторную проверку.

Конечные точки для опроса состояния (пользовательские интерфейсы)

Компоненты JavaScript и SDK обрабатывают состояние сессии для стандартных встраиваемых элементов. Используйте их только при создании пользовательского интерфейса, который вручную вызывает GET /v1/qr/pass/{pass_id}/start.

Обработка ответа

В случае успеха Checkify возвращает HTTP 200 с success: true и status: completed. Разрешать доступ только при наличии необходимых утверждений (например, 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"
  }
}

Результат с подписью

Объект signed_result позволяет бэкенду хранить защищённую от подделки аудиторскую запись о том, что Checkify одобрил требуемый claim в момент проверки. Большинству интеграций достаточно approved_claims. Регулируемым или высокорисковым компаниям можно также хранить signed_result. Вложенный proof_metadata может содержать криптографические или операционные свидетельства (метаданные assurance, типы evidence или хэши согласия) — не документы удостоверения личности и не сырую дату рождения. Не считайте вложенные поля assurance сертификацией или гарантией доверия; проверяйте certification_status и свою политику. Не храните больше персональных данных, чем необходимо.

Если клиент еще не завершил работу в приложении, Checkify возвращает HTTP 200 с success: false и status: pending. Запретить защищенные действия и попросить пользователя завершить проверку.

{
  "success": false,
  "status": "pending",
  "message": "Verification is not completed yet",
  "request_id": "56a57761-ff5b-42f0-9c97-6c13e223e017",
  "approved_claims": {},
  "signed_result": null
}
ПолеЗначение
successtrue когда проверка завершена и требования соответствуют
statuscompleted или pending
approved_claimsУтверждения Checkify одобрены, например. human_verified: true
signed_resultДополнительные подписанные полезные данные для контрольного журнала

JSON ошибки полезной нагрузки

Если проверка не может быть продолжена, Checkify возвращает HTTP 4xx/5xx со структурированным телом JSON. Проверьте error.code и запишите error.detail на стороне сервера. Верните конечным пользователям общие сообщения.

{
  "success": false,
  "error": {
    "code": "verification_failed",
    "message": "The verification did not include all required claims.",
    "details": {
      "missing_claims": ["age_over_18"]
    }
  }
}
Код HTTP Значение Рекомендуемые действия
missing_authorization401Заголовок авторизации не был отправлен.Отправка авторизации: Bearer YOUR_SITE_API_KEY только из серверного кода.
invalid_token401Отсутствует, имеет некорректный формат или является недействительным ключом сайта API.Проверьте ключ на панели управления вашей компании и сохраните его в переменных среды.
expired_token401Ключ сайта API был отозван.Создайте новый ключ сайта API и выполните его ротацию на ваших серверах.
missing_required_field400 / 422В теле запроса JSON отсутствует request_id или token.Передайте request_id из скрытого поля формы или токен опроса, если ваша интеграция все еще его использует.
invalid_request_id400Ссылка не может быть обработана или оказывается пустой после нормализации.Убедитесь, что ваш фронтенд отправляет request_id без изменений.
result_not_found404Запрос на подтверждение по данной ссылке отсутствует.Отклонить действие. Возможно, пользователь изменил скрытое поле или отправил данные из старой сессии.
result_expired410Проверка была завершена слишком давно, чтобы доверять ей в данном случае.Предложите пользователю повторно выполнить сканирование и вызвать функцию проверки с новым request_id.
verification_failed403 / 409Несовпадение сайта/бизнеса, уже использованный результат (HTTP 409) или общая ошибка проверки.Отклоните доступ. Проверьте error.details. Для пробелов в claims/полях см. missing_required_claims и 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_operational403Учетная запись компании заблокирована, заархивирована или неактивна.Обратитесь к владельцу бизнеса или в службу поддержки Checkify. Не разрешайте защищенные действия, пока учетная запись не будет активирована.
validation_errors422Тело сообщения JSON не прошло проверку схемы (HTTP 422).Проверьте error.details.validation_errors на наличие сообщений на уровне полей. Исправьте типы request_id, required_claims или required_fields перед повторной попыткой.
rate_limited429Слишком много подтверждающих звонков за короткий промежуток времени.Повторите попытку с экспоненциальной задержкой. Проверяйте только защищенные действия, а не каждый просмотр страницы.
server_error500+Проверка Checkify не может быть завершена из-за временной проблемы с сервером.Повторите попытку один или два раза, затем закройте окно с ошибкой и зарегистрируйте инцидент.

Вебхуки и асинхронная проверка

Сегодня серверная проверка осуществляется синхронно: ваш бэкэнд проверяет request_id, когда пользователь отправляет защищенное действие. Для процессов оформления заказа, регистрации и контроля доступа это рекомендуемый подход. Для стандартных интеграций не требуются веб-хуки общего назначения для проверки. GoHighLevel и другие партнерские интеграции могут использовать отдельную конфигурацию исходящих веб-хуков в панели управления бизнесом.

Распространенные ошибки

Напоминание о безопасности

Считайте скрытое поле ненадежной ссылкой, а не доказательством. Прежде чем предоставлять доступ, всегда проверяйте ключ API вашего сайта на сервере. Используйте consume: true для одноразовых действий, таких как регистрация или сброс пароля.

Следующие шаги