Управление заказами

Заказы магазина (ShopOrder)

Документация API владельца магазина: статусы, жизненный цикл, все методы /v1/shop/order/*, форматы ответов и примеры.


Авторизация API

Все методы — POST с телом JSON.

ПараметрГдеОбязательностьОписание
bot_idтелодаID бота в системе BOT-T
token или botTokenquery или телода*Токен бота
secretKeyqueryда*Секретный ключ (альтернатива токену)

* Достаточно либо token/botToken, либо secretKey.

Заголовки:

Content-Type: application/json

Формат ответа:

{ "result": true, "data": ... }
{ "result": false, "message": "текст ошибки" }

Всегда проверяйте result === true перед использованием data.

Хост API: https://api.bot-t.com.
Базовый префикс методов: /v1/shop/order/.


Статусы заказа (status)

IDКодНазвание (RU)Описание
0WAITОжидает оплатыЗаказ создан, товар зарезервирован, оплата не прошла.
1ACTIVEОплаченОплата подтверждена. Товар выдаётся покупателю.
2ERRORОшибкаОшибка при обработке. Не учитывается в статистике.
3DELETEDУдалёнСлужебный; запись может быть удалена из системы.
4WORKINGВ работеСмена через change-status.
5COMPLETEВыполненЗаказ полностью исполнен.
6WAIT_USERОжидает исполнителяПосле оплаты для категорий типа «Услуга».
7CANCELОтмененОтмена с возвратом средств.
8BOOKEDБронируетсяМожно выставить через change-status.
9RETURNEDЗаявлен на возвратПокупатель подал заявку на возврат.
10PARTIALLY_RETURNEDВозвращен частичноЧастичный возврат: сумма уменьшена, остаток в статистике.

Оплаченные (можно менять product через update-product):
ACTIVE, WORKING, COMPLETE, WAIT_USER, PARTIALLY_RETURNED.

В выручку обычно не попадают: WAIT, ERROR, RETURNED, CANCEL.


Жизненный цикл (упрощённо)

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: refund-order 100%
    RETURNED --> PARTIALLY_RETURNED: refund-order percent < 100
    RETURNED --> COMPLETE: отказ в возврате
    WORKING --> COMPLETE: change-status
    ACTIVE --> CANCEL: refund-order 100%
    ACTIVE --> PARTIALLY_RETURNED: refund-order percent < 100

Важно:

  • success-order — только для WAIT (0). Иначе: Заказ уже оплачен.
  • change-status нельзя для WAIT — сначала success-order.
  • update-product — только для оплаченных статусов.
  • reset-order удаляет заказ и не возвращает деньги.
  • Для возврата денег — refund-order.

Сводка методов

МетодURLНазначение
indexPOST .../indexСписок заказов
viewPOST .../viewОдин заказ
find-by-shop-productPOST .../find-by-shop-productПоиск по строке product
create-orderPOST .../create-orderСоздать заказ для bot_user_id
create-order-apiPOST .../create-order-apiСоздать заказ API-категории (amount, product)
success-orderPOST .../success-orderПодтвердить оплату и выдать товар
update-productPOST .../update-productЗаменить содержимое заказа (product)
send-productPOST .../send-productОтправить содержимое покупателю в Telegram
refund-orderPOST .../refund-orderВернуть деньги на баланс
change-statusPOST .../change-statusСменить статус
reset-orderPOST .../reset-orderУдалить заказ без возврата
send-messagePOST .../send-messageОтправить сообщение бота покупателю
send-requestPOST .../send-requestВызов метода Telegram Bot API

Методы подробно

POST /v1/shop/order/index

Список заказов магазина.

ПолеТипПо умолчаниюОписание
bot_idintegerОбязательно
category_idinteger0 — все категории; иначе фильтр
statusintegerФильтр по одному статусу (опционально)
limitinteger20Максимум 20
offsetinteger0Пагинация

Ответ data: массив объектов списка (см. формат списка).


POST /v1/shop/order/view

ПолеОписание
bot_idID бота
order_idID заказа

Ответ data: один объект заказа.


POST /v1/shop/order/find-by-shop-product

Поиск заказа по точному совпадению выданной строки product в shop_product.

ПолеОписание
bot_idID бота
productСтрока товара (точное совпадение)

Ошибки: product не указан, Товар с таким содержимым не найден или не привязан к заказу.


POST /v1/shop/order/create-order

Создаёт заказ для пользователя бота. Цена считается по категории. Статус — WAIT (0).

ПолеОписание
bot_idID бота
category_idID категории
countКоличество (> 0)
bot_user_idID пользователя бота

Не для категорий типа API (type = API_FEEDBACK) — для них create-order-api.


POST /v1/shop/order/create-order-api

Создаёт заказ только в категории типа API (API_FEEDBACK, type=5).
Сумма и содержимое задаются явно. Заказ сразу считается оплаченным (через внутренний success).

ПолеОписание
bot_idID бота
category_idID API-категории
countКоличество (> 0)
amountСумма в копейках
productСодержимое товара
bot_user_idID пользователя бота

Ошибка, если категория не API:
Нельзя создать заказ в данной категории, так как категория не является API.


POST /v1/shop/order/success-order

Ручное подтверждение оплаты: WAIT → оплачен, выдача товара, уведомления, вебхук API-модуля (если настроен).

ПолеОписание
bot_idID бота
order_idID заказа

POST /v1/shop/order/update-product

Заменяет содержимое выданных позиций заказа (shop_product).

ПолеТипОписание
bot_idintegerОбязательно
order_idintegerОбязательно
productstringОбязательно. Новое содержимое, до 9999 символов

Условия:

  • Заказ должен быть оплачен (isPaid: статусы 1, 4, 5, 6, 10).
  • Нельзя для WAIT, CANCEL, RETURNED, ERROR и т.п.
  • Если у заказа одна строка product — она обновляется; иначе старые строки удаляются и создаётся одна новая.

Не отправляет товар покупателю — для этого send-product.

Пример:

{
  "bot_id": 1,
  "order_id": 1001,
  "product": "KEY-ABC-123\nлогин: user\nпароль: secret"
}

Ошибки: product не указан, Продукт слишком длинный..., Нельзя изменить содержимое неоплаченного или отменённого заказа.


POST /v1/shop/order/send-product

Отправляет текущее содержимое заказа покупателю в Telegram
(тот же сценарий, что кнопка «Отправить товар» в ЛК).

ПолеОписание
bot_idID бота
order_idID заказа

Нужен telegram_id у покупателя. Если содержимое пустое — стратегия категории пишет в лог «нет товара» и по сути ничего не шлёт.

Типичная связка после вебхука:

  1. update-product
  2. send-product

POST /v1/shop/order/change-status

ПолеОписание
bot_idID бота
order_idID заказа
statusНовый статус (см. таблицу)

Нельзя менять статус у заказа в WAIT (0).


POST /v1/shop/order/refund-order

Возврат на внутренний баланс покупателя (как кнопка в ЛК). Не путать с reset-order.

ПолеТипПо умолчаниюОписание
order_idintegerОбязательно
percentinteger100Доля суммы, 1–100
  • percent = 100 → статус CANCEL (7).
  • percent < 100PARTIALLY_RETURNED (10), сумма уменьшается.

Нужны включённые пополнения в боте.


POST /v1/shop/order/reset-order

Удаляет заказ. Деньги не возвращаются. В ответе — данные заказа до удаления.

ПолеОписание
bot_idID бота
order_idID заказа

POST /v1/shop/order/send-message

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

ПолеОписание
bot_idID бота
order_idID заказа
message_idID сообщения бота

Сообщение должно принадлежать текущему боту.


POST /v1/shop/order/send-request

Произвольный метод Telegram Bot API в чат покупателя. chat_id подставляется из заказа.

ПолеОписание
bot_idID бота
order_idID заказа
methodИмя метода (например sendMessage)
paramsОбъект параметров

Ошибка без Telegram: Нет telegram_id для заказа.


Поля заказа

ПолеТипОписание
idintegerID заказа
shop_idintegerID магазина
category_id / shop_category_idintegerID категории
user_idinteger | nullID пользователя платформы
bot_user_idinteger | nullID пользователя в боте
bot_clone_idinteger | nullБот-копия
countintegerКоличество
statusintegerСтатус
amountintegerСумма в копейках
discountintegerСписано с баланса (копейки)
telegram_idinteger | nullTelegram ID
productstring / objectВыданный товар
created_atinteger / stringВремя создания
couponobject | null{ code, discount, type }

Ответ: список и просмотр

{
  "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Отформатированная сумма
productСодержимое позиций, строки через перенос
coupon{ code, discount, type } или null

Ответ: создание (create-order, create-order-api)

{
  "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Копейки
product.typepay при status = 0; text / button после оплаты
product.dataТекст товара или deep-link o_{id}

Создание заказа (общее)

При создании через API:

  1. Лимиты неоплаченных заказов.
  2. Минимальный интервал между заказами.
  3. Цена (акции, скидки, валюта).
  4. Статус WAIT (0), кроме create-order-api.
  5. Бронь товара на время оплаты.

Ссылка на оплату в боте:

https://t.me/{username_бота}?start=o_{order_id}

Публичный API (кратко)

Префикс: https://api.bot-t.com/v1/shoppublic/order/

МетодНазначение
createАнонимный заказ + orderKey
create-userЗаказ с user_id + secret_user_key
get-productВыдача после оплаты по order_id + orderKey
get-product-userВыдача по user_id + secret_user_key

Оплаченные для get-product: ACTIVE, WORKING, COMPLETE, WAIT_USER.


Плейсхолдеры в сообщениях бота

ПлейсхолдерОписание
{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 BOT_ID = 1;
const BOT_TOKEN = '123456789:ABCdefGHI...';

function shopOrderRequest(string $action, array $body): array
{
    $url = 'https://api.bot-t.com/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'];
}

$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]);

// После вебхука API-модуля: записать содержимое и отправить покупателю
shopOrderRequest('update-product', [
    'order_id' => 1001,
    'product' => "KEY-ABC-123",
]);
shopOrderRequest('send-product', [
    'order_id' => 1001,
]);

shopOrderRequest('refund-order', ['order_id' => 1001]);
shopOrderRequest('refund-order', [
    'order_id' => 1001,
    'percent' => 50,
]);

В index один status. Несколько статусов — отдельные запросы или фильтр на своей стороне.


Типичные ошибки

СообщениеПричина
Заказ уже оплаченПовторный success-order не в WAIT
Нельзя сменить статус у неоплаченного заказаchange-status при status = 0
Нельзя изменить содержимое неоплаченного или отменённого заказаupdate-product для неоплаченного
product не указанПустой product в update-product / find-by-shop-product
Продукт слишком длинный, максимальная длина 9999 символовproduct > 9999
Нельзя вернуть деньги у неоплаченного заказаrefund-order для WAIT
Нельзя вернуть деньги у отмененного заказа заказаПовторный refund-order
Нельзя вернуть деньги автоматически, так как выключены пополненияВыключены пополнения
Процент возврата должен быть от 1 до 100percent вне 1–100
Достигнут лимит неоплаченных заказовЛимит WAIT
not found / accessЧужой order_id / category_id
Нет telegram_id для заказаАнонимный заказ / нет Telegram

Важные замечания

  1. Суммы: amount — в копейках; price.sum в view — уже строка.
  2. Пользователь: приоритет у bot_user_id, иначе привязка по user_id.
  3. После оплаты: обычный товар → ACTIVE (1); «Услуга» → WAIT_USER (6).
  4. Бронь: неоплаченный заказ может отмениться по таймеру магазина.
  5. API-модуль товара: вебхук после оплаты, затем update-product и send-product.
  6. OpenAPI: Swagger UI на API-хосте (тег Магазин).