Перейти к содержанию

Уровни верификации

Уровни верификации — это настраиваемые оператором сценарии, которые определяют, какие шаги должен пройти заявитель (ID-документ, селфи, анкета, AML-скрининг и т. д.) и какие поля идентичности SDK собирает на каждом шаге. У каждого уровня есть человекочитаемое имя в формате KYC_01 — именно оно используется как идентификатор во всех запросах.

Заранее запрашивать список уровней не нужно. Просто захардкодьте имя, с которым работает ваша интеграция (KYC_BASIC, KYC_PREMIUM, KYB_STANDARD и т. п.), и передавайте его как есть. Конструктор уровней проверяет формат (^[A-Z][A-Z0-9_]{1,40}$) и блокирует переименование, как только хотя бы один заявитель сослался на уровень — то есть, попав в продакшен, имя больше не меняется.

GET /v1/levels

Возвращает все активные уровни в рамках продукта вашего ключа. Внутренние поля оператора (счётчики использования, описание для персонала, флаги «только для чтения», метки SDK) исключены.

curl -X GET 'https://api.compliance.example/v1/levels?type=individual' \
  -H 'X-Api-Key: pk_live_...' \
  -H 'X-Api-Secret: ...' \
  -H 'X-Environment: production'
{
  "items": [
    {
      "name": "KYC_01",
      "applicantType": "individual",
      "isActive": true,
      "isDefault": true,
      "requiredSteps": ["identity_doc", "selfie", "questionnaire"]
    }
  ],
  "totalItems": 1
}

Параметры запроса

Параметр Значения По умолчанию Что делает
type individual | company | all all Фильтр по типу заявителя
includeInactive true | false false Включать отключённые уровни

GET /v1/levels/{levelName}

Детали одного уровня с конфигурацией каждого шага + списки включённых/обязательных полей для personal-info / company-data / company-documents шагов уровня. Используйте, чтобы точно знать, какие поля интеграция может предзаполнить в POST /v1/applicants для этого уровня.

{
  "id": "a1b2c3d4-...",
  "name": "KYB_STANDARD",
  "applicantType": "company",
  "isActive": true,
  "isDefault": false,
  "steps": [ /* конфиг каждого шага */ ],
  "attachedQuestionnaireId": null,

  // Personal-info форма (KYC). Пустые массивы = у уровня нет шага
  // personal_information ИЛИ список полей не настроен (SDK
  // использует свой baseline: firstName + lastName + dateOfBirth +
  // nationality + email + phone).
  "personalInfoFields":         ["firstName", "lastName", "email", "phone"],
  "personalInfoRequiredFields": ["firstName", "lastName"],

  // KYB-форма. Пустые массивы = у уровня нет шага company_data ИЛИ
  // список полей не настроен (SDK использует baseline: companyName
  // + registrationCountry + registrationNumber + legalAddress +
  // email + phone). required ⊆ enabled.
  "companyDataFields":     ["companyName", "registrationCountry", "registrationNumber",
                            "incorporatedOn", "legalForm", "legalAddress", "email", "phone"],
  "companyRequiredFields": ["companyName", "registrationNumber", "registrationCountry"],

  // Шаг company_documents. Пустой список ⇒ все включённые документы
  // обязательны. companyDocumentsMinRequired null ⇒ SDK использует
  // количество обязательных документов.
  "companyRequiredDocuments":   ["certificate_of_incorporation"],
  "companyDocumentsMinRequired": 1,

  // Whitelist форм юр. лиц для уровня. Пусто ⇒ SDK показывает полный
  // каталог.
  "companyLegalForms":          ["LLC", "JSC", "Ltd"]
}

Возвращает 404, если уровня не существует или он принадлежит другому тенанту — без различий (различия выдавали бы существование).

Соответствие имён полей

В companyDataFields / personalInfoFields используются имена, принятые в SDK-форме (incorporatedOn, legalAddress, registrationCountry). В POST /v1/applicants имена полей в теле запроса соответствуют именам в нашей сущности:

Поле API-запроса Имя в SDK / уровне
incorporationDate incorporatedOn
registeredAddress legalAddress
country registrationCountry

Backend конвертирует автоматически. В теле запроса используйте имена сущности; при чтении enabled/required списков используйте ключи уровня.

Как использовать имя уровня

Передайте его как verificationLevelName при старте сессии:

curl -X POST 'https://api.compliance.example/v1/applicants/user-12345/verification-sessions?verificationLevelName=KYC_01&lang=ru&theme=dark&returnUrl=https://acme.com/done' \
  -H 'X-Api-Key: pk_live_...' \
  -H 'X-Api-Secret: ...' \
  -H 'X-Environment: production'

В ответе придёт url, по которому нужно перенаправить пользователя. Полный сценарий сессии — в разделе Quick Start, а необязательные параметры lang / theme / returnUrl / successUrl / errorUrl описаны в Параметрах ссылки сессии.

Что происходит с полями, не включёнными в уровень

Если в payload POST /v1/applicants вы передадите поля, которые выбранный уровень не включает (например, incorporationDate для уровня, чей company_data не содержит incorporatedOn), backend молча отбросит их. Заявитель будет создан с остальными полями. Так интеграция может использовать единый «надмножественный» DTO для нескольких уровней — backend сам оставит то, что нужно конкретному уровню.

Поля, которые партнёр прислал и уровень включает → SDK покажет значение в форме как отключённое (пользователь не сможет его изменить). Поля, которые партнёр не прислал → SDK соберёт сам. Обязательные поля, которые партнёр не прислал, блокируют отправку; необязательные пользователь может пропустить.

Блокировка полей — значения партнёра неизменяемы

Каждое поле идентичности, которое партнёр передал через POST /v1/applicants или PATCH /v1/applicants/{externalUserId}/company-info, запоминается на заявителе и становится неизменяемым из SDK. Контракт:

  • В форме SDK соответствующий input рендерится как disabled — пользователь не может править значение, которым уже владеет партнёр.
  • На бэкенде POST /api/v1/sdk/personal-info отказывается мутировать поле из списка блокировки, если отправленное значение отличается от хранящегося — защита-в-глубину на случай обхода фронтового disabled. В ответе SDK возвращается массив lockedFields: [...] с именами отброшенных полей для отладки.
  • Снять блокировку может только партнёр: вызвать PATCH на поле (на текущее или новое значение). Со стороны SDK разблокировать поле нельзя.

Имена полей в списке блокировки совпадают со словарём personalInfoFields / companyDataFields уровня (имена SDK — incorporatedOn / legalAddress / registrationCountry, не имена из POST /v1/applicants). Backend сам делает соответствие при создании.

Практический случай для KYC, когда партнёр знает только часть: передавайте то, что знаете, при создании. Пользователь дозаполнит остальное в SDK; известные партнёру поля останутся как есть. Если не хотите блокировать поле — просто не передавайте его в payload создания: SDK соберёт его сам, редактируемым.