Identity Verification (KYC)
Персональная KYC-верификация — flow для подтверждения личности любого физического лица в системе: end-user'а вашего приложения, держателя кошелька, владельца API-ключа. Состоит из загрузки документов, верификации телефона по SMS и проверки статуса.
ℹ
KYC vs KYB
Эта страница — про KYC (Know Your Customer): идентификация физического лица (паспорт + селфи + телефон). Для верификации юридического лица (компании) используется KYB API — другой набор данных (ОГРН/ИНН, директор, бухгалтер, бенефициары, 12+ типов документов, AML-проверка).
В B2B-сценарии перед KYC-операциями партнёр обязан зафиксировать факт согласия end-user'а через POST /customers/{uuid}/consent. Для собственного аккаунта KYC проводится через mobile-эндпоинты (см. Authentication).
ℹ
Когда нужен KYC
Платежи (buy/sell/withdraw) требуют kyc_status = 'verified'. Без верификации возвращается 422 KYC_REQUIRED. Чтение баланса и история транзакций KYC не требуют.
Стандартный flow
- Consent —
POST /customers/{uuid}/consent(один раз на customer'а). - Start session —
POST /customers/{uuid}/kyc/startс phone + passport_type. - Upload documents —
POST /customers/{uuid}/kyc/documentsmultipart c selfie/passport/address. - Request SMS code —
POST /customers/{uuid}/kyc/request-code. - Verify code —
POST /customers/{uuid}/kyc/verify-codeс 6-значным кодом → переход вverified. - Poll status —
GET /customers/{uuid}/kyc/statusв любое время. Или подпишитесь на webhookcustomer.kyc.verified.
Жизненный цикл
kyc_status переходы
| Name | Type | Required | Description |
|---|---|---|---|
not_started
|
|
optional | Начальное состояние, KYC ещё не запускался. |
pending
|
после start
|
optional | Session создана, ожидаем documents/phone. |
processing
|
после documents
|
optional | Документы загружены, идёт верификация (для live — провайдером). |
verified
|
финальный
|
optional | KYC успешно пройден. Платежи разрешены. |
rejected
|
финальный
|
optional |
Документы отклонены. Причина в kyc_rejection_reason. Возможен reset.
|
expired
|
финальный
|
optional | KYC просрочен (raz v 3 года). Требуется reset + повтор. |
Уровни KYC
kyc_level
| Name | Type | Required | Description |
|---|---|---|---|
0
|
Anonymous
|
optional | KYC не пройден. Платежи запрещены. |
1
|
Phone+Email
|
optional | Базовая верификация. Депозиты до 500 USD/день, без вывода. |
2
|
ID Verified
|
optional | Документы и SMS пройдены. Все операции до 10 000 USD/день. |
3
|
Address Proof
|
optional | Подтверждённый адрес. Без дневных лимитов (subject to AML). |
Старт верификации
POST
/api/v1/customers/{uuid}/kyc/start
⚷
Bearer Token
Создать KYC-сессию
Создаёт upstream-сессию (в sandbox — мок). Должен вызываться после
POST /consent.Request body
| Name | Type | Required | Description |
|---|---|---|---|
phone
|
string
|
required | E.164 формат. |
passport_type
|
enum
|
optional |
ru (РФ паспорт + адрес) или foreign (загранник + текстовый адрес).
Default:
ru |
Responses
{
"data": {
"session_id": "sbx_aXmjv1X5tw9J8CLdynh6ZfE8",
"next": "upload_documents",
"env": "sandbox",
"customer_uuid": "5f8d7a3c-...",
"kyc_status": "pending"
}
}
{
"message": "The given data was invalid.",
"errors": {
"consent": ["End-user consent must be recorded before KYC operations. POST /api/v1/customers/{uuid}/consent first."]
}
}
Загрузка документов
POST
/api/v1/customers/{uuid}/kyc/documents
⚷
Bearer Token
Multipart upload документов
Content-Type: multipart/form-data. Каждое поле опционально, но все 3 типа обычно нужны для уровня 2.Files
| Name | Type | Required | Description |
|---|---|---|---|
selfie
|
file
|
optional | Фото лица. jpg/jpeg/png/pdf, до 10 MB. |
passport
|
file
|
optional | Скан/фото паспорта. То же ограничение. |
address
|
file
|
optional | Подтверждение адреса (proof of address). Опционально. |
⚠
Хранение
Файлы хранятся в Finance OS. Партнёр не должен хранить их у себя после успешного аплоада — это нарушает GDPR / 152-ФЗ. Удалите файлы локально сразу после ответа 200.
SMS-код
POST
/api/v1/customers/{uuid}/kyc/request-code
⚷
Bearer Token
Запросить код подтверждения
Отправляет 6-значный код на телефон, указанный в
start. В sandbox возвращает фиксированный mock-код для тестирования.Responses
{
"data": {
"sent": true,
"channel": "sandbox",
"mock_code": "000000",
"expires_in": 300,
"note": "In sandbox the code \"000000\" always succeeds."
}
}
{
"data": {
"sent": true,
"channel": "sms",
"expires_in": 300
}
}
Проверка кода
POST
/api/v1/customers/{uuid}/kyc/verify-code
⚷
Bearer Token
Завершить верификацию
Передайте 6-значный код. При успехе customer переходит в
verified + уровень 2. Партнёрский webhook customer.kyc.verified диспатчится автоматически.Request body
| Name | Type | Required | Description |
|---|---|---|---|
code
|
string
|
required |
6 цифр. В sandbox только 000000 проходит.
|
Responses
{
"data": {
"customer_uuid": "5f8d7a3c-...",
"kyc_status": "verified",
"kyc_level": 2
}
}
{
"message": "The given data was invalid.",
"errors": {"code": ["Invalid code. In sandbox the code \"000000\" always succeeds."]}
}
Статус
GET
/api/v1/customers/{uuid}/kyc/status
⚷
Bearer Token
Текущий статус верификации
Responses
{
"data": {
"kyc_status": "verified",
"kyc_level": 2,
"kyc_rejection_reason": null,
"consent_signed": true,
"documents": {
"selfie_uploaded": true,
"passport_state": "success",
"address_state": "success"
},
"phone": "+79001234567",
"env": "live",
"attempts_remaining": 5
}
}
Reset
POST
/api/v1/customers/{uuid}/kyc/reset
⚷
Bearer Token
Сбросить сессию и начать заново
Удаляет загруженные документы и сбрасывает
kyc_status в not_started. Полезно при rejected. Rate-limit: 5 reset'ов в 24 часа на customer.Коды ошибок
| Name | Type | Required | Description |
|---|---|---|---|
CONSENT_REQUIRED
|
422
|
optional |
Не было вызова POST /consent перед KYC-операцией.
|
SESSION_NOT_STARTED
|
422
|
optional |
Не было POST /kyc/start перед документами/кодом.
|
INVALID_CODE
|
422
|
optional | Неверный SMS-код. |
RATE_LIMITED
|
422
|
optional | Превышен лимит reset (5/24h). |
PROVIDER_DOWN
|
422
|
optional | Upstream verification провайдер недоступен. Retry через минуту. |