--- title: "Проверка клиента" url: "https://docs.x-hub.online/exchange/kyc/" description: "Подача документов, статусы и повторная подача после отказа." relatedDocuments: - "https://docs.x-hub.online/exchange/" --- # KYC (Know Your Customer) KYC — верификация **конечного клиента** мерчанта (того кто платит). **Не мерчанта.** Нужен только для: - Платежей на суммы выше настроенного порога (если настроено); - Обменов (`/exchanges`) в обе стороны — USDT↔RUB; - Некоторых категорий мерчантов по решению X-Hub. Если твой аккаунт не требует KYC — пропусти этот раздел. Все три KYC-эндпоинта вернут `{"status": "not_required"}` или `400 KYC_NOT_REQUIRED`. ## Два способа интеграции KYC У мерчанта два варианта — выбери один: ### Способ 1: Hosted redirect (простой) X-Hub предоставляет готовую страницу верификации. Мерчант перенаправляет своего клиента туда, клиент заполняет форму (телефон, селфи, паспорт, адрес), после верификации возвращается на сайт мерчанта. ``` https://app.x-hub.online/kyc?phone=+79001234567&redirect=https://your-site.com/kyc-done ``` **Query-параметры:** | Параметр | Обяз. | Описание | |---|---|---| | `phone` | — | Телефон клиента в формате `+7XXXXXXXXXX` (можно не передавать — клиент введёт сам) | | `redirect` | — | URL, куда вернуть клиента после завершения. Только HTTPS, только same-origin с твоим доменом. Если не указан — редирект на `/` | Плюсы: ничего не надо писать на стороне мерчанта. Минусы: клиент уходит с твоего сайта, меньше контроля над UX. ### Способ 2: API-first (встроенный в UI мерчанта) Мерчант делает KYC-форму внутри своего приложения (свой UI, свой дизайн), а вызывает наши API для загрузки документов и регистрации. Клиент не покидает сайт мерчанта. Flow (со стороны backend мерчанта): 1. `POST /v1/kyc/check` → проверить, нужен ли KYC и не пройден ли уже; 2. `POST /v1/kyc/upload-url` × 3 → получить signed URL на селфи / паспорт / адрес; 3. Фронтенд мерчанта загружает файлы напрямую на upload URL (PUT, без прохождения через backend); 4. `POST /v1/kyc/register` → передать `file_key`'и + `phone`; 5. Периодически `POST /v1/kyc/check` → дождаться `status: verified`. Плюсы: полный контроль UX и брендинга. Минусы: больше кода на стороне мерчанта, своя форма загрузки файлов. **Детали всех endpoints — ниже.** ## Когда нужен KYC Если при создании платежа вы получаете ошибку: ```json { "error": { "code": "KYC_REQUIRED", "message": "..." } } ``` — значит для вашего аккаунта настроена обязательная KYC-проверка. Используйте flow ниже. ## Если ошибки нет Если при создании платежа вы НЕ получаете `KYC_REQUIRED` — KYC не требуется. Можете пропустить этот раздел. Все три KYC-эндпоинта вернут `{"status": "not_required"}` или `400 KYC_NOT_REQUIRED`. ## Проверить KYC — POST /kyc/check Проверяет статус KYC-верификации клиента по номеру телефона. ```bash curl -X POST https://api.x-hub.online/api/v1/kyc/check \ -H "X-Api-Key: ..." -H "X-Api-Secret: ..." \ -H "Content-Type: application/json" \ -d '{"phone": "+79991234567"}' ``` ### Body | Поле | Тип | Обяз. | Описание | |---|---|---|---| | `phone` | string | ✓ | Телефон клиента в формате `+7XXXXXXXXXX` | ### Ответы **KYC не требуется** (для вашего аккаунта не настроен): ```json {"status": "not_required"} ``` **KYC верифицирован:** ```json {"status": "verified", "accountNumber": "..."} ``` **KYC не пройден (нужна регистрация):** ```json {"status": "required", "kyc_url": "https://..."} ``` **KYC в обработке:** ```json {"status": "processing"} ``` **KYC отклонён:** ```json {"status": "failed", "error": "..."} ``` ### Ошибки KYC-эндпоинтов { #kyc-errors } Одинаковы для всех трёх (`/kyc/check`, `/kyc/upload-url`, `/kyc/register`): | HTTP | Code | Причина | Что делать | |---|---|---|---| | 400 | `SANDBOX_NOT_SUPPORTED` | KYC в песочнице недоступен для конфигурации твоего аккаунта | Тестируй KYC в боевом режиме или напиши в X-Hub | | 400 | `KYC_NOT_REQUIRED` | KYC для аккаунта не настроен (`/upload-url`, `/register`). У `/kyc/check` тот же случай даёт `200 {"status":"not_required"}` | Просто создавай платежи, KYC не нужен | | 400 | `VALIDATION_ERROR` | Невалидный `phone` / `content_type` / состав ключей файлов | Проверь формат | | **403** | **`PROVIDER_DISABLED`** | **KYC для твоего аккаунта отключён.** Отдаётся до любой другой проверки — то есть даже валидный запрос получит `403` | Это не ошибка запроса и не «не пройден KYC». Ретрай не поможет: напиши в X-Hub | | **502** | **`PROVIDER_ERROR`** | Проверяющая сторона не ответила (сеть, таймаут, её `5xx`) | Временная ошибка. Ретрай через 30–60 сек | | **503** | **`KYC_UNAVAILABLE`** | **Твоему аккаунту KYC положен, но верификация сейчас недоступна на нашей стороне** (внутренняя неполадка X-Hub, не твоей интеграции) | Это **не** «KYC не нужен» — не пропускай верификацию клиента. Ретрай через 1–2 минуты; если долго — напиши в X-Hub | | **500** | **`KYC_PERSIST_FAILED`** | Только на `/kyc/register`: проверяющая сторона клиента уже приняла, но у нас не сохранилась запись об этом — сбой уже ПОСЛЕ успешного шага верификации | **Не повторяй запрос с теми же данными.** Напиши в X-Hub с временем запроса и телефоном/e-mail клиента — восстановим вручную | !!! warning "`403 PROVIDER_DISABLED` легко спутать с отказом в верификации" Это **не** «клиент не прошёл KYC» — отказ по клиенту приходит как `{"status": "failed"}` с `200`. `403 PROVIDER_DISABLED` означает, что KYC для твоего аккаунта отключён, и ни один клиент верифицироваться не сможет. Если он появился внезапно — не переписывай интеграцию, сначала спроси команду X-Hub. !!! warning "`503 KYC_UNAVAILABLE` — тоже не «KYC не нужен»" Если твой аккаунт настроен на KYC, `KYC_NOT_REQUIRED` / `{"status":"not_required"}` ты в норме никогда не увидишь. `503 KYC_UNAVAILABLE` значит ровно обратное: KYC нужен, но сейчас сломан на нашей стороне. Не интерпретируй его как разрешение пропустить верификацию клиента. ## Получить URL для загрузки документов — POST /kyc/upload-url Получает pre-signed URL для загрузки документов KYC (фото паспорта, селфи). ```bash curl -X POST https://api.x-hub.online/api/v1/kyc/upload-url \ -H "X-Api-Key: ..." -H "X-Api-Secret: ..." \ -H "Content-Type: application/json" \ -d '{"content_type": "image/jpeg"}' ``` ### Body | Поле | Тип | Обяз. | Описание | |---|---|---|---| | `content_type` | string | ✓ | MIME-тип файла (`image/jpeg`, `image/png`, `application/pdf`) | ### Ответ ```json { "upload_url": "https://storage.example.com/...", "file_key": "kyc/abc123..." } ``` Загрузи файл по `upload_url` (PUT), затем используй `file_key` в POST /kyc/register. ## Зарегистрировать KYC — POST /kyc/register { #kyc-register } Отправляет данные KYC-верификации в X-Hub. ```bash curl -X POST https://api.x-hub.online/api/v1/kyc/register \ -H "X-Api-Key: ..." -H "X-Api-Secret: ..." \ -H "Content-Type: application/json" \ -d '{ "phone": "+79991234567", "selfie_key": "kyc/selfie-abc123", "document_key": "kyc/doc-def456", "address_key": "kyc/addr-ghi789" }' ``` ### Body | Поле | Тип | Обяз. | Описание | |---|---|---|---| | `phone` | string | ✓ | Телефон клиента в формате `+7XXXXXXXXXX`. Единственное поле, обязательное всегда | | `selfie_key` | string | * | `file_key` от upload-url (селфи) | | `document_key` | string | * | `file_key` от upload-url (документ) | | `address_key` | string | | `file_key` от upload-url (подтверждение адреса) | | `email` | string | * | E-mail клиента | | `user_type` | string | * | `individual` или `legal_entity` | !!! note "Какие из полей со звёздочкой нужны — зависит от KYC-конфигурации аккаунта" Конфигураций две, и обязательный набор у них разный: - **загрузка документов** — нужны `selfie_key` + `document_key` (плюс опционально `address_key`); - **переадресация клиента на форму верификации** — нужны `email` + `user_type`, файлы не нужны; в ответе придёт `{"status": "required", "kycUrl": "..."}`, и клиента надо отправить по этому адресу. Валидация тела **не** проверяет комбинацию: запрос без нужных полей пройдёт схему и упрётся уже в проверяющую сторону (`502 PROVIDER_ERROR` или отказ по клиенту). Какая конфигурация у тебя — уточни при подключении. ### Ответ ```json {"status": "processing"} ``` Либо `{"status": "required", "kycUrl": "..."}` — если клиента нужно отправить на форму верификации, либо `{"status": "verified", "accountNumber": "..."}` — если он уже верифицирован. !!! tip "Повторный `register` по тому же телефону безопасен" Если клиент уже верифицирован (или ему уже выдана ссылка на верификацию), повторный вызов вернёт **сохранённый** результат, не запуская проверку заново. Исключение — клиент, которому ранее отказали: такой запрос уйдёт на новую проверку. !!! warning "Исключение — `500 KYC_PERSIST_FAILED`: это НЕ тот безопасный повтор" Если ответ — `500 KYC_PERSIST_FAILED`, «сохранённого результата» из подсказки выше ещё нет: у нас не записалась информация о том, что клиент уже прошёл шаг верификации. Слепой повтор `register` с теми же данными может уйти в новую попытку регистрации у проверяющей стороны — для части конфигураций это ломает саму возможность зарегистрировать клиента повторно. Не повторяй — пиши в X-Hub. После регистрации — периодически проверяй статус через POST /kyc/check. ## Интеграция KYC + платежи Если для вашего аккаунта требуется KYC, при создании платежа передавай `client_phone`: ```bash curl -X POST https://api.x-hub.online/api/v1/payments \ -H "X-Api-Key: ..." -H "X-Api-Secret: ..." \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "amount_rub": "500.00", "payment_method": "sbp", "client_phone": "+79991234567" }' ``` Если KYC не пройден, API вернёт: - `400 KYC_REQUIRED` — клиент не верифицирован - `400 KYC_PROCESSING` — верификация в процессе, попробуй позже - `400 KYC_FAILED` — верификация отклонена ---