ВВалидатор API
О продукте

Валидатор API

Проверка подлинности чеков об оплате. Вы отдаёте чек и данные заявки - получаете один статус и одно действие: проводить платёж, посмотреть руками или попросить новый чек.

Куда слать запросы Все примеры работают против открытой песочницы https://chekvalidator.com/sandbox: ключ - любая строка от 8 символов, договор не нужен. Боевой адрес и ключ выдаются при подключении; пути, поля и ответы те же.

Как это работает

Путей приёма чека два, дальше они сходятся: та же проверка, те же статусы, те же вебхуки.

Путь 1, основной - чек прикладывает плательщик

Файл к вам не попадает вовсе: своя форма загрузки и хранилище чужих чеков не нужны.

  1. Вы заводите заявку запросом POST /v1/upload-links с полями заявки. В ответе сразу все адреса: upload_url - страница для плательщика, embed_url - она же рамкой на вашем сайте, email_address - адрес для письма из банка, а для вас status_url и receipt_url.
  2. Плательщик открывает страницу (GET /u/{token}) и прикладывает фото, снимок экрана или PDF. Ключ API ему не нужен: пропуск - токен ссылки со сроком и лимитом попыток.
  3. Судьба заявки - одним адресом GET /v1/upload-links/{token}: file_received - чек приложен (останавливайте свой таймер), checking и eta_seconds - идёт проверка, job_id и verdict - готово. Не подошёл чек - плательщик шлёт новый по той же ссылке, счёт виден в attempts и resend_left_seconds.

Путь 2 - чек отдаёте вы

Файл уже у вас: из вашей формы, от другой системы или из архива.

  1. Вы отдаёте чек запросом POST /v1/receipts:validate: файл (или временная ссылка на него) плюс поля заявки. Ответ приходит сразу, проверка идёт в фоне.
  2. Вердикт приходит вебхуком или забирается запросом GET /v1/receipts/{job_id}. Нужен ответ одним запросом - добавьте wait_seconds.
Ваш случайЧто взять
Своей формы для файла нет: плательщик в мессенджере, у оператора, в чате поддержкиСсылка загрузки - путь 1
Форма есть, файл приходит к вамПодача файлом - путь 2
Чек лежит в вашем хранилищеПодача ссылкой - файл заберём сами
Нужен синхронный фильтрПоле wait_seconds: PDF решается за доли секунды прямо в ответе подачи
Сделки не должны вставать, если мы недоступныРезервный блок из пакета подключения: принимает чек в вашу систему и досылает нам позже

Быстрый старт

Три запроса в песочницу: подать чек, забрать вердикт, сообщить итог ордера. Язык примеров переключается над блоком кода - выбор запоминается на всей странице.

# 1. Подать чек (файлом)
curl -s https://chekvalidator.com/sandbox/v1/receipts:validate \
  -H "Authorization: Bearer sandbox-demo-key" \
  -F "file=@check.jpg" \
  -F "request_id=ORDER-1001" \
  -F "expected_amount=1500.00" \
  -F "requisite=79001234567" \
  -F "initiated_at=2026-08-23T10:15:00"

# Ответ: {"job_id":"...","status":"pending","eta_seconds":3.5,"status_url":"...",...}

# 2. Забрать результат (через пару секунд)
curl -s https://chekvalidator.com/sandbox/v1/receipts/<job_id> \
  -H "Authorization: Bearer sandbox-demo-key"

# Ответ: {"status":"done","verdict":"accepted","status_color":"green",...}

# 3. Сообщить итог ордера
curl -s https://chekvalidator.com/sandbox/v1/receipts/<job_id>/feedback \
  -H "Authorization: Bearer sandbox-demo-key" \
  -H "Content-Type: application/json" \
  -d '{"order_outcome":"approved","comment":"деньги пришли"}'
Попробовать прямо здесь Страница подаст в песочницу учебный файл с полной заявкой и дождётся вердикта. Вердикт песочницы выбирается по имени файла.
Результат появится здесь.

Доступ и ключи

Ключ передаётся любым из двух заголовков; если пришли оба, читается X-API-Key:

Authorization: Bearer ВАШ_КЛЮЧ
# или
X-API-Key: ВАШ_КЛЮЧ

Подача чека

POST/v1/receipts:validate

Отвечает сразу 202: задача создана, проверка идёт в фоне. Тот же 202 приходит и при отказе приёма - тогда в теле "status": "done", "verdict": "rejected" и код причины. Решение принимайте по телу, а не по коду HTTP.

Файлом (multipart/form-data)

Файл - в поле file, остальные поля - строками рядом.

curl -s https://chekvalidator.com/sandbox/v1/receipts:validate \
  -H "Authorization: Bearer sandbox-demo-key" \
  -F "file=@check.jpg" \
  -F "request_id=ORDER-1001" \
  -F "expected_amount=1500.00" \
  -F "requisite=79001234567" \
  -F "initiated_at=2026-08-23T10:15:00" \
  -F "partner_meta={\"order\":1001}"

Ссылкой (application/json)

Чек лежит в вашем хранилище - передайте временную ссылку, файл заберём сами.

curl -s https://chekvalidator.com/sandbox/v1/receipts:validate \
  -H "Authorization: Bearer sandbox-demo-key" \
  -H "Content-Type: application/json" \
  -d '{
    "file_url": "https://storage.example.com/tmp/check.jpg?sig=...",
    "request_id": "ORDER-1001",
    "expected_amount": "1500.00",
    "requisite": "79001234567",
    "initiated_at": "2026-08-23T10:15:00"
  }'
Ссылки принимаются строго Только https, домен из списка, согласованного при подключении, внутренние сети и редиректы запрещены. Пока домен не согласован, приём по ссылке выключен: FETCH_DISABLED. Остальные отказы - в кодах приёма. Песочница по ссылке файл не скачивает, а строит ответ по имени файла в ней.

Поля заявки

ПолеОбязательноеЧто это
file / file_urlдачек: PDF, JPEG, PNG, WebP, GIF или HEIC. Список можно сузить в кабинете, лишний формат получит FORMAT_NOT_ALLOWED
expected_amountдаожидаемая сумма строкой: "1500.00" или "1500,00"
requisiteдареквизит получателя, выданный плательщику: карта, счёт или телефон, как есть
initiated_atдакогда создана заявка, ISO 8601; без смещения - время сервиса
request_idнастоятельноID заявки у вас: едет во все ответы и вебхуки, включает защиту от дублей
wait_secondsнетждать вердикт в ответе подачи, 0-25 секунд. Не успели - обычный pending
currencyнетвалюта заявки
bankнетбанк, если известен заранее
file_nameнетимя для журналов, до 80 символов
subsystemнеткакая ваша система подаёт чек, см. подсистемы
partner_metaнетваше сквозное поле до 4096 символов: вернётся как есть в ответах и вебхуках. Считайте его недоверенным вводом

Без любого из трёх обязательных полей подача отклоняется кодом CONTEXT_FIELDS_MISSING - и в бою, и в песочнице.

Ответ подачи

{
  "request_id": "ORDER-1001",
  "job_id": "3f8a1c2e-...",
  "status": "pending",
  "comment": "Чек принят, идёт проверка",
  "eta_seconds": 3.5,
  "status_url":  "https://.../v1/receipts/3f8a1c2e-...",
  "receipt_url": "https://.../v1/receipts/3f8a1c2e-.../file",
  "share_url":   "https://.../r/<токен>"
}

eta_seconds - через сколько ждать вердикт, status_url - где его забирать, receipt_url - файл чека по ключу, share_url - карточка проверки без ключа. Отказы по самому файлу при подаче файлом (UNSUPPORTED_FORMAT, FILE_TOO_LARGE, IMAGE_TOO_LARGE, CONTENT_TYPE_MISMATCH) приходят не здесь, а вердиктом задачи.

Ссылки загрузки

POST/v1/upload-links

Заявка, по которой чек прикладывает сам плательщик. Поля заявки те же и так же обязательны; ttl_minutes - срок жизни ссылки, по умолчанию час, не больше суток.

curl -s https://chekvalidator.com/sandbox/v1/upload-links \
  -H "Authorization: Bearer sandbox-demo-key" \
  -H "Content-Type: application/json" \
  -d '{
    "request_id": "ORDER-1002",
    "expected_amount": "900.00",
    "requisite": "79007654321",
    "initiated_at": "2026-08-23T12:00:00",
    "ttl_minutes": 60
  }'

# Ответ 201:
{
  "token": "kZ2r...",                                # непрозрачная строка, на формат не опирайтесь
  "upload_url":    "https://.../u/kZ2r...",          # страница загрузки для плательщика
  "embed_url":     "https://.../u/kZ2r...?embed=1",  # та же страница в iframe на вашем сайте
  "expires_at":    "2026-08-23T13:00:00",            # до этого момента ссылка ждёт чек
  "max_attempts":  3,                                # попыток загрузки на одну ссылку
  "email_address": "order-1002.a1b2c3@...",          # чек можно прислать письмом; null - канал выключен
  "status_url":    "https://.../v1/upload-links/kZ2r...",
  "receipt_url":   "https://.../v1/upload-links/kZ2r.../file"
}

Попытки кончились (max_attempts) - выпускайте новую ссылку.

GET/v1/upload-links/{token}

Состояние заявки. status: pending - ссылка ждёт чек, done - проверка закончена, expired - срок вышел без чека, not_found - ссылки нет. Рядом: file_received, uploaded_at, attempts, expires_at, job_id, verdict, checking, eta_seconds, resend_deadline, resend_left_seconds и адреса status_url, receipt_url, share_url.

GET/v1/upload-links/{token}/file

Чек по адресу заявки: 202 и waiting, пока чека нет, 202 и processing, пока идёт проверка, 410 - срок вышел без чека; дальше как у файла чека.

Повторные подачи

Повтор той же подачи с тем же request_id не создаёт новую задачу: вернётся та же job_id с "repeated": true и тем же 202 - ретраи по обрыву сети безопасны. Память о заявке держится сутки. Без request_id защиты от дублей нет.

{"request_id":"ORDER-1001","job_id":"3f8a1c2e-...","status":"done",
 "repeated":true,"verdict":"accepted",...}

Результат проверки

GET/v1/receipts/{job_id}

Ответ всегда 200, разбирайте по полю status: processing - ждите, done - готово, not_found - задачи нет, она чужая или старше суток. Результат доступен сутки, файл - столько, сколько выбрано в настройке хранения.

{
  "job_id": "3f8a1c2e-...",
  "request_id": "ORDER-1001",
  "status": "done",
  "status_key": "chist",
  "status_text": "Чист",
  "status_action": "Проводить платёж.",
  "status_explain": "Чек прошёл проверку: подделки не нашли, данные сошлись с заявкой.",
  "status_hex": "#1e8e5a",
  "warning": null,
  "file_delivery": "передаём",
  "file_delivery_reason": "",
  "verdict": "accepted",
  "reason_code": null,
  "status_color": "green",
  "comment": "Признаков подделки не найдено",
  "points": [],
  "mismatches": [],
  "extracted": {
    "amount": "1500.00",
    "payment_time": "2026-08-23T10:17:41",
    "bank": "...",
    "transfer_type": "..."
  },
  "file_available": true,
  "file_cropped": false,
  "partner_meta": "{\"order\":1001}"
}
ПолеЧто это
status_keyГлавное поле: один статус - одно действие, см. статусы
status_text, status_action, status_explainстатус словом, что делать и что именно не так - готовые фразы для человека
warningпредупреждение одной строкой; null только у чистого статуса
status_hexцвет статуса для интерфейса, показывайте вместе со словом
file_delivery, file_delivery_reasonпередаём ли файл чека: передаём | передаём обрезанный | не передаём, и почему
verdict, status_color, reason_codeпрежняя форма ответа, работает как раньше, см. таблицу соответствия
mismatchesчто разошлось с заявкой, словами; непуст при status_color: yellow
comment, pointsпояснение и пункты разбора для оператора; состав points не фиксирован
surveyкороткая анкета, только при not_confirmed; ответ - POST /v1/receipts/{job_id}/survey, необязателен
file_available, file_croppedотдадим ли файл по receipt_url; вырезан ли чек из кадра
extractedчто распознали: сумма, время оплаты, банк, вид перевода. Приходит, если что-то извлечено
partner_metaваше сквозное поле, как прислали

Остальные служебные поля (например, authenticity) могут меняться - решение принимайте по полям выше.

Отказ приёма выглядит иначе Если не прошли файл или поля заявки, приходят verdict: "rejected", reason_code, stage: "intake" и detail, но status_key равен prishlite_zanovo: чек мы не смотрели, беда в файле или запросе. Показывать это плательщику как подделку нельзя.

Статусы и коды причин

Разбирайте ответ по status_key: он есть у каждой завершённой проверки, и у каждого значения ровно одно действие.

СтатусЧто значитЧто делать
chist «Чист»чек настоящий, данные сошлись с заявкойпроводить платёж
rashozhdenie «Расхождение»чек выглядит настоящим, но разошёлся с заявкой; что именно - в status_explain и mismatchesне проводить автоматом, посмотреть руками
povtor «Повтор»файл уже предъявлялся по другой заявкене проводить; если та заявка сорвалась - сообщите итогом ордера, блокировка снимется
ne_podtverzhdyon «Не подтверждён»подтвердить нечем: банк нам незнаком или проверка не завершилась по нашей причине. Признаков подделки нет, файл передаёмрешать вам; при незнакомом банке в ответе анкета survey
prishlite_zanovo «Пришлите заново»файл не читается, чека в нём не видно, или он не прошёл приёмпопросить новый чек; попытка не тратится
otkaz «Отказ»доказанная подделка или грубое нарушениене проводить платёж

Если заключения нет вовсе, приходит neyasno.

Прежняя форма: verdict и status_color

Код, написанный по старым полям, работает как раньше. В прежней форме пять вердиктов:

ВердиктЦветЧто делатьФайл чека
acceptedgreen - сошлось; yellow - подделки нет, но данные разошлись с заявкой (mismatches)green - проводить; yellow - решение за вами, обычно ручная проверкаесть
resend_requestedresendпопросить новый чек, comment можно показать плательщику как есть; это не отказнет, 409
rejectedredпо вашему регламенту подозрительных операций; при отказе приёма код из таблицы приёманет, 409
not_confirmedunconfirmedбанк нам незнаком, подделки не нашли - решение за вамиесть
unverifiedgrayзаключения нет по нашей технической причине - сделка стоять не должнаобычно есть, см. file_available
Частые ошибки Жёлтый accepted принимают за зелёный и пропускают расхождение (у него status_key = rashozhdenie). resend_requested показывают плательщику как отказ. Ветку unverified не пишут вовсе - и сделка встаёт из-за нашего сбоя.

Коды приёма файла

Приходят с verdict: rejected и status_key: prishlite_zanovo.

reason_codeЧто случилосьЧто делать
EMPTY_FILEфайл не приложен или пустпроверьте поле file
FILE_TOO_LARGEфайл больше лимитапросите чек из приложения банка, а не фото экрана
IMAGE_TOO_LARGEкартинка больше допустимого в пикселяхто же
UNSUPPORTED_FORMATформат или тип тела не поддерживаетсяmultipart/form-data или application/json; PDF, JPEG, PNG, WebP, GIF, HEIC
FORMAT_NOT_ALLOWEDформат отключён в вашем кабинетепричина словами - в detail, её можно показать плательщику
CONTENT_TYPE_MISMATCHзаявленный тип не совпал с содержимымне подставляйте тип вручную
CONTEXT_FIELDS_MISSINGнет expected_amount, requisite или initiated_atпередавайте все три
CONTEXT_FIELDS_INVALIDсумма или дата не разбираютсясумма - десятичная строка, дата - ISO 8601
URL_INVALIDнет file_url или в нём не разобрать хостпроверьте ссылку
URL_SCHEME_NOT_ALLOWEDссылка не по httpsтолько https
DOMAIN_NOT_ALLOWEDдомен не из согласованного спискасогласуйте домен хранилища
DNS_RESOLUTION_FAILEDдомен ссылки не резолвитсяпроверьте доступность хранилища снаружи
URL_RESOLVES_TO_INTERNAL_IPссылка ведёт во внутреннюю сетьнужно публичное хранилище
FETCH_DISABLEDприём по ссылке не включёнподавайте файлом или попросите включить
FETCH_FAILEDхранилище не отдало файлповторите, когда хранилище ответит

Коды «нужен новый чек»

Приходят с verdict: resend_requested; comment готов для плательщика.

reason_codeЧто случилось
NOT_A_RECEIPTфайл читается, но это не чек
LOW_EXTRACTION_CONFIDENCEчек не читается
AMOUNT_NOT_FOUNDсумма в чеке не распозналась
FOREIGN_BACKGROUNDв кадре обстановка вокруг чека, сам чек не выделить
FOREIGN_INTERFACE_VISIBLEв кадре постороннее приложение

Коды наших технических обстоятельств

reason_codeЧто случилосьЧто делать
QUEUE_FULLчек не взят, ответ 503 сразуповторите после паузы из Retry-After
PIPELINE_ERRORпроверка упала из-за нашего сбояподайте чек ещё раз
CHECK_UNAVAILABLEзаключения нет, чек передан (unverified)решайте по регламенту, файл доступен
CHECK_STALLEDпроверка затянулась и закрытато же
CHECK_INTERRUPTEDперезапуск сервиса оборвал проверкуто же

Коды признаков подделки при rejected приходят, но открыто не расшифровываются: открытый список проверок был бы инструкцией для изготовителей подделок. Справочник входит в пакет подключения.

Файл чека

GET/v1/receipts/{job_id}/file

Файл по ключу API. Пока проверка идёт - 202 и processing; если она затянулась, файл может прийти раньше вердикта с заголовком X-Validator-Verdict: pending. Файла не будет (нужен новый чек, отказ, снят с хранения) - 409 с вердиктом и кодом; чужая задача - 404.

DELETE/v1/receipts/{job_id}/file

Снять чек с хранения досрочно. Ответ: {"job_id": "...", "stored": false, "deleted": true}.

Карточка без ключа - share_url вида /r/<токен>: в браузере это статус, заключение и сам чек, программе по тому же адресу приходит файл. Удобно для карточки операции в вашей админке. Ссылка равноценна документу: храните как секрет и не отдавайте плательщику. Живёт, пока чек на хранении. По настройке файл отдаётся очищенным от служебных полей (EXIF, GPS, метаданные PDF).

Вебхуки

Вердикт приходит сам на ваш адрес. Адрес задаётся в кабинете партнёра (только https и публичный адрес), секрет подписи выдаётся при подключении и меняется в кабинете.

СобытиеКогда
receipt.acceptedфайл принят, проверка пошла - переводите сделку в ожидание
receipt.verdictпроверка закончена: status_key, status_text, status_action, warning, file_delivery и прежние verdict, status_color, reason_code, comment, points, file_available. Расхождения и распознанное - по status_url
receipt.delayedпроверка затянулась; доступен ли уже файл - в file_available, вердикт придёт отдельно
receipt.lateтолько для подсистем, которые не ждут: пригодный чек пришёл после финала
# тело события: имя дублируется полем event и заголовком X-Validator-Event
{
  "event": "receipt.verdict",
  "job_id": "3f8a1c2e-...",
  "request_id": "ORDER-1001",
  "status": "done",
  "verdict": "accepted",
  "status_color": "green",
  "reason_code": null,
  "comment": "Признаков подделки не найдено",
  "points": [],
  "file_available": true,
  "status_url":  "https://.../v1/receipts/3f8a1c2e-...",
  "receipt_url": "https://.../v1/receipts/3f8a1c2e-.../file",
  "share_url":   "https://.../r/<токен>"
}
# у receipt.accepted вместо вердикта - "status": "pending" и comment;
# partner_meta едет в каждом событии, если вы его прислали

Подпись - проверять обязательно

Заголовок X-Validator-Signature - HMAC-SHA256 от сырого тела, ключ - ваш секрет, шестнадцатеричная строка в нижнем регистре. Считайте подпись до разбора JSON: пересобранное тело даёт другие байты. Нет заголовка или не сошлась - событие чужое.

# Python: проверка подписи
import hmac, hashlib

def подпись_верна(тело: bytes, заголовок: str, секрет: str) -> bool:
    ожидаемая = hmac.new(секрет.encode(), тело, hashlib.sha256).hexdigest()
    return hmac.compare_digest(ожидаемая, заголовок)

Доставка

Приёмник по шагам

  1. Прочитать сырое тело байтами и проверить подпись.
  2. X-Validator-Event-Id уже видели - ответить 2xx и выйти.
  3. Разобрать тело: event, job_id, request_id, partner_meta.
  4. Записать событие и сразу ответить 2xx.
  5. В фоне применить вердикт к сделке.

Итог ордера

POST/v1/receipts/{job_id}/feedback

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

{"order_outcome": "approved", "comment": "деньги поступили"}
# order_outcome: approved | declined; comment - до 1000 символов, лишнее обрезаем

# Ответ: {"job_id": "...", "feedback": "recorded", "order_outcome": "approved"}
# 422 - order_outcome не approved и не declined
# 404 - по этой задаче у нас нет записанного решения

Ошибки HTTP

HTTPКогда
200статус задачи и состояние ссылки загрузки - разбирайте по status, включая not_found
201ссылка загрузки создана
202чек принят, проверка идёт; тот же код у отказа приёма - смотрите тело
401нет ключа или ключ неверен
403IP не в списке разрешённых (проверяется раньше ключа)
404файл или решение не найдены, в том числе чужая задача
409файла не будет: нужен новый чек, отказ или чек снят с хранения; в теле verdict и reason_code
410срок ссылки загрузки вышел без чека
413запрос заведомо больше лимита
422тело не по контракту: неверный order_outcome или неразбираемое тело ссылки загрузки
429слишком много обращений к несуществующим ссылкам с одного адреса
503временно не принимаем: "status": "busy", "reason_code": "QUEUE_FULL" и заголовок Retry-After

Формы тела ошибки: {"detail": "..."} у 401 и 403; {"error": "..."} у 422 и 404 итога ордера; обычный ответ подачи с verdict, reason_code, stage и detail у отказов приёма.

Служебные адреса и схема

АдресЧто отвечает
GET /health{"status":"ok"} - сервис жив; ключ не нужен
GET /readiness{"status":"ready"} - принимает запросы; ключ не нужен. Не готов - 503 и причина в detail

Машинная схема всех маршрутов - openapi.yaml: её понимают Postman, Insomnia и генераторы клиентов. Собирается из кода, поэтому не расходится с сервисом. Та же схема в виде страницы Swagger с запросами в песочницу.

Подсистемы

Если за одним ключом стоят разные ваши системы (касса, бот, ручной разбор) и они по-разному умеют ждать, заведите их в кабинете («Интеграция» → «Подсистемы») и присылайте идентификатор полем subsystem - при подаче и при создании ссылки загрузки.

Три срока - не перепутайте

СрокПро чтоКто задаёт
Срок оплаты ордераденьги: оплата позже срока - «Расхождение», не отказвы, на подключении или подсистеме
Окно повторной загрузкифайл: сколько плательщик может слать новый снимокмы, по умолчанию 10 минут
Предел ожидания финалавебхук: сколько ваша система ждёт окончательного ответавы, на подсистеме

Песочница

https://chekvalidator.com/sandbox - открытый двойник API для отладки: те же адреса, поля и строгость приёма, но подлинность не проверяется - вердикт выбирается по имени файла. Попробовать мышкой - в быстром старте.

Имя файла содержитВердиктreason_code
fakerejectedSANDBOX_MARKED_FAKE
resendresend_requestedSANDBOX_UNREADABLE
что угодно ещёacceptednull
# сценарий «подделка»: подаём файл, вердикт забираем по status_url через ~4 секунды
curl -s https://chekvalidator.com/sandbox/v1/receipts:validate \
  -H "Authorization: Bearer sandbox-demo-key" \
  -F "file=@fake-check.jpg;filename=fake-check.jpg" \
  -F "request_id=TEST-FAKE-1" \
  -F "expected_amount=1500.00" \
  -F "requisite=79001234567" \
  -F "initiated_at=2026-09-01T10:15:00"

Переход в бой

В коде меняются две настройки - адрес и ключ. Приём одинаковый, различия осознанные:

ЧтоПесочницаБой
Адрес и ключhttps://chekvalidator.com/sandbox, любой ключ от 8 символоввыдаются при подключении; может быть закреплён список IP
Поля заявкиобязательны так же, как в бою: CONTEXT_FIELDS_MISSING, CONTEXT_FIELDS_INVALIDобязательны все три
Вердиктпо имени файла, коды SANDBOX_*настоящая проверка
wait_secondsдо 25 секунд, только для PDFтак же; фото сразу получает pending
Проверка файлатолько размерплюс пиксели, тип содержимого и форматы подключения
Подача ссылкойфайл не скачиваетсяскачивается, со всеми ограничениями ссылок
Вебхукиcallback_url в подаче, общий секрет - подпись ничего не доказываетадрес в кабинете, ваш секрет, проверка обязательна
Ссылки загрузкисрок и попытки как в бою, письмом - нетплюс приём письмом, если канал настроен
Хранениеоколо часа в памятифайл шифруется, срок - ваша настройка
Проверка одной командой В боевой конфигурации не должно быть ни слова sandbox. Заголовок X-Sandbox на боевом ключе значит, что запрос ушёл не туда: такую задачу не проводите.

Чек-лист перед выкатом

  1. В каждой подаче есть expected_amount, requisite, initiated_at и request_id; повтор с "repeated": true не плодит дублей.
  2. На каждый status_key есть ветка; жёлтый accepted не считается зелёным; «Пришлите заново» плательщик видит как просьбу, а не отказ.
  3. Вебхуки: адрес в кабинете, секрет в секретах, подпись по сырому телу, повтор события безопасен, ответ быстрый.
  4. Подача ссылкой - домен хранилища согласован; путь плательщика - решено, где показываете upload_url.
  5. IP согласованы, срок хранения выбран, ключ в секретах и меняется без выката.
  6. Наша недоступность не останавливает сделки: таймауты и повторы настроены.
  7. Итог ордера уходит автоматически. В день перехода - один настоящий чек, вердикт пришёл и по status_url, и вебхуком с верной подписью.

Безопасность и данные

Изменения API

Изменения обратно совместимы: поля и значения только добавляются, старые сохраняют смысл.

ДатаЧто изменилось
01.09.2026Главный статус ответа: status_key, status_text, status_action, warning, file_delivery. Вердикт not_confirmed и анкета survey. Поле subsystem и событие receipt.late. Песочница требует поля заявки так же, как бой
29.08.2026Выбор принимаемых форматов в кабинете и код FORMAT_NOT_ALLOWED; HEIC принимается и переводится в JPEG
06.08.2026Событие receipt.delayed, заголовок X-Validator-Verdict: pending, вердикт unverified