API публичной оплаты
Документация для внешних разработчиков: веб-страница оплаты, Telegram Web App, мобильное приложение или любой другой HTTP-клиент.
API позволяет провести прямую оплату через платёжную систему (карта, СБП и т.д.). Списание внутреннего баланса бота через эту форму не поддерживается.
Интерактивная спецификация OpenAPI доступна по адресу {API_BASE}/docs/ (раздел «Оплата (публично)»).
Общие сведения
| Параметр | Значение |
|---|---|
| Метод | POST для всех запросов |
| Базовый URL | {API_BASE}/v1/payment/order/{действие} |
| Заголовок | Content-Type: application/json |
| Авторизация | не требуется (ни токен бота, ни ключ пользователя) |
| Лимит | 120 запросов в минуту с одного IP |
Подставьте свой хост API вместо {API_BASE}, например https://api.example.com.
Формат ответа
Успех:
{
"result": true,
"data": { ... }
}
Ошибка:
{
"result": false,
"message": "текст ошибки"
}
Перед использованием поля data всегда проверяйте result === true.
Идентификатор оплаты (order_id)
order_id)В каждом запросе передаются bot_id (число) и order_id (строка).
| Формат | Что оплачивается | Пример | Откуда взять |
|---|---|---|---|
o-{число} | Заказ магазина | o-123321 | Ссылка на оплату, API магазина |
c-{число} | Заказ корзины | c-456 | После оформления заказа из корзины |
p-{число} | Платёж по сообщению бота (тип «Оплата») | p-789 | Сценарий бота / ссылка вида p-{номер} |
Условия доступа:
- заказ с таким номером существует;
bot_idсовпадает с ботом, к которому относится заказ;- заказ ожидает оплаты (см. раздел «Статус заказа»).
Статус заказа
Проверка выполняется во всех методах.
Если заказ уже оплачен (или иным образом не ожидает оплату), API вернёт ошибку:
{
"result": false,
"message": "Заказ уже оплачен"
}
Повторно начать сценарий оплаты для такого заказа нельзя — покажите пользователю сообщение об успешной оплате.
При успешном get-status заказ всегда в состоянии ожидания:
{
"result": true,
"data": {
"status": "wait",
"order_id": "o-123321",
"amount": 150000
}
}
Поле amount — сумма в минимальных единицах валюты (копейки, центы). Для отображения разделите на 100.
Сценарий для интерфейса
sequenceDiagram
participant UI as Ваш клиент
participant API as API оплаты
UI->>API: get-status
alt result=false (уже оплачен)
UI->>UI: Экран «Заказ уже оплачен»
else result=true, status=wait
UI->>API: get-groups
UI->>API: get-items (group_id)
UI->>API: get-pay-data (item_id)
UI->>UI: Форма / редирект на оплату
loop Пуллинг после оплаты
UI->>API: check-pay или get-status
end
end
Пошагово
-
Входные данные — из URL или конфигурации:
bot_id,order_id. Без них оплату не начинать. -
get-status— первая загрузка страницы. При ошибке «Заказ уже оплачен» — экран успеха, без мастера оплаты. -
get-groups— список групп способов оплаты (карты, СБП…). Пользователь выбирает группу → запомнитеgroup_id. -
get-items— способы оплаты в группе. Для карточек UI используйте поля вродеdesign.title,design.text_button. Пользователь выбирает способ →item_id. -
get-pay-data— экран оплаты. Сервер фиксирует выбранный способ. Смотритеdata.dataPay.type(таблица ниже). -
После ухода на оплату — периодически вызывайте
check-payилиget-status, пока оплата не подтвердится или не истечёт таймаут. -
Отмена — по кнопке «Назад» можно вызвать
cancel(данные для навигации в ответе).
Методы
Базовый путь: POST /v1/payment/order/{действие}
| Действие | Назначение |
|---|---|
get-status | Сумма и проверка, что заказ ждёт оплаты |
get-groups | Группы способов оплаты |
get-items | Способы оплаты в выбранной группе |
get-pay-data | Данные для экрана оплаты |
set-pay-input | Сохранить ввод пользователя (тип оплаты 2) |
check-pay | Запросить статус у платёжной системы |
cancel | Отменить сценарий оплаты |
POST /v1/payment/order/get-status
Проверить, можно ли начать оплату, и получить сумму.
Тело запроса
| Поле | Обяз. | Тип | Описание |
|---|---|---|---|
bot_id | да | integer | ID бота |
order_id | да | string | o-…, c-… или p-… |
Пример
{
"bot_id": 1,
"order_id": "o-123321"
}
Успех (data)
| Поле | Тип | Описание |
|---|---|---|
status | string | Всегда "wait" при успехе |
order_id | string | Переданный идентификатор |
amount | integer | Сумма в минимальных единицах валюты |
POST /v1/payment/order/get-groups
Список групп способов оплаты.
Тело запроса — как у get-status.
Успех (data)
| Поле | Тип | Описание |
|---|---|---|
order_id | string | Идентификатор оплаты |
amount | integer | Сумма |
groups | array | Группы |
Элемент groups[]
| Поле | Тип | Описание |
|---|---|---|
id | integer | ID группы (для get-items) |
title | string | Название |
text_choose | string | Подсказка при выборе |
sort | integer | Порядок сортировки |
POST /v1/payment/order/get-items
Способы оплаты внутри группы.
Тело запроса
| Поле | Обяз. | Тип | Описание |
|---|---|---|---|
bot_id | да | integer | ID бота |
order_id | да | string | Идентификатор оплаты |
group_id | да | integer | ID группы из get-groups |
Пример
{
"bot_id": 1,
"order_id": "c-456",
"group_id": 5
}
Успех (data)
| Поле | Тип | Описание |
|---|---|---|
order_id | string | Идентификатор оплаты |
amount | integer | Сумма |
items | array | Способы оплаты |
Каждый элемент items[] — публичное описание способа (название, текст кнопки, оформление). Секретные ключи платёжных систем не передаются.
POST /v1/payment/order/get-pay-data
Данные для экрана оплаты после выбора способа.
Тело запроса
| Поле | Обяз. | Тип | Описание |
|---|---|---|---|
bot_id | да | integer | ID бота |
order_id | да | string | Идентификатор оплаты |
item_id | нет | integer | ID способа из get-items |
Пример
{
"bot_id": 1,
"order_id": "p-789",
"item_id": 42
}
Успех (data) — основные поля
| Поле | Тип | Описание |
|---|---|---|
status | string | "wait" |
id | string/integer | Внутренний ID для отображения |
amount | integer | Сумма |
button_cancel_pay | string | null | Текст кнопки отмены |
button_check_pay | string | null | Текст кнопки «Проверить оплату» |
userContacts | null | В веб-API всегда null |
item | object | Выбранный способ оплаты |
dataPay | object | null | Инструкции для UI (см. ниже) |
Ошибка: если способ требует email/телефон для чека — result: false с текстом о выборе другого способа или оплате в Telegram-боте.
POST /v1/payment/order/set-pay-input
Нужен, когда dataPay.type === 2: пользователь вводит текст (номер карты отправителя, комментарий и т.п.).
Тело запроса
| Поле | Обяз. | Тип | Описание |
|---|---|---|---|
bot_id | да | integer | ID бота |
order_id | да | string | Идентификатор оплаты |
item_id | да | integer | ID способа оплаты |
input_value | да* | string | Введённый текст |
text | нет | string | Альias для input_value (устаревший) |
* Обязателен input_value или text.
Пример
{
"bot_id": 1,
"order_id": "o-123321",
"item_id": 42,
"input_value": "текст от пользователя"
}
Успех (data)
{
"saved": true,
"message": "Данные сохранены. Вызовите get-pay-data с тем же item_id."
}
После успеха снова вызовите get-pay-data с тем же item_id.
POST /v1/payment/order/check-pay
Проверить у платёжной системы, прошла ли оплата (аналог кнопки «Проверить оплату» в боте).
Тело запроса — как у get-status.
Успех (data)
| Поле | Тип | Описание |
|---|---|---|
payment_found | boolean | true — оплата найдена |
payment_url | string | Опционально: ссылка для повторной оплаты (отдельные платёжки) |
Если payment_found === true, можно показать экран успеха или снова вызвать get-status (ожидается ошибка «Заказ уже оплачен» после обработки webhook).
POST /v1/payment/order/cancel
Отменить сценарий оплаты (кнопка «Назад»).
Тело запроса — как у get-status.
Успех (data)
| Поле | Тип | Описание |
|---|---|---|
redirect_action | string | Идентификатор действия для навигации |
redirect_data | object | Дополнительные данные для навигации |
Поле dataPay — что показывать пользователю
dataPay — что показывать пользователюtype | Поведение |
|---|---|
| 0 | Только текст: показать dataPay.text |
| 1 | Ссылка: кнопка/ссылка на dataPay.link |
| 2 | Поле ввода по label_input и rules_input → set-pay-input → снова get-pay-data |
| 3, 4, 8 | В ответе requires_telegram: true — завершить оплату можно только в Telegram-боте |
| 6 | Открыть Web App: dataPay.web_app |
| 7, 9 | На сайте не поддерживается — API вернёт ошибку ещё на этапе get-pay-data |
Дополнительные поля dataPay:
| Поле | Описание |
|---|---|
text | Поясняющий текст |
link | URL оплаты |
web_app | URL Telegram Web App |
label_input | Подпись поля ввода (type 2) |
rules_input | Правила валидации ввода |
is_button_check | Если true — показывать кнопку проверки оплаты |
requires_telegram | Способ нельзя завершить на сайте |
requires_telegram_hint | Текст подсказки для пользователя |
next_action | Для type 2: "set-pay-input" |
next_action_hint | Подсказка по следующему запросу |
qr_image_url | URL QR-кода (если есть) |
Если заданы button_check_pay и dataPay.is_button_check === true, по нажатию вызывайте check-pay.
Типовые ошибки
| Ситуация | message (пример) |
|---|---|
Неверный формат order_id | Допустимы только o-{id}, c-{id} или p-{id} |
| Заказ не найден | not found |
bot_id не совпадает с ботом заказа | not_access (public_bot) |
| Заказ уже оплачен | Заказ уже оплачен |
| Нет настроенных способов оплаты | Создатель бота не настроил ни одного способа оплаты |
| Способ с чеком (email/телефон) | Текст про другой способ или оплату в Telegram |
| Сумма вне лимитов группы | Текст с минимальной/максимальной суммой |
| Внутренняя ошибка сервера | Произошла внутренняя ошибка |
Откуда берётся order_id
order_id| Тип | Как получить |
|---|---|
o-{id} | После создания заказа в магазине; часто передаётся в ссылке на страницу оплаты |
c-{id} | После оформления заказа из корзины (API корзины, метод создания заказа) |
p-{id} | При переходе пользователя к оплате сообщения бота с типом «Оплата» |
Чек-лист интеграции
- Страница принимает
bot_idиorder_idиз URL или конфигурации. - Все запросы: POST, JSON, заголовок
Content-Type: application/json. - В каждом теле есть
bot_idиorder_id. - Первая загрузка:
get-status; обработка «Заказ уже оплачен». - Цепочка:
get-groups→get-items→get-pay-data. - Рендер по
dataPay.type; для type 2:set-pay-input→get-pay-data. - Обработка ошибки способа с чеком на
get-pay-data. - Подсказка про Telegram для
requires_telegram. - Кнопка «Проверить оплату» →
check-pay. - Сумма в интерфейсе:
amount / 100(с учётом валюты проекта).