# Начало работы

Чтобы приступить к работе с IDnGO:

  1. Войдите в Дешборд.
  2. Настройте доступы для пользователей в вашей компании, пригласите свою команду и определите роли и разрешения.
  3. Создайте уровень верификации.
  4. Кастомизируйте верификацию под ваш сервис.
  5. Пройдите аутентификацию.
  6. Выберите подходящий способ интеграции:

WebSDK → iOS SDK → Android SDK → API-интеграция →

# Аутентификация

Чтобы начать работу с SDK и API от IDnGO, все клиенты должны пройти аутентификацию.

# App токен

В разделе «Панель разработчика» Дешборда нужно сгенерировать appToken и secretKey, далее на их основе генерируется accessToken.
Для каждого окружения (Тестовое или Основное) необходим свой App токен.

Внимание:

Значения appToken и secretKey отображаются только один раз в момент создания токена, позже будет невозможно просмотреть или изменить настройки этого токена.

# Заголовки авторизации

Все API-запросы должны содержать следующие заголовки:

  • X-App-Token — токен приложения, сгенерированный в панели управления;
  • X-App-Access-Sig — подпись запроса в шестнадцатеричном формате, строчными буквами;
  • X-App-Access-Ts — количество секунд с начала Unix-эпохи (в UTC).

Имена заголовков нечувствительны к регистру и могут различаться в зависимости от реализации как на стороне ваших запросов, так и в наших ответах.

# Подпись запроса

Значение X-App-Access-Sig генерируется алгоритмом HMAC-SHA256 с использованием секретного ключа secretKey (предоставляется при создании appToken) на основе строки, полученной путём объединения следующей информации:

  1. Временная метка (значение заголовка X-App-Access-Ts);

Временная метка должна быть в пределах 1 минуты от времени нашего сервера. Убедитесь, что время на ваших серверах правильное.

  1. Название HTTP-метода в верхнем регистре (например, GET или POST);
  2. URI запроса без имени хоста, начиная со слэша и включая все параметры запроса, например: /resources/applicants/123?fields=info;
  3. Тело запроса (если есть) в том виде, в каком оно будет отправлено.

Пример строки, из которой будет сгенерирована подпись:

1607551635POST/resources/accessTokens?userId=cfd20712-24a2-4c7d-9ab0-146f3c142335&levelName=basic-kyc-level&ttlInSecs=600

# POST Генерация токена доступа

При инициализации SDK необходимо использовать токен доступа accessToken. Для его получения нужно отправить запрос:

POST /resources/accessTokens?userId={userId}&levelName={levelName}

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

При инициализации SDK убедитесь, что для заголовков авторизации запроса используется пара appToken и secretKey, созданная в правильном окружении (Тестовое или Основное):

  • Для тестирования используйте пару appToken и secretKey, созданную в Тестовом окружении (Sandbox);
  • Для реальных проверок пару appToken и secretKey, созданную в Основном окружении (Production).

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

Название Тип Обязательно Описание
userId String Да Внешний идентификатор пользователя, который будет привязан к токену. Он соответствует externalUserId анкеты пользователя.
levelName String Да Название уровня верификации.
ttlInSecs Integer Нет Срок действия токена в секундах (по умолчанию — 600 секунд).
externalActionId String Нет Внешний идентификатор действия пользователя (actions), который будет привязан к токену.

Параметр запроса userId должен быть уникальным и осмысленным. Это может быть внешний идентификатор пользователя в вашей системе или адрес электронной почты. Не генерируйте эти идентификаторы случайным образом, если только вы не проводите тестирование.

Внимание:

Если ваш userId или levelName содержит зарезервированные символы (например, «@», «+»), его следует закодировать в URL, иначе вы можете столкнуться с несоответствием подписи.

Ответ

Название Тип Описание
token String Сгенерированный токен доступа для верификации пользователя.

Пример

# Вебхуки

Вебхуки от IDnGO — это инструмент, который позволяет автоматически получать уведомления о различных событиях и изменениях, связанных с процессом верификации ваших пользователей.

После завершения проверки пользователя мы отправим вам POST-запрос с полезной нагрузкой в формате JSON на URL, предоставленный нам при интеграции. Зачастую URL-адреса различаются для Тестового и Основного окружения.

Внимание:

  • Мы не отправляем никакой информации на эндпоинт по протоколу HTTP, только HTTPS.
  • Поддерживаемые версии протокола TLS1.2 или выше.
  • Существует ограничение на количество вебхуков: не более 20.
  • Мы не передаем никаких личных данных через вебхуки. Вы можете получить все распознанные данные пользователя при помощи этого API-метода.
  • Если вы не получаете от нас вебхуков, попробуйте сначала проверить свои эндпоинты с помощью SSL Labs или Docker.

Пожалуйста, протестируйте ваш вебхук, прежде чем отправлять его URL нам. Он не должен выдавать HTTP-ответ 500 или требовать какой-либо авторизации.

Вы можете отслеживать и анализировать каждое событие во вкладке «Журналы вебхуков».

Так как при API-интеграциии в Тестовом окружении (Sandbox) не происходят автоматической проверки, необходимо задать параметры верификации с помощью этого запроса. После чего можно получить результаты проверки в Тестовом окружении через вебхук applicantReviewed.

На случай, если по какой-то причине вебхук не был получен, мы записываем все, что пытаемся отправить вам, и можем повторно отправить вебхук в любой момент. Если вебхук не удается отправить, мы делаем это повторно четыре раза: через 5 минут, 1 час, 5 и 18 часов, до тех пор пока запрос не будет успешным. Рекомендуем вам дожидаться вебхука не более суток, а затем отправить запрос на наш сервер для получения информации о статусе пользователя.

Проверяйте поле createdAtMs полезной нагрузки вебхука, чтобы убедиться, что вы получаете актуальный статус пользователя.

# Типы вебхуков

Настраивать типы, отслеживать статусы вебхуков и отправлять их вручную можно в разделе «Менеджер вебхуков».

Значение Описание
applicantCreated Создана анкета пользователя.
applicantPending Все необходимые документы пользователем загружены и анкета ожидает проверки.
applicantReviewed Верификация пользователя завершена. Содержит результат верификации.
applicantOnHold Пользователь ожидает окончательного решения от специалиста по соблюдению нормативных требований (начата ручная проверка).
applicantReset Анкета пользователя была сброшена: статус пользователя изменился на init, и все документы стали неактивны, ожидается загрузка новых изображений/данных.
applicantPersonalInfoChanged Предоставленная информация пользователя была изменена.
applicantPrechecked Завершена первичная проверка пользователя.
applicantDeleted Пользователь был удален навсегда.
applicantLevelChanged Уровень проверки был изменен.
applicantActionPending Действия пользователя ожидают проверки.
applicantActionReviewed Проверка действий пользователя завершена.
applicantActionOnHold Действие пользователя ожидает окончательного решения от специалиста по соблюдению нормативных требований.

Поля полезной нагрузки вебхука

Название Тип Обязательно Описание
applicantId String Да Идентификатор пользователя.
inspectionId String Да Идентификатор проверки.
correlationId String Да Идентификатор, который однозначно идентифицирует событие на нашей стороне.
levelName String Нет Название уровня верификации.
externalUserId String Нет Внешний идентификатор пользователя – уникальный идентификатор пользователя на вашей стороне.
type String Да Тип вебхука.
sandboxMode Boolean Да True, если вебхук был отправлен из Тестового окружения (Sandbox).
reviewStatus String Да Текущий статус пользователя. Более подробную информацию можно найти здесь.
createdAtMs Date Да Дата и время создания вебхука в UTC (формат YYYY-MM-dd hh:mm:ss.fff).
applicantType String Нет Тип пользователя, например, individual/company.
reviewResult Object Нет Поле, содержащее дополнительную информацию о результатах верификации пользователя.
applicantMemberOf Array of objects Нет Содержит список анкет компаний, к которым относится текущий пользователь в качестве бенефициара.
applicantActionId String Нет Идентификатор действия пользователя.
externalApplicantActionId String Нет Уникальный идентификатор действия на вашей стороне.
clientId String Да Уникальный идентификатор вас как нашего клиента.

# Причины отказа

Вебхук с результатом верификации содержит поле rejectLabels, в котором указаны один или более тегов, описывающих причину отказа. Теги rejectLabels нужны только для анализа результатов проверок и они лишь обобщенно описывают проблему, поэтому не стоит использовать их для генерации комментариев для пользователя.

Тег отказа
(значение rejectLabels)
Тип отказа
reviewRejectType
Описание
FORGERY FINAL Попытка мошенничества.
SPAM FINAL Было загружено слишком много изображений (спам фотографиями).
BAD_PROOF_OF_IDENTITY RETRY Тип предоставленного документа не подходит для верификации/на изображении нет документа, документ без подписей или печатей.
SELFIE_MISMATCH FINAL Фотография пользователя (селфи) не совпадает с фотографией на предоставленных документах.
ID_INVALID RETRY Документ, удостоверяющий личность, недействителен.
DUPLICATE FINAL У этого пользователя уже есть проверенная ранее анкета, а дублирование не допускается настройками.
BAD_AVATAR RETRY Аватар не соответствует требованиям.
WRONG_USER_REGION FINAL Запрещены пользователи из данного региона/страны.
INCOMPLETE_DOCUMENT RETRY Документ на фотографии виден частично из-за чего отсутствует часть информации.
BLACKLIST FINAL Пользователь занесен в черный список нами.
BLOCKLIST FINAL Пользователь занесен в черный список вами.
UNSATISFACTORY_PHOTOS RETRY На изображении видны следы обработки в графическом редакторе.
DOCUMENT_PAGE_MISSING RETRY Отсутствуют нужные для проверки страницы документа.
DOCUMENT_DAMAGED RETRY Документ поврежден.
REGULATIONS_VIOLATIONS FINAL Пользователь не соответствует требованиям проверки.
INCONSISTENT_PROFILE FINAL В анкете были обнаружены данные или документы разных людей.
ADDITIONAL_DOCUMENT_REQUIRED RETRY Для прохождения верификации требуются дополнительные документы.
AGE_REQUIREMENT_MISMATCH FINAL Возраст пользователя не соответствует требованиям.
EXPERIENCE_REQUIREMENT_MISMATCH FINAL Опыт пользователя не соответствует требованиям (например, опыт вождения).
CRIMINAL FINAL Пользователь был вовлечен в незаконную деятельность.
WRONG_ADDRESS RETRY Адрес из документов не совпадает с адресом, который ввел пользователь.
GRAPHIC_EDITOR RETRY Фотография была отредактирована в графическом редакторе.
DOCUMENT_DEPRIVED RETRY Документ у пользователя был изъят.
FRAUDULENT_PATTERNS FINAL Обнаружено мошенническое поведение.
NOT_ALL_CHECKS_COMPLETED RETRY Не все проверки были завершены.
FRONT_SIDE_MISSING RETRY Отсутствует лицевая сторона/главный разворот документа.
BACK_SIDE_MISSING RETRY Обратная сторона/разворот документа отсутствует.
SCREENSHOTS RETRY Пользователь загрузил скриншоты.
BLACK_AND_WHITE RETRY Пользователь загрузил черно-белые фотографии документов.
INCOMPATIBLE_LANGUAGE RETRY Требуется перевод документа.
EXPIRATION_DATE RETRY Пользователь загрузил документ с истекшим сроком действия.
BAD_SELFIE RETRY Пользователь загрузил плохое селфи.
BAD_FACE_MATCHING RETRY Не удается сверить лицо в документе с лицом на селфи.
BAD_PROOF_OF_ADDRESS RETRY Пользователь загрузил плохой документ подтверждащий адрес проживания PoA.
FRAUDULENT_LIVENESS FINAL Была попытка обойти проверку живости (liveness).
OTHER RETRY Иная причина.
PROBLEMATIC_APPLICANT_DATA RETRY Предоставленная информация не совпадает с информацией, полученной из документа.
OK RETRY Пользовательский тег отказа.

Пример

# Пример полезной нагрузки вебхука applicantReviewed:

# Пример полезной нагрузки вебхука applicantCreated:

{
  "applicantId": "5c9e177b0a975a6eeccf5960",
  // inspection ID that contains a result
  "inspectionId": "5c9e177b0a975a6eeccf5961",
  // an ID to debug in case of unexpected errors (should be provided to IDnGO)
  "correlationId": "req-63f92830-4d68-4eee-98d5-875d53a12258",
  "levelName": "basic-kyc-level",
  "externalUserId": "12672",
  // type of webhook (see the corresponding section)
  "type": "applicantCreated",
  "sandboxMode": "false",
  "reviewStatus": "init",
  "createdAtMs": "2020-02-21 13:23:19.001",
  "clientId": "cyberityClient"
}

# Пример полезной нагрузки вебхука applicantPending:

{
  "applicantId": "5c7791f80a975a1df426b9e9",
  "inspectionId": "5c7791f80a975a1df426b9ea",
  "applicantType" : "individual",
  "correlationId": "req-4af54c06-6a50-4cb9-a7dc-b94b2f5b07eb",
  "levelName": "liveness-level",
  "externalUserId": "12672",
  "type": "applicantPending",
  "sandboxMode": "false",
  "reviewStatus": "pending",
  "createdAtMs": "2020-02-21 13:23:19.001",
  "clientId": "cyberityClient"
}

# Пример полезной нагрузки вебхука applicantOnHold:

{
  "inspectionId": "5d10ca4e0a975a1c4cc30bbb",
  "applicantType" : "individual",
  "correlationId": "req-a98abc30-a5d9-4e1d-bab4-2f1af64bd5a5",
  "levelName": "poa-level",
  "externalUserId": "12672",
  "reviewStatus": "onHold",
  "applicantId": "5d10ca4e0a975a1c4cc30bba",
  "type": "applicantOnHold",
  "sandboxMode": "true",
  "createdAtMs": "2020-02-21 13:23:19.001",
  "clientId": "cyberityClient"
}

# Пример полезной нагрузки вебхука applicantPersonalInfoChanged:

{
  "applicantId" : "5ede51230a975a19a19ba5c1",
  "inspectionId" : "5ede51230a975a19a19ba5c2",
  "applicantType" : "individual",
  "correlationId" : "req-60103dee-79f1-43f4-bdcc-eb2554556afa",
  "levelName": "id+liveness",
  "externalUserId" : "12672",
  "type" : "applicantPersonalInfoChanged",
  "sandboxMode": "false",
  "reviewResult" : {
    "reviewAnswer" : "GREEN"
  },
  "reviewStatus" : "completed",
  "createdAtMs" : "2020-06-08 19:39:29.001",
  "clientId": "cyberityClient"
}

# Пример полезной нагрузки вебхука applicantPrechecked:

{
  "applicantId": "5d1f2914c2d75a1c14130bd2",
  "inspectionId": "5d1f2914c2d75a1c14130bd3",
  "applicantType" : "individual",
  "correlationId": "req-e9d77142-59e6-4713-9b07-9b342cc51dda",
  "levelName": "kyc",
  "externalUserId": "12672",
  "type": "applicantPrechecked",
  "sandboxMode": "false",
  "reviewStatus": "queued",
  "createdAtMs": "2020-02-21 13:23:19.001",
  "clientId": "cyberityClient"
}

# Пример полезной нагрузки вебхука applicantDeleted:

{
  "applicantId": "5f194e74040c3f316bda271c",
  "inspectionId": "5f194e74040c3f316bda271d",
  "applicantType": "individual",
  "correlationId": "req-d34c974c-5935-41b8-a0a9-cedd2407eada",
  "levelName": "phone-level",
  "externalUserId": "12672",
  "type": "applicantDeleted",
  "sandboxMode": "false",
  "reviewStatus": "init",
  "createdAtMs": "2020-07-23 11:18:33.001",
  "clientId": "cyberityClient"
}

# Пример полезной нагрузки вебхука applicantLevelChanged:

{
  "applicantId": "5f194e74040c3f316bda271c",
  "inspectionId": "5f194e74040c3f316bda271d",
  "applicantType": "individual",
  "correlationId": "req-d34c974c-5935-41b8-a0a9-cedd2407eadd",
  "levelName": "basic-kyc-level",
  "externalUserId": "12672",
  "type": "applicantLevelChanged",
  "sandboxMode": "false",
  "reviewStatus": "init",
  "createdAtMs": "2020-07-23 11:19:33.002",
  "clientId": "cyberityClient"
}

# Пример полезной нагрузки вебхука applicantReset:

{
  "applicantId": "5f194e74040c3f316bda271c",
  "inspectionId": "5f194e74040c3f316bda271d",
  "applicantType": "individual",
  "correlationId": "req-57fed49a-07b8-4413-bdaa-a1be903769e9",
  "levelName": "basic-kyc-level",
  "externalUserId": "12672",
  "type": "applicantReset",
  "sandboxMode": "false",
  "reviewResult": {
    "reviewAnswer": "GREEN"
  },
  "reviewStatus": "init",
  "createdAtMs": "2021-03-01 11:34:51.001",
  "clientId": "cyberityClient"
}

# Проверка отправителя вебхука

Лучше не полагаться на наши IP-адреса при составлении белого списка отправителей вебхуков, поскольку они могут время от времени меняться.

Чтобы убедиться, что вебхук отправлен именно нами, можно воспользоваться подписью с помощью алгоритма HMAC. Если вы хотите воспользоваться этой функцией, задайте значение секретного ключа для каждого вебхука и выберите алгоритм HMAC в «Панели разработчика» Дешборда.

При использовании подписи мы также отправляем дополнительный заголовок X-Payload-Digest-Alg, в котором указывается один из следующих алгоритмов:

  • HMAC_SHA1_HEX — устарел
  • HMAC_SHA256_HEX — используется по умолчанию при создании нового вебхука
  • HMAC_SHA512_HEX

Инструкция проверки отправителя вебхука:

  1. Получите значение заголовка вебхука x-payload-digest и полезную нагрузку как она есть, без каких-либо изменений или преобразования в JSON.
  2. Получите тело HTTP-вебхука в байтах.
  3. Вычислите контрольное значение (digest) с использованием исходной полезной нагрузки в байтах и алгоритма HMAC, указанного в заголовке x-payload-digest-alg.
  4. Сравните значение заголовка x-payload-digest с вычисленным вами контрольным значением.

Проверка отправителя вебхука: POST /resources/inspectionCallbacks/testDigest?secretKey={secretKey}

# Пример запроса к вашему эндпоинту:

curl -X POST \
  'https://callbackurl.com/kyc' \
  -H 'Content-Type: application/json' \
  -d '{
    "applicantId": "5cb56e8e0a975a35f333cb83",
    "inspectionId": "5cb56e8e0a975a35f333cb84",
    "correlationId": "req-ec508a2a-fa33-4dd2-b93d-fcade2967e03",
    "externalUserId": "12672",
    "type": "applicantReviewed",
    "reviewResult": {
        "reviewAnswer": "GREEN"
    },
    "reviewStatus": "completed",
    "createdAtMs": "2020-02-21 13:23:19.111",
    "clientId": "CyberityClient"
}'

# Пример вычисления контрольного значения digest: