Skip to main content
Батч — это способ отправить до 5000 операций одним подписанным запросом. Работает для трёх видов операций: создание платежей, возвраты и выплаты. Главное, что нужно понять сразу: батч — это штатный способ не упираться в rate limit. Лимит частоты считается по HTTP‑запросам (по умолчанию 120 запросов/мин на IP). Если вы отправляете 5000 выплат циклом — это 5000 запросов, и вы гарантированно упрётесь в 429 и растянете работу на часы. Тот же список, отправленный батчем, — это один запрос и одна подпись.

Как это устроено: асинхронность

Батч не обрабатывается синхронно. Шлюз не держит ваше соединение, пока проводит 5000 выплат — это заняло бы минуты и любой таймаут убил бы запрос. Вместо этого:
То есть ответ на отправку не содержит результатов — только квитанцию с batch_id. Результаты появляются позже, в /v1/batch/info.

Шаг 1. Отправить батч

Три эндпоинта, по одному на вид операции. Внутри массива лежат ровно те же объекты, что вы отправили бы поштучно:
Сохраните batch_id — без него результаты не забрать. Элементы батча платежей поддерживают всё то же, что и одиночный POST /v1/payment, — включая цену в фиате, причём в разных валютах внутри одного батча:
Три режима создания счёта

on_error: что делать при ошибке в элементе

Отдельного статуса skipped нет. Непройденный элемент отличается от настоящей ошибки только текстом в поле error. Поэтому при on_error: "stop" число failed включает и те элементы, до которых обработка просто не дошла, — не считайте их все отказами.
Берите continue, если элементы независимы (типичный случай: выплаты разным людям). Берите stop, если пачка осмысленна только целиком и вы хотите разобраться до того, как уйдут остальные деньги. Как continue выглядит на практике: батч из 3 платежей, один элемент с несуществующей парой валюта/сеть →
Ошибка в середине не остановила остальные — элементы 0 и 2 создались.
stop — это не откат. Элементы, которые успели пройти до ошибки, уже выполнены и назад не откатываются: деньги ушли. stop лишь не даёт выполнить оставшиеся. Если вам нужна семантика «всё или ничего» — её нет: проверяйте данные до отправки.
Как выглядит stop на практике — тот же батч из 3 платежей, ошибка во втором:
Элемент 0 создался и остался. Элемент 2 не выполнялся — но формально он тоже error.

Шаг 2. Опрашивать статус

Статусы батча: pending (принят, ещё не начали) → processing (идёт обработка) → completed (обработаны все элементы, которые должны были обработаться).
completed не значит «всё удалось». Оно значит «шлюз закончил». Сколько элементов прошло, а сколько нет — смотрите в succeeded / failed.

Шаг 3. Разобрать результаты поэлементно

Ответ /v1/batch/info:
  • idx — позиция элемента в исходном массиве, который вы отправили. По нему вы сопоставляете результат со своей строкой в БД.
  • result — то, что вернул бы одиночный вызов (полный объект платежа/выплаты/возврата, с uuid).
  • error — строка с причиной, если элемент не прошёл.
Статусы элемента (items[].status) — не путайте их со статусом батча: Статуса skipped нет. Элемент, до которого обработка не дошла (при on_error: "stop"), тоже получает error — с текстом "skipped: batch stopped after an earlier failure". Отличить его от настоящего отказа можно только по этому тексту:
Ветвитесь по status, а не по тексту error. Текст в error — человекочитаемое сообщение, а не код ошибки: он может измениться. Единственное исключение — проверка на строку выше, если вам важно отличить «не дошли» от «не прошло».
items постраничные — их может быть 5000. Листайте через limit/offset:

Node.js: полный цикл


Шаг 4 (для выплат). done ≠ выплачено

Для батча выплат items[].status: "done" означает лишь, что выплата создана: в result она приходит со status: "process" (это видно в примере ответа выше). Финальные статусы — paid, fail или cancel — наступают позже, когда шлюз отправляет транзакцию в сеть, и выплата на этом этапе всё ещё может упасть.
Батч результат не переоценивает: выплата, упавшая после создания, в /v1/batch/info навсегда останется done. Смотреть на батч как на источник финального статуса нельзя.
Дождаться финала можно двумя способами: Именно поэтому в примерах выше мы сохраняем uuid каждого done-элемента: это ваш ключ для сверки финального статуса. Для батча платежей аналогично: done = счёт создан, об оплате сообщат invoice.*‑вебхуки.

Идемпотентность батча

Работает на двух уровнях, и оба стоит использовать:
  1. Заголовок Idempotency-Key на самом запросе батча. Защищает от «отправил батч, ответ потерялся, отправил ещё раз» — повтор с тем же ключом вернёт тот же batch_id, а не создаст второй батч из тех же 5000 выплат. Это ровно тот сценарий, где ошибка стоит очень дорого.
  2. order_id внутри каждого элемента. Дедуплицирует конкретную операцию (для выплат order_id обязателен). Даже если батч каким‑то образом продублируется, элементы с теми же order_id не уйдут дважды.
Идемпотентность

Ошибки уровня батча

Отклоняется весь запрос (элементы даже не начинают обрабатываться): Ошибки отдельных элементов сюда не попадают: они лежат в items[].error и не роняют весь запрос (при on_error: "continue").

Что осталось от /v1/payout/mass

POST /v1/payout/mass (до 100 выплат, синхронно) продолжает работать, но это легаси‑путь. Он оправдан ровно в одном случае: пачка маленькая и вам нужен результат прямо в ответе, без поллинга. Для всего остального — батч. Массовые выплаты

Практические правила

  • Не поллите слишком часто. /v1/batch/info — тоже запрос и тоже ест лимит частоты. Раз в несколько секунд более чем достаточно; вы только что сэкономили 5000 запросов, не тратьте их на поллинг.
  • Проверьте баланс до батча выплат. Если денег хватит на половину списка, вторая половина честно вернёт insufficient_funds в items[].error — но вы об этом узнаете только на разборе.
  • Храните batch_id рядом с задачей. Если ваш процесс упал в середине поллинга, batch_id — единственный способ забрать результаты потом.
  • Уникальный order_id на каждый элемент. Это ваш якорь для сверки: idx привязан к позиции в массиве, order_id — к вашей сущности.

Связанные страницы

POST /v1/payment/batch

POST /v1/payout/batch

POST /v1/refund/batch

POST /v1/batch/info

Массовые выплаты (легаси)

/v1/payout/mass и когда он ещё уместен.

Ограничение частоты

Почему батч решает проблему 429.

Идемпотентность

Рецепт устойчивого клиента

Первая выплата

Возвраты платежей