Перейти к содержанию

Выгрузка счетов

Вы можете присылать в платёжный шлюз R1.pay список счетов на оплату. Эти счета будут разосланы в информационные системы управляющих компаний, чтобы попасть к конечным потребителям.

Процесс обработки счетов

  1. Поставщик услуг отправляет пакет счетов через POST /api/v1/invoices/push
  2. Шлюз проверяет каждый счет:
    • Проверяет на дубликаты комбинаций account+period в пакете. Несколько счетов за один период быть не должно.
    • Проверяет форматы и диапазоны всех полей.
    • Ищет в базе данных соответствующего счёту агента (управляющую компанию).
  3. Шлюз возвращает push_id (при успехе) или отклоняет пакет с деталями ошибок.
  4. Если счета валидны, шлюз присылает ответ, что счета приняты, и далее асинхронно рассылает их соответствующим агентам.
  5. По завершении операции поставщик услуг получит вебхук-уведомление со статусом рассылки и возможными ошибками.
  6. При необходимости статус рассылки счетов можно проверить самостоятельно через запрос к POST /api/v1/invoices/status

Информация о запросах

Базовый URL: https://paygw.robstor.ru/api/v1/
Метод: POST

Заголовки запросов:

Имя заголовка Значение
Content-Type application/json
R1-Token <ваш_секретный_токен>

Аутентификация

Используйте в разделе header запроса ключ R1-Token, содержащий ваш токен поставщика услуг. Получите токен у администратора платформы R1.pay. На нашей стороне ваш токен хранится в зашифрованном виде и проверяется при каждом обращении к сервису.

Пример CURL запроса с использованием токена для аутентификации:

curl -X POST https://paygw.robstor.ru/api/v1/invoices/push \
  -H "Content-Type: application/json" \
  -H "R1-Token: <ваш_секретный_токен>" \
  -d '{
    "invoices": [
      {
        "account": "3494987",
        "period": 202607,
        "date": "2026-07-01",
        "calculated": 500,
        "amount": 1500
      }
    ]
  }'

Коды состояния HTTP

Коды, которые мы отдаём в ответах на запросы.

  • 200 OK — запрос принят и обработан (включая случаи с ошибками валидации, отклонением счетов)
  • 401 Unauthorized — запрос отклонён, потому что указан неверный токен
  • 500 Internal Server Error — только в случае серверных сбоев на стороне шлюза

1. Отправка счетов

POST /invoices/push

Отправка пакета счетов на оплату для распределения по управляющим компаниям.

Запрос

Структура запроса

Поле Тип Обязательное Описание
invoices array Да Список счетов для отправки (поля счёта описываются далее)
account string Да Номер лицевого счёта клиента (макс. 64 символа)
period integer Да Период в виде числа в формате YYYYMM (например, 202607 для июля 2026). Месяц должен быть 01–12, год в диапазоне 2000-2050
date string Да Дата счёта в формате YYYY-MM-DD.
calculated integer Да Рассчитанная/начисленная сумма (в копейках). Строго больше нуля.
amount integer Да Итоговая сумма к оплате (в копейках). Строго больше нуля.
fields array Нет Дополнительные поля счёта (массив объектов { "field": "имя", "value": "значение" }). Обратите внимание: данный массив содержит ТОЛЬКО текстовую информацию (поля "field" и "value" обязательно имеют строковый тип данных, записываются в кавычках)

Пример запроса

{
  "invoices": [
    {
      "account": "3494987",
      "period": 202607,
      "date": "2026-07-01",
      "calculated": 500,
      "amount": 1500,
      "fields": []
    },
    {
      "account": "3494988",
      "period": 202607,
      "date": "2026-07-01",
      "calculated": 300,
      "amount": 900,
      "fields": [
        {
          "field": "имя необязательного дополнительного поля",
          "value": "значение дополнительного поля"
        }
      ]
    }
  ]
}

Ответ

Правила формирования ответа

  1. Ответ на данный запрос указывает на количество принятых к обработке или отклонённых счетов после первоначальной проверки (валидации). Но после инициализации рассылки счетов агенты могут отклонить тот или иной счёт или он может быть не доставлен по другим причинам. Окончательная информация о статусе рассылки счетов может быть получена позже через вебхук или через запрос статуса.
  2. Если хотя бы один счёт в пакете имеет ошибки, весь пакет отклоняется. В ответе указываются детали по каждому отклонённому счёту и причине отклонения, чтобы вы могли исправить данные и отправить повторно.

Структура ответа

Поле Тип Описание
msg string Сообщение о статусе обработки
push_id int64 Идентификатор запроса загрузки счетов (для отслеживания статуса)
status string Общий статус: in_progress, completed, completed_with_errors, failed
total integer Общее количество счетов в пакете
accepted integer Количество принятых счетов
rejected integer Количество отклонённых счетов
rejected_invoices array Список отклонённых счетов (пустой при успехе)

Поля в rejected_invoices

Поле Тип Описание
account string Номер лицевого счёта, который не был принят
error_code integer Код ошибки (см. документацию по ошибкам)
error string Текстовое описание ошибки

Примеры ответов

  • Все счета приняты к рассылке
{
  "msg": "We’ve received the invoices. Distribution to agents is now in progress.",
  "push_id": 12345,
  "status": "in_progress",
  "total": 2,
  "accepted": 2,
  "rejected": 0,
  "rejected_invoices": []
}
  • Запрос отклонён из-за части неверных счетов
{
  "msg": "Errors detected in one or more invoice entries. Request rejected.",
  "push_id": 0,
  "status": "failed",
  "total": 2,
  "accepted": 1,
  "rejected": 1,
  "rejected_invoices": [
    {
      "account": "3494988",
      "error_code": 401,
      "error": "Account not found"
    }
  ]
}

2. Узнать статус загрузки счетов

POST /invoices/status

Позволяет проверить текущий статус ранее отправленного пакета счетов.

Запрос

Структура запроса

Поле Тип Обязательное Описание
push_id integer Да Идентификатор запроса, полученный при отправке счетов через /api/v1/invoices/push

Пример запроса

{
  "push_id": 12345
}

Ответ

Структура ответа

Поле Тип Описание
msg string Сообщение о статусе запроса
push_id int64 Идентификатор запроса загрузки
status string Статус рассылки: in_progress, completed, completed_with_errors, failed
total integer Общее количество счетов в пакете
accepted integer Количество принятых агентами счетов
rejected integer Количество отклонённых счетов
rejected_invoices array Список отклонённых счетов с деталями ошибок. Список может быть пустым в случае отсутствия ошибок

Примеры ответов

  • Все счета успешно разосланы
{
  "msg": "Invoices delivery status information",
  "push_id": 12345,
  "status": "completed",
  "total": 2,
  "accepted": 2,
  "rejected": 0,
  "rejected_invoices": []
}
  • Счета частично разосланы
{
  "msg": "Invoices delivery status information",
  "push_id": 12345,
  "status": "completed_with_errors",
  "total": 5,
  "accepted": 4,
  "rejected": 1,
  "rejected_invoices": [
    {
      "account": "3494988",
      "error_code": 401,
      "error": "Account not found"
    }
  ]
}

ℹ️ Примечание: Статус completed_with_errors говорит о том, что рассылка счетов по управляющим компаниям завершена, но не все счета успешно разосланы и приняты. Список непринятых счетов с указанием ошибок можно посмотреть в rejected_invoices.

  • Запись с указанным push_id не найдена для данного поставщика

ℹ️ Примечание: Запрос должен поступать от того же поставщика услуг, который ранее инициировал загрузку

{
  "msg": "No record for merchant with the push_id",
  "push_id": 12345,
  "status": "",
  "total": 0,
  "accepted": 0,
  "rejected": 0,
  "rejected_invoices": []
}

Важные замечания по ответам

Логика работы шлюза

При отправке счетов каждый счёт проходит следующие проверки:

Правило Код ошибки Сообщение об ошибке
account пустой 303 "Empty account field"
Длина account > 64 301 "Account number exceeds maximum length of 64"
Период в period невалидный (месяц не 01–12 или год выходит за рамки 2000-2050) 302 "Error in period: Invalid period format"
calculated < 0 304 "Calculated value cannot be negative"
amount < 0 304 "Amount value cannot be negative"
Формат date не YYYY-MM-DD 305 "Invalid date format (expected YYYY-MM-DD)"
Дубликат account+period в пакете 306 "Duplicate account-period entry"
Счёт не зарегистрирован у агента 401 "Account not found"

Коды ошибок при доставке (error_code в rejected_invoices)

Код Ошибка (EN) Перевод Описание
301 Account number exceed maximum length of 64 Номер лицевого счёта превысил максимальную длину в 64 символа Указан слишком длинный номер лицевого счёта. Если номер действительно очень длинный, необходимо обратиться к администратору платёжной системы
302 Error in period: ... Ошибка в периоде:... после двоеточия указана более точная причина ошибки, например, неверный формат данных
303 Empty account field Лицевой счёт пустой Ошибка возникает, если лицевой счёт в счёте на оплату не указан
304 Calculated (Amount) value cannot be nagative Значение поля Calculated (Amount) не может быть отрицательным Эта ошибка может возникнуть, если сумма отрицательная
305 Invalid date format (expected YYYY-MM-DD) Неверный формат даты (ожидается в формате ГГГГ-ММ-ДД) Дата счёта указана не в принятом формате
306 Duplicate account-period entry Повторная запись "лицевой счет - период" В одном пакете не должна быть передано более одного раза запись, касающаяся одного лицевого счёта за один период
401 Account not found Лицевой счёт не найден Лицевой счёт не найден в базе платёжной системы. Это могло произойти, если лицевой счёт не был добавлен пользователем (и в базе данных не создалась запись об этом счёте), но поставщик услуг пытается присылать счета на оплату по данном лицевому счёту
501 Server Errors Ошибки сервера Ошибки, не связанные с передаваемыми данными, возникающие в результате сбоев на стороне сервера шлюза или серверов агентов:
- Cannot get active agents from DB — сервис не смог получить список активных агентов из БД.
- Failed to marshal invoice payload — сервис не смог сформировать данные для отправки агенту.
- Agent internal error, code= — агент вернул ошибку, сообщается её код
504 Failed to deliver to agent after several retries Ошибка доставки к агенту после нескольких попыток Возможно, сервер агента не доступен или неверно настроен, поэтому сервис не может доставить счета.

Вебхук-уведомления о статусе загрузки счетов

После завершения асинхронной рассылки счетов агентам (управляющим компаниям), шлюз отправляет вам вебхук-уведомление с финальным статусом и детальной статистикой. Вы самостоятельно указываете администратору платёжного шлюза R1.pay базовый URL вебхук-эндпоинта. Если URL не установлен, вебхук-уведомления отправляться не будут.

Вебхук-URL: https://ВАШ_BASE_WEBHOOK_URL/invoices/status
Метод: POST

Заголовки запросов:

Имя заголовка Значение
Content-Type application/json
R1-Token <ваш_секретный_токен>

Аутентификация

Шлюз отправляет заголовок R1-Token с вашим токеном, который вам нужно предварительно передать представителю R1.pay защищённым способом. Вам следует проверять этот токен для подтверждения, что запрос исходит от доверенного шлюза. Обычно такую проверку внедряют в middleware, подключённому к защищаемым роутам.

Пример части кода на Python, реализующего такую проверку:

  EXPECTED_TOKEN = os.environ.get("R1_Token")
  token = request.headers.get("R1-Token")
  if not token:
      abort(401)

  received = token.encode("utf-8")
  expected = EXPECTED_TOKEN.encode("utf-8")

  if not hmac.compare_digest(received, expected):
      abort(401)

Важно: В целях безопасности токены рекомендуется хранить в зашифрованном виде, чтобы в случае взлома эти чувствительные данные не попали в руки злоумышленников. Если выявлен факт утечки, следует незамедлительно сгенерировать новый токен для нашей системы.

Функционал обработчика вебхука

  1. Принять JSON-тело запроса со статусом рассылки
  2. Проверить заголовок R1-Token для подтверждения, что запрос от доверенного шлюза
  3. Обработать полученные данные (сохранить в вашу базу, обновить статусы счетов, отправить уведомления клиентам и т.д.)
  4. Вернуть HTTP 200 OK с любым валидным JSON-ответом

⚠️ Важно: Шлюз ожидает ответ 200 OK в течение ограниченного времени. Долгая обработка может привести к таймауту, но шлюз повторит попытку (см. retry-логику ниже).

Запрос

Структура запроса

Поле Тип Описание
msg string Сообщение о статусе уведомления
push_id int64 Идентификатор запроса загрузки (тот же, что был возвращён при /api/v1/invoices/push)
status string Финальный статус рассылки: completed, completed_with_errors, failed
total integer Общее количество счетов в пакете
accepted integer Количество счетов, принятых агентами
rejected integer Количество отклонённых/недоставленных счетов
rejected_invoices array Список отклонённых счетов с деталями ошибок (пустой массив при полном успехе)

Поля в rejected_invoices

Поле Тип Описание
account string Номер лицевого счёта, который не был принят
error_code integer Код ошибки (см. документацию по ошибкам )
error string Текстовое описание ошибки

Пример запроса

{
  "msg": "Webhook notification about invoices delivery status",
  "push_id": 12345,
  "status": "completed_with_errors",
  "total": 5,
  "accepted": 3,
  "rejected": 2,
  "rejected_invoices": [
    {
      "account": "3494988",
      "error_code": 401,
      "error": "Account not found"
    },
    {
      "account": "3494990",
      "error_code": 501,
      "error": "Agent internal error"
    }
  ]
}

Ответ

Ваш обработчик должен вернуть HTTP 200 OK с любым валидным JSON-ответом, например:

{
  "status": "received",
  "push_id": 12345
}

Шлюз не проверяет содержимое вашего ответа, ему важен код состояния 200.

Retry-логика

Если шлюз не получает ответ 200 OK или получает ошибку HTTP, он повторяет отправку вебхука.

3 попытки отправки — если все оказались неудачными, шлюз больше не повторяет отправку для этого push_id. В таком случае используйте POST /api/v1/invoices/status для ручной проверки статуса.