Заказы магазина (ShopOrder)
Документация для внешних интеграций: статусы заказа, жизненный цикл, поля в ответах API, методы и примеры запросов.
Авторизация API
Все методы — POST с телом JSON.
| Параметр | Где | Обязательность | Описание |
|---|---|---|---|
bot_id | тело | да | ID бота в системе BOT-T |
token или botToken | query или тело | да* | Токен бота |
secretKey | query | да* | Секретный ключ (альтернатива токену) |
* Достаточно либо token/botToken, либо secretKey.
Заголовки:
Content-Type: application/json
Формат ответа:
{ "result": true, "data": ... }
{ "result": false, "message": "текст ошибки" }
Всегда проверяйте result === true перед использованием data.
Статусы заказа (status)
status)| ID | Код | Название (RU) | Описание |
|---|---|---|---|
0 | WAIT | Ожидает оплаты | Заказ создан, товар зарезервирован, оплата не прошла. Начальный статус при создании. |
1 | ACTIVE | Оплачен | Оплата подтверждена. Товар выдаётся покупателю. |
2 | ERROR | Ошибка | Ошибка при обработке. Не учитывается в статистике продаж. |
3 | DELETED | Удалён | Служебный статус; при удалении заказа запись может быть полностью удалена из системы. |
4 | WORKING | В работе | Заказ в обработке (смена через API change-status). |
5 | COMPLETE | Выполнен | Заказ полностью исполнен. |
6 | WAIT_USER | Ожидает исполнителя | После оплаты для категорий типа «Услуга». |
7 | CANCEL | Отменен | Отмена с возвратом средств. |
8 | BOOKED | Бронируется | Может быть выставлен вручную через change-status. |
9 | RETURNED | Заявлен на возврат | Покупатель подал заявку на возврат. |
Какие статусы считаются «успешными» для аналитики
В выручку/статистику обычно не попадают заказы со статусами:
WAIT, ERROR, RETURNED, CANCEL
Оплаченные и обрабатываемые заказы: ACTIVE, COMPLETE, WORKING, WAIT_USER.
Жизненный цикл (упрощённо)
stateDiagram-v2
[*] --> WAIT: создание заказа
WAIT --> ACTIVE: оплата / success-order
WAIT --> [*]: отмена / reset-order
ACTIVE --> WAIT_USER: категория «Услуга»
ACTIVE --> WORKING: change-status
ACTIVE --> RETURNED: заявка на возврат
ACTIVE --> COMPLETE: change-status
WAIT_USER --> WORKING: change-status
WAIT_USER --> COMPLETE: change-status
RETURNED --> CANCEL: возврат средств
RETURNED --> COMPLETE: отказ в возврате
WORKING --> COMPLETE: change-status
ACTIVE --> CANCEL: возврат средств
Важно:
success-orderвозможен только для заказа в статусеWAIT(0). Иначе:Заказ уже оплачен.change-statusнельзя вызвать для заказа вWAIT— сначала подтвердите оплату (success-order).- Неоплаченный заказ при отмене снимает бронь и может быть удалён из системы.
- Для возврата денег по оплаченному заказу используйте сценарии возврата в боте/ЛК;
reset-orderудаляет заказ.
Поля заказа
Основные поля, встречающиеся в ответах API и при интеграции:
| Поле | Тип | Описание |
|---|---|---|
id | integer | ID заказа |
shop_id | integer | ID магазина |
category_id / shop_category_id | integer | ID категории (товара) |
user_id | integer | null | ID пользователя платформы; null — анонимный заказ |
bot_user_id | integer | null | ID пользователя в боте |
bot_clone_id | integer | null | ID бота-копии, если заказ через клон |
count | integer | Количество |
status | integer | Статус (см. таблицу выше) |
amount | integer | Сумма в минимальных единицах валюты (копейки) |
discount | integer | Списано с внутреннего баланса (копейки) |
telegram_id | integer | null | Telegram ID покупателя |
product | string / object | Выданный товар или ссылка на оплату (см. форматы ответа) |
created_at | integer / string | Время создания (Unix timestamp или строка) |
coupon | object | null | { code, discount, type } при применении купона |
Создание заказа
При создании через API:
- Проверяются лимиты неоплаченных заказов (настройки магазина).
- Проверяется минимальный интервал между заказами одного покупателя.
- Рассчитывается цена (акции, скидки, валюта бота).
- Статус устанавливается в
WAIT(0). - Товар бронируется на время оплаты.
Ссылка на оплату в Telegram-боте:
https://t.me/{username_бота}?start=o_{order_id}
Идентификатор заказа для платёжных систем (webhook):
{code}-{order_id}-{payment_item_id}
где order_id — ID заказа, code и payment_item_id выдаются при настройке оплаты в BOT-T.
API владельца магазина
Базовый префикс: /v1/shop/order/
| Метод | URL | Назначение |
|---|---|---|
index | POST .../index | Список заказов (пагинация, фильтр по статусу) |
view | POST .../view | Один заказ по order_id |
find-by-shop-product | POST .../find-by-shop-product | Поиск заказа по строке выданного товара (product) |
create-order | POST .../create-order | Создать заказ для bot_user_id |
create-order-api | POST .../create-order-api | Создать заказ API-категории (amount, product) |
success-order | POST .../success-order | Подтвердить оплату и выдать товар |
change-status | POST .../change-status | Сменить статус (status) |
reset-order | POST .../reset-order | Удалить заказ |
send-message | POST .../send-message | Отправить сообщение бота покупателю |
send-request | POST .../send-request | Вызов метода Telegram Bot API в чат покупателя |
POST /v1/shop/order/index
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
bot_id | integer | — | Обязательно |
category_id | integer | — | 0 — все категории магазина; иначе фильтр по категории |
status | integer | — | Фильтр по одному статусу (опционально) |
limit | integer | 20 | Максимум 20 |
offset | integer | 0 | Пагинация |
POST /v1/shop/order/view
| Поле | Описание |
|---|---|
order_id | ID заказа |
POST /v1/shop/order/create-order
| Поле | Описание |
|---|---|
category_id | ID категории |
count | Количество (> 0) |
bot_user_id | ID пользователя бота |
POST /v1/shop/order/change-status
| Поле | Описание |
|---|---|
order_id | ID заказа |
status | Новый статус (см. таблицу статусов) |
Нельзя менять статус у заказа в
WAIT(0).
POST /v1/shop/order/success-order
Подтверждает оплату вручную. Переводит WAIT → ACTIVE, выдаёт товар, отправляет уведомления покупателю.
Ответ API: список и просмотр (index, view)
index, view){
"id": 1001,
"category_id": 42,
"count": 1,
"bot_user_id": 555,
"user_id": 100500,
"telegram_id": 182352323552,
"status": 1,
"price": {
"sum": "150.00 ₽",
"balance_type_id": "ЮKassa",
"currency": "RUB"
},
"product": "ключ-активации-или-текст",
"created_at": 1716288000,
"coupon": null
}
| Поле | Описание |
|---|---|
status | Числовой ID статуса |
price.sum | Отформатированная сумма для отображения |
price.balance_type_id | Название способа оплаты |
product | Содержимое выданных позиций, строки через перенос |
coupon | { code, discount, type } или null |
Ответ API: создание заказа (create-order, create-order-api, публичный create)
create-order, create-order-api, публичный create)Расширенный объект заказа:
{
"id": 1001,
"count": 1,
"category": { "...": "объект категории" },
"user": { "...": "объект пользователя" },
"botUser": { "...": "объект пользователя бота" },
"product": {
"type": "text",
"data": "содержимое или ссылка на оплату"
},
"status": 0,
"price": "150.00 ₽",
"amount": 15000,
"discount": 0,
"created_at": "2024-05-21 12:00:00"
}
| Поле | Описание |
|---|---|
amount | Сумма в минимальных единицах (копейки) |
discount | Списано с баланса бота (копейки) |
product.type | pay — ссылка на оплату при status = 0; text, button и др. — после оплаты |
product.data | Текст товара, URL или deep-link o_{id} |
Публичный API (без пользователя Telegram)
Префикс: /v1/shoppublic/order/
| Метод | URL | Назначение |
|---|---|---|
create | POST .../create | Анонимный заказ (без user_id) |
get-product | POST .../get-product | Выдача товара после оплаты по order_id + orderKey |
Лимиты IP: 1 запрос/мин, 10/час, 100/сутки.
create
{
"bot_id": 1,
"category_id": 42,
"count": 1
}
В ответе дополнительно orderKey — секретный ключ (HMAC-SHA256 от order_id и токена бота). Сохраните его для получения товара после оплаты.
Недоступно для категорий типа «Подарок» / «Подарок файлом».
get-product
Требуется заказ в статусе ACTIVE (1).
{
"bot_id": 1,
"order_id": 1001,
"order_key": "..."
}
Альтернативное имя поля: orderKey.
Ответ: массив { "id", "product" }[].
Плейсхолдеры в сообщениях бота
Используются в шаблонах уведомлений BOT-T (при настройке текстов в личном кабинете):
| Плейсхолдер | Описание |
|---|---|
{ORDER_ID} | Номер заказа |
{ORDER_TIME} | Время создания (часовой пояс бота) |
{ORDER_PRICE} | Сумма с валютой |
{ORDER_PRICE_WITHOUT_CURRENCY} | Сумма без валюты (значение / 100) |
{ORDER_COUNT} | Количество |
{ORDER_STATUS} | Текст статуса |
{COUPON_INFO} | Информация о купоне |
{ORDER_ITEMS_INFO} | Строка товаров в заказе |
{TIME} | Минуты бронирования (на этапе оплаты) |
{TIME_END} | Время автоотмены |
{LOG} | Причина отмены |
Также доступны плейсхолдеры категории, пользователя и способа оплаты — их список отображается в редакторе сообщений в ЛК.
Примеры (PHP)
<?php
const API_BASE = 'https://api.example.com';
const BOT_ID = 1;
const BOT_TOKEN = '123456789:ABCdefGHI...';
function shopOrderRequest(string $action, array $body): array
{
$url = API_BASE . '/v1/shop/order/' . $action . '?botToken=' . urlencode(BOT_TOKEN);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode(array_merge(['bot_id' => BOT_ID], $body)),
]);
$raw = curl_exec($ch);
curl_close($ch);
$data = json_decode($raw, true);
if (!is_array($data) || empty($data['result'])) {
throw new RuntimeException($data['message'] ?? 'API error');
}
return $data['data'];
}
// Список оплаченных заказов (status = 1)
$orders = shopOrderRequest('index', [
'category_id' => 0,
'status' => 1,
'limit' => 20,
'offset' => 0,
]);
// Просмотр заказа
$order = shopOrderRequest('view', ['order_id' => 1001]);
// Смена статуса на «В работе»
shopOrderRequest('change-status', [
'order_id' => 1001,
'status' => 4,
]);
// Подтвердить оплату вручную
shopOrderRequest('success-order', ['order_id' => 1002]);
Фильтрация по нескольким статусам
В index API принимает один status. Для нескольких статусов делайте отдельные запросы или выгрузку без фильтра с отбором на своей стороне.
Типичные ошибки
| Сообщение | Причина |
|---|---|
Заказ уже оплачен | Повторный success-order для заказа не в статусе WAIT |
Нельзя сменить статус у неоплаченного заказа | change-status при status = 0 |
Достигнут лимит неоплаченных заказов | Превышен лимит ожидающих оплаты заказов у покупателя |
not found / access | Неверный order_id или category_id для данного бота |
product не указан | Пустой параметр в find-by-shop-product |
Нет telegram_id для заказа | Анонимный заказ без привязки к пользователю |
Важные замечания
-
Суммы: поля
amountи числовые суммы в интеграции — в копейках (минимальных единицах валюты). Полеprice.sumв ответеview— уже отформатированная строка. -
Пользователь заказа: если указан
bot_user_id, он используется в приоритете; иначе заказ привязывается поuser_idк пользователю бота. -
Статус после оплаты: для обычных товаров —
ACTIVE(1); для категорий «Услуга» —WAIT_USER(6). -
Срок брони: неоплаченный заказ может быть автоматически отменён по истечении времени, заданного в настройках магазина.