Skip to content

Статусы, неопределённость и поздние платежи ​

Эта страница — про то, как читать состояние счёта, когда считать заказ оплаченным и что делать при неопределённости, таймауте и позднем платеже.

Чтение: GET /v1/cashier/invoices/{reference} ​

Возможность ключа: payment.read. Неизвестная, некорректная и чужая ссылка дают одинаковый 404 invoice_not_found — без раскрытия, какая это ссылка. Ответ — тот же объект, что и при создании (поля).

bash
curl "$ELEVENPAY_BASE_URL/v1/cashier/invoices/ep1_7t4k2m8q9x3v6b1n5c0d2f4a8h" \
  -H "Authorization: Bearer $ELEVENPAY_API_KEY"

Состояния ​

Поле status — состояние платежа (общий список значений: pending, processing, succeeded, cancelled, failed, outcome_unknown). Для счетов Cashier сегодня достижимы только pending → succeeded; остальные значения общей модели для счетов не гарантируются (контракт отказа/истечения не определён — UNKNOWN). Ваш код обязан терпимо относиться к неожиданному значению: не считать его оплатой.

Поле invoice_state — где находится сам счёт:

invoice_stateЗначениеЧто делать
queuedсчёт поставлен в очередь, ещё не отправленпоказывайте «отправляем запрос…»
sendingотправка идётто же
sentзапрос дошёл до плательщикаесли payer_action задан — «подтвердите платёж в приложении»
not_sentзапрос не отправлен (однозначно, платежа нет)сообщите плательщику; новая попытка — новым заказом по вашему решению
unknownнеопределённый исход: счёт мог быть, а мог не быть созданне создавайте второй счёт для этого заказа; ждите вебхук, сверяйтесь GET, обратитесь в поддержку при затягивании

unknown никогда не повторяется автоматически: повторная отправка могла бы задвоить счёт для плательщика. Это сознательное свойство, а не ошибка.

Когда заказ оплачен ​

Заказ считается оплаченным только при подтверждённом расчёте:

  1. пришёл подписанный вебхук payment.succeeded (подпись проверена, data.payment.status равен succeeded, заказ/сумма/валюта совпали с вашими), или
  2. GET вернул status: "succeeded" и settled: true.

Не считайте оплаченным: ответ создания (даже 201), payer_action, окончание вашего опроса, переход плательщика «назад на сайт» или любое значение, которое вы не распознали.

Таймаут и истечение — на вашей стороне ​

Eleven Pay не истекает и не отменяет счёт: отмены нет, и отправленный счёт остаётся оплачиваемым. Поэтому срок заказа — ваше решение:

  • По истечении вашего срока пометьте заказ как просроченный у себя. Это ничего не отменяет в Eleven Pay и у плательщика: счёт ещё можно оплатить.
  • Не создавайте новый счёт «на замену» для того же заказа; для нового намерения — новый заказ.
  • Опрос с ограничением по времени, закончившийся без результата, означает «ещё не оплачено», а не «не удалось»: вебхук всё ещё может прийти.

Поздний платёж (после вашего срока) ​

Если проверенный payment.succeeded приходит для заказа, который вы уже пометили просроченным:

  • не теряйте деньги и не игнорируйте событие: ответьте 2xx (отказ не «отменит» платёж);
  • по умолчанию отправьте заказ на ручной разбор (выдать вручную или вернуть деньги другим способом — возвраты для счетов Cashier недоступны);
  • автоматическая выдача после срока — это явная политика мерчанта, а не поведение по умолчанию.

Готовая реализация этого правила есть в Python и Node.js наборах: просроченный заказ + проверенный платёж → запись late_payment_after_expiry в очередь разбора (политика review) либо выдача (политика fulfil).

Сверка после перезапуска ​

Храните у себя: merchant_order_id, Idempotency-Key, reference (после первого ответа), последний invoice_state, срок заказа, список обработанных id событий. После перезапуска:

  • заказы без reference повторите тем же запросом и тем же ключом (вернётся исходный счёт);
  • заказы с reference, но без итога, сверьте GET;
  • вебхук, пришедший во время простоя, будет повторён Eleven Pay (повторы).

Лимиты ​

Лимиты есть, значения не публикуются: 429 rate_limited (заголовок Retry-After) и 429 payer_rate_limited (слишком много счетов одному плательщику; Retry-After: 3600). Лимиты суммы и количества задаются при подключении организации (409 cashier_limit_exceeded).