Заказы

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

Документация для внешних интеграций: статусы заказа, жизненный цикл, поля в ответах API, методы и примеры запросов.


Авторизация 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.


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

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

Какие статусы считаются «успешными» для аналитики

В выручку/статистику обычно не попадают заказы со статусами:

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 и при интеграции:

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

Создание заказа

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

  1. Проверяются лимиты неоплаченных заказов (настройки магазина).
  2. Проверяется минимальный интервал между заказами одного покупателя.
  3. Рассчитывается цена (акции, скидки, валюта бота).
  4. Статус устанавливается в WAIT (0).
  5. Товар бронируется на время оплаты.

Ссылка на оплату в 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Назначение
indexPOST .../indexСписок заказов (пагинация, фильтр по статусу)
viewPOST .../viewОдин заказ по order_id
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Подтвердить оплату и выдать товар
change-statusPOST .../change-statusСменить статус (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Пагинация

POST /v1/shop/order/view

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

POST /v1/shop/order/create-order

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

POST /v1/shop/order/change-status

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

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

POST /v1/shop/order/success-order

Подтверждает оплату вручную. Переводит WAITACTIVE, выдаёт товар, отправляет уведомления покупателю.


Ответ API: список и просмотр (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)

Расширенный объект заказа:

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

Публичный API (без пользователя Telegram)

Префикс: /v1/shoppublic/order/

МетодURLНазначение
createPOST .../createАнонимный заказ (без user_id)
get-productPOST .../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 для заказаАнонимный заказ без привязки к пользователю

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

  1. Суммы: поля amount и числовые суммы в интеграции — в копейках (минимальных единицах валюты). Поле price.sum в ответе view — уже отформатированная строка.

  2. Пользователь заказа: если указан bot_user_id, он используется в приоритете; иначе заказ привязывается по user_id к пользователю бота.

  3. Статус после оплаты: для обычных товаров — ACTIVE (1); для категорий «Услуга» — WAIT_USER (6).

  4. Срок брони: неоплаченный заказ может быть автоматически отменён по истечении времени, заданного в настройках магазина.