Коротко
invoice_not_found (HTTP 404) означает не «счёта нет», а «этому ключу такой счёт не виден». Обычно счёт на месте, но вы запрашиваете его другим ключом, в другом режиме или из другой организации. Порядок проверки: идентификатор → режим (qp_test_ / qp_live_) → привязка ключа к кассиру → организация.
Симптом → причина → решение
| Симптом | Причина | Решение |
|---|---|---|
| Только что созданный счёт не находится | Взяли не поле id из ответа | Используйте поле id из ответа POST /invoices |
| В кабинете счёт виден, через API — нет | Счёт создан в песочнице, запрос идёт боевым ключом | Приведите ключ в соответствие режиму |
| Вчера работало, сегодня 404 | Ключ заменили, новый привязан к другому кассиру | Посмотрите привязку ключа в кабинете |
| Один сервис счёт видит, другой нет | У сервисов разные ключи, один из них привязан | Дайте общий ключ или снимите привязку |
Поиск по externalOrderId ничего не даёт | Искали как по id | Фильтруйте через список счетов |
Порядок проверки
1. Верный ли идентификатор
Счёт запрашивается по полю id из ответа POST /api/v1/invoices. Частые путаницы:
- Перепутали
externalOrderIdиid.externalOrderId— ваш собственный номер заказа, он возвращается в вебхуке, ноGET /invoices/{id}его не принимает. - Лишний пробел или перевод строки. И в ключе, и в идентификаторе хвостовой
\nиз переменной окружения не видно глазами. - Идентификатор из другой среды. Скопировали из тестов в продакшен.
Если нужно искать по номеру заказа, используйте список GET /api/v1/invoices. Подробнее: Metadata и номер заказа.
2. Совпадает ли режим
Песочница и боевой режим — два отдельных мира. Счёт, созданный ключом qp_test_…, ключу qp_live_… не виден вообще, и наоборот.
Самый частый сценарий: разработчик потестировал в песочнице, перешёл в боевой режим, а старые тестовые идентификаторы остались в коде или в тестах. Результат — чистый 404.
Проверка: посмотрите на префикс ключа, который сейчас используется. qp_test_ — песочница, qp_live_ — боевой режим. Разница описана здесь: Чем песочница отличается от боевого режима.
3. Привязан ли ключ к кассиру
Ключ можно привязать к конкретному кассиру. Боевые счета привязанного ключа идут только через этого кассира, и чужие счета такой ключ не видит — на запрос возвращается 404.
Это не ошибка, а задуманное поведение: чтобы две точки или два подразделения не видели счета друг друга.
Когда встречается:
- В организации несколько кассиров, счета создаются разными ключами
- Ключ привязали позже, а старые счета принадлежат другому кассиру
- Сервис отчётности работает привязанным ключом и ожидает увидеть всё
Решение: выдайте отчётности отдельный непривязанный ключ либо дайте каждому сервису ключ своего кассира. Подробнее: Привязка API-ключа к кассиру.
4. Та ли организация
Если в аккаунте несколько организаций, у каждой свои ключи. Запрос чужого счёта вернёт 404 или forbidden — счёт существует, но он не ваш.
Проверка: посмотрите в кабинете, в какой организации создан ключ. Подробнее: Несколько организаций в одном аккаунте.
Диагностика за минуту
Запросите список тем же самым ключом:
GET /api/v1/invoices
X-API-Key: <тот же самый ключ>
| Результат | Вывод |
|---|---|
| Список пустой | Не тот режим или ключ вообще из другой организации |
| Счета есть, но нужного нет | Ключ привязан к другому кассиру либо идентификатор неверный |
| Нужный счёт в списке есть | Идентификатор скопирован неправильно |
| Пришёл 401 | Проблема в ключе, а не в счёте: API отвечает 401 |
Чего делать не стоит
- Не повторяйте запрос циклом. 404 — не временный сбой, повтор не поможет и может привести к
too_many_attempts. - Не создавайте новый счёт вслепую. Если старый успеют оплатить, покупатель заплатит дважды. Сначала найдите его в кабинете.
- Не удаляйте ключ. Проблему это не решит, а работающие интеграции сломает.
Вопросы и ответы
Мог ли счёт удалиться? Нет. Счета не удаляются, они меняют статус: cancelled, expired. Такой счёт по-прежнему открывается через GET.
В кабинете счёт вижу, API не находит. Как так? В кабинете вы видите всю организацию, а привязанный ключ — только счета своего кассира. Это самая частая причина.
Можно ли задавать идентификатор самому? Нет, id выдаём мы и изменить его нельзя. Для своего номера есть externalOrderId.
Подойдёт ли id из вебхука? Да, invoice.id в вебхуке — тот же самый идентификатор. Если по нему приходит 404, значит не совпадает режим или ключ.
Можно ли перенести счета из песочницы в боевой режим? Нет. Данные песочницы в боевой режим не переходят, это разные среды. После перехода вы создаёте новые счета.