Первое правило диагностики: ветвитесь по коду ошибки (
error.code), а не по тексту. Полный
список кодов с расшифровкой и что делать — Справочник кодов ошибок.Быстрая навигация по симптому
Сначала — 5 быстрых проверок
Прежде чем углубляться, проверьте базовое (это закрывает большинство проблем на старте):- Ключи вставлены без пробелов по краям (частая причина
401). - Секрет — это секрет, а не public_id (их легко перепутать местами).
- Сумма — строкой (
"10.00"), а не числом. - Сайт доступен из интернета (для вебхуков —
localhostне подойдёт). - Вы на боевом URL API, а не на плейсхолдере из документации.
Ошибки аутентификации (401/403)
Симптом: любой запрос отдаёт401.
Проверьте по порядку:
X-Public-Idиsecret. Скопируйте заново, без пробелов. Секрет — тот, что подписывает, а неpublic_id.- Строка для подписи. Подписывается ровно
"{timestamp}\n{METHOD}\n{path}\n{body}", аX-Signature = hex(HMAC‑SHA256(secret, строка)). Тело подписи должно побайтно совпадать с отправляемым телом — не пересериализуйте JSON после подписи. Разбор — Как подписать запрос. - Часы сервера.
timestamp— в unix‑секундах, окно ±5 минут. Разъехались часы → синхронизируйте NTP. Симптом окна — кодmerchant.bad_signature(а неauth.bad_timestamp). merchant.wrong_key_kind(403) — ключ не подходит для этого эндпоинта. Второго ключа искать не надо: в Oblodai один API‑ключ на всё — и приём, и выплаты (раздельных ключей «для приёма» и «для выплат» не существует). На практике этот код означает, что вы предъявляете легаси‑ключ старого формата (pk_…/wk_…). Выпустите в кабинете актуальный ключoblodai_…и используйте его везде. → Регистрация и ключи401 auth.ip_not_allowed— включён IP‑allowlist, а запрос идёт с адреса вне списка. Добавьте IP или временно выключите контроль.
Превышен лимит частоты (429)
Симптом:429 с телом {"state":1,"message":"rate limit exceeded"}.
- Лимит считается на IP (по умолчанию 120 запросов/мин). Подробнее — Ограничение частоты.
-
Что делать: прочитать заголовок
Retry-After(секунды), подождать и повторить (повтор безопасен благодаря идемпотентности: тот жеIdempotency-Key+ тот жеorder_id). SDK делают это сами. -
Как не упираться:
- Массовые операции отправляйте батчем —
/v1/payment/batch,/v1/refund/batch,/v1/payout/batch: до 5000 операций одним запросом вместо 5000 запросов. Это штатный способ вообще не встречаться с429. → Массовые операции - Не поллите
/payment/info— статус придёт вебхуком. - Кэшируйте
services/currencies/курсы.
- Массовые операции отправляйте батчем —
Платёж: создался, но address пустой
Это нормально для валюто‑агностичного счёта (is_multi: true): валюту и сеть выбирает покупатель
на hosted‑странице, и адрес выделяется в момент выбора.
- Хотите адрес сразу — задайте
to_currencyиnetworkпри создании (одновалютный режим). Разбор режимов — Три режима создания счёта.
Платёж не создаётся
Диагностика: платёж «застрял»
Симптом: покупатель говорит, что оплатил, а статус заказа не сталpaid.
Идите по шагам:
- Запросите факт. Вызовите
/v1/payment/infoпоuuid/order_idи посмотритеpayment_status:check/select— оплаты ещё не видели на блокчейне. Ждём или платёж не отправлен.confirm_check— транзакцию видим, ждём подтверждений сети (это нормально, подождите).wrong_amount_waiting— пришла недоплата, покупатель может докинуть остаток (см. Недоплата/переплата).paid/paid_over— оплата прошла. Значит проблема на вашей стороне: не пришёл/не обработался вебхук → см. следующий раздел.wrong_amount— недоплата, срок вышел.cancel— счёт истёк/отменён.
- Если
paid, а заказ не обновился — проблема в доставке/обработке вебхука. Проверьте журнал доставок и раздел ниже. - Разовая ручная синхронизация: можно переотправить вебхук или
обновить заказ по результату
/payment/infoвручную.
Диагностика: вебхук не приходит
Симптом: оплата в статусеpaid, но уведомление на ваш сервер не пришло.
Пройдите по цепочке — уведомление рвётся в одном из звеньев:
- Endpoint зарегистрирован? Oblodai шлёт вебхуки только если вы вызвали
POST /v1/webhooksи получилиsecret. Без регистрации доставок нет вовсе — даже per‑объектныйurl_callbackигнорируется (без секрета endpoint подписывать нечем, доставка не создаётся). (Модули CMS делают это автоматически при сохранении настроек.) - URL доступен снаружи? Адрес должен открываться из интернета (не
localhost, не за VPN, не за Basic‑Auth). Проверьте, что на вашurl_callbackможно сделатьPOSTизвне. - Ваш сервер отвечает
2xx? Если обработчик возвращает не‑2xx (или падает) — Oblodai считает доставку неуспешной и будет повторять (до 12 попыток, ~3,5 часа), затем статусdead. - Смотрите журнал доставок:
POST /v1/webhooks/deliveries— там видноstatus(pending/delivered/dead), число попыток и текст последней ошибки. Учтите: журнал хранит только 50 последних доставок и не имеет фильтров (тело запроса — пустой{}) — на бойком магазине нужная запись могла выпасть из окна, и её отсутствие не означает, что вебхук не отправлялся. В этом случае сверьте статус платежа через/v1/payment/infoи при необходимости переотправьте вебхук. - Проверьте вручную: тестовый вебхук отправит событие на ваш URL — так можно отделить «Oblodai не шлёт» от «мой сервер не принимает».
Вебхук приходит, но подпись не сходится
Частые причины (по убыванию частоты):- Проверяете не тем секретом. Вебхуки подписываются секретом из
POST /v1/webhooks, а не вашим API‑секретом. - Не сырое тело. Подпись считается по сырым байтам запроса. Если фреймворк распарсил JSON, а вы
пересобрали его в строку — подпись не сойдётся. Берите
php://input/express.raw/request.get_data(). - Другой алгоритм. Подпись вебхука — это
hex(HMAC‑SHA256(secret, "{timestamp}." + сырое_тело))по заголовкамX-Webhook-Timestamp/X-Webhook-Signature. Это не тот же алгоритм, что у подписи запроса. Формат — Объект вебхука. - Пробный вебхук. События с
"is_test": trueне подписаны — их не нужно проверять, просто отвечайте200.
Выплаты не проходят
Полный список — Справочник кодов ошибок, раздел
payout.
Модули CMS: заказ не меняет статус
- Убедитесь, что способ оплаты включён и виден на оформлении заказа.
- Сохраните настройки способа оплаты ещё раз — так модуль перерегистрирует вебхук.
- Сайт должен быть доступен из интернета (иначе вебхуки не дойдут).
- Проверьте, что Public ID и API secret вставлены без пробелов.
Таймауты и недоступность API
Сеть моргнула, запрос завис или пришёл5xx/503 — это ожидаемая ситуация, к ней надо быть готовым.
- Таймаут ≠ «не прошло». Ответ мог потеряться уже после того, как операция выполнилась на сервере.
Поэтому не создавайте вторую операцию вслепую — повторите тот же запрос: с тем же
HTTP‑заголовком
Idempotency-Keyи тем жеorder_id. Идемпотентность вернёт уже созданный объект (с заголовкомIdempotent-Replayed: true), а не сделает дубль. 5xx/503— временная недоступность зависимости (например, оракула курсов). Повторяйте с экспоненциальным backoff (0.5с → 1с → 2с …), а не в плотном цикле.409 idempotency.in_progress— не ошибка: ваш предыдущий запрос с этимIdempotency-Keyещё выполняется. Подождите и повторите — получите его результат.- Что повторять безопасно: запросы с
Idempotency-Keyи/илиorder_id/reference(создание платежа, выплаты, возврата) — идемпотентны. Чтения (info,balance,services) безопасны всегда. - Готовый рецепт клиента (таймауты, ретраи, backoff, идемпотентность) — Устойчивый клиент. Все SDK реализуют это из коробки.
Не нашли решение?
- Быстрые вопросы‑ответы — FAQ.
- Все коды ошибок и что делать — Справочник кодов ошибок.
- Как это устроено «под капотом» — Диаграммы жизненных циклов.
- Незнакомый термин — Глоссарий.
- Ничего не помогло — создайте тикет в поддержку в кабинете my.oblodai.com
(раздел «Поддержка»). Приложите ваш
public_id,uuidплатежа/выплаты и строки лога с префиксомoblodai:(в SDK включаются переменнойOBLODAI_LOG, в модулях CMS — галочкой Debug log);secretне прикладывайте.