API-модуль товара
Инструкция для интеграций, где товар формируется на вашем сервере, а не лежит на складе BOT-T.
Два сценария:
- После оплаты. BOT-T шлёт вебхук с заказом. Вы записываете содержимое и отправляете его покупателю.
- Через обратную связь. Покупатель заполняет форму. BOT-T шлёт заявку на ваш URL. Вы отвечаете текстом — BOT-T отправляет его в Telegram.
Сценарий 1. Оплата → вебхук → выдача
sequenceDiagram
participant Buyer as Покупатель
participant Bot as BOT-T
participant You as Ваш сервер
Buyer->>Bot: Оплачивает заказ
Bot->>You: POST вебхук с объектом заказа
You->>You: Готовите ключ / аккаунт / ссылку
You->>Bot: POST update-product
You->>Bot: POST send-product
Bot->>Buyer: Содержимое в Telegram
- Покупатель оплачивает заказ.
- BOT-T отправляет на ваш URL объект заказа.
- Вы формируете содержимое.
- Записываете его в заказ:
update-product. - Отправляете покупателю:
send-product.
Пока не вызваны оба метода, покупатель может не получить товар.
Подготовка в ЛК
У категории включите модуль API и укажите HTTPS URL «уведомление после оплаты».
Для обратных вызовов update-product и send-product нужен токен бота:
bot_id+botToken(илиsecretKey)
Запросы к API BOT-T выполняйте только с вашего backend.
Повторы вебхука возможны (до 3 попыток при сетевой ошибке). Обработка должна быть идемпотентной по id заказа: не выдавайте новый ключ на каждый повтор.
Что приходит на ваш URL
POST, тело application/x-www-form-urlencoded (не JSON).
В PHP это $_POST. Ответ: HTTP 2xx, тело не проверяется. Отвечайте быстро, тяжёлую работу уводите в очередь у себя.
Пример объекта заказа (в форме те же поля вложенно: category[id], user[telegram_id], product[data]):
{
"id": 1001,
"count": 1,
"status": 1,
"price": "150.00 ₽",
"amount": 15000,
"discount": 0,
"created_at": "2024-05-21 12:00:00",
"email": "[email protected]",
"bot_clone_id": null,
"purchase_bot_title": "—",
"product": {
"type": "text",
"data": ""
},
"user": {
"id": 100500,
"telegram_id": 182352323552,
"username": "buyer",
"first_name": "Иван",
"last_name": "Иванов",
"link": "@buyer",
"type": "private"
},
"botUser": {
"id": 555,
"bot_id": 1,
"money": 0,
"create_at": 1716280000,
"created_time": "2024-05-21 10:00:00",
"update_at": 1716280000,
"updated_time": "2024-05-21 10:00:00",
"expectation": null,
"secret_user_key": null,
"ref": null,
"status": {
"id": 1,
"title": "Активен"
},
"user": {
"id": 100500,
"telegram_id": 182352323552,
"username": "buyer",
"first_name": "Иван",
"last_name": "Иванов",
"link": "@buyer",
"type": "private"
}
},
"category": {
"id": 42,
"category_id": null,
"type": 1,
"status": 1,
"is_hide": false,
"is_view": true,
"api_id": 7,
"feedback_id": null,
"design": {
"title": "Ключ на 30 дней",
"description": "Описание до покупки",
"instruction": "Инструкция после покупки"
},
"price": {
"full": "150.00 ₽",
"amount": 15000,
"discount": 0,
"old_price": 0
}
}
}
| Поле | Зачем |
|---|---|
id | order_id для update-product и send-product |
status | 1 — оплачен. 0 — ещё не оплачен |
amount | Сумма в копейках, уже со скидками BOT-T |
count | Количество |
product.data | Текущее содержимое. До вашего ответа часто пустое |
user.telegram_id | Telegram покупателя |
botUser.id | ID пользователя в боте |
category.id / category.design.title | Какой товар купили |
email | Email, если есть. Иначе null |
Если к заказу уже привязана заявка обратной связи, в том же POST будет поле reviews. Формат — как объект заявки в сценарии 2.
Записать содержимое
POST https://api.bot-t.com/v1/shop/order/update-product?botToken=...
Заголовок: Content-Type: application/json
{
"bot_id": 1,
"order_id": 1001,
"product": "KEY-ABC-123"
}
Несколько строк — через \n:
{
"bot_id": 1,
"order_id": 1001,
"product": "login: user01\npassword: secret\nurl: https://example.com"
}
| Поле | Обязательно | Описание |
|---|---|---|
bot_id | да | ID бота |
order_id | да | id из вебхука |
product | да | Текст до 9999 символов |
Заказ должен быть оплачен. Метод только пишет product, в Telegram ничего не шлёт.
Успешный ответ:
{
"result": true,
"data": {
"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": "Баланс",
"currency": "RUB"
},
"product": "KEY-ABC-123",
"created_at": 1716288000,
"coupon": null
}
}
Ошибка:
{
"result": false,
"message": "Нельзя изменить содержимое неоплаченного или отменённого заказа"
}
Отправить покупателю
POST https://api.bot-t.com/v1/shop/order/send-product?botToken=...
{
"bot_id": 1,
"order_id": 1001
}
Ответ — тот же объект заказа, что у update-product. Сначала update-product, потом send-product. Иначе уйдёт старое или пустое содержимое.
Пример обработчика
<?php
const BOT_ID = 1;
const BOT_TOKEN = '123456789:ABCdefGHI...';
$orderId = (int)($_POST['id'] ?? 0);
if ($orderId <= 0) {
http_response_code(400);
exit;
}
$product = 'KEY-' . $orderId;
botShopOrder('update-product', [
'order_id' => $orderId,
'product' => $product,
]);
botShopOrder('send-product', [
'order_id' => $orderId,
]);
http_response_code(200);
echo 'OK';
function botShopOrder(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'];
}
Сценарий 2. Обратная связь → ваш API → сообщение клиенту
Форма собирает данные у покупателя (логин, почту, выбор тарифа). Когда заявка заполнена, BOT-T сам вызывает ваш URL. Ответ вашего сервера BOT-T отправляет покупателю в чат.
Этот вызов не пишет товар в заказ. Если содержимое должно остаться в заказе и в кабинете — дополнительно вызовите update-product (и при необходимости send-product). order_id лежит в поле заявки data.
sequenceDiagram
participant Buyer as Покупатель
participant Bot as BOT-T
participant You as Ваш сервер
Buyer->>Bot: Заполняет форму обратной связи
Bot->>You: POST заявка (интеграция CUSTOM)
You->>You: Готовите товар по ответам
You-->>Bot: JSON result + data.message
Bot->>Buyer: Текст data.message в Telegram
Подготовка в ЛК
- Создайте сообщение обратной связи и вопросы (текст, выбор, файл).
- Привяжите его к товару: покупатель получает форму после оплаты.
- В обратной связи откройте интеграции и добавьте тип CUSTOM.
- В поле «Публичный ключ» укажите HTTPS URL вашего сервера.
«Приватный ключ» и «Дополнительный ключ» для CUSTOM не используются — можно оставить пустыми, если интерфейс их требует.
Интеграция срабатывает один раз, когда покупатель ответил на все вопросы.
Что BOT-T отправляет вам
POST, тело application/x-www-form-urlencoded.
В PHP — $_POST.
Пример заявки. Полезные ответы — в answer (готовый текст) и в items (по каждому вопросу).
{
"id": 9001,
"feedback_id": 15,
"bot_id": 1,
"answer": "Логин:\nuser01\n\nТариф:\n30 дней",
"created_time": "2024-05-21 12:10",
"notice_time": null,
"deleted_time": "",
"data": "{\"order_id\":1001}",
"status": {
"id": 1,
"title": "Не прочитан"
},
"user": {
"id": 100500,
"telegram_id": 182352323552,
"username": "buyer",
"first_name": "Иван",
"last_name": "Иванов"
},
"items": [
{
"id": 31,
"answer_id": 9001,
"type": 1,
"input": {
"id": 501,
"answer": "user01"
},
"file": null,
"select": null,
"crossroad": null,
"main_input": {
"id": 31,
"text": "Логин",
"type": 1,
"feedback_id": 15,
"confirm": false
}
},
{
"id": 32,
"answer_id": 9001,
"type": 3,
"input": null,
"file": null,
"select": {
"id": 88,
"options": [
{
"id": 12,
"option": {
"id": 12,
"text": "30 дней"
}
}
]
},
"crossroad": null,
"main_input": {
"id": 32,
"text": "Тариф",
"type": 3,
"feedback_id": 15,
"confirm": false
}
}
]
}
| Поле | Зачем |
|---|---|
id | ID заявки |
data | Строка JSON. Для формы товара: {"order_id":1001} |
answer | Все ответы одним текстом |
items[].type | 1 текст, 2 файл, 3 выбор, 4 развилка |
items[].input.answer | Ответ на текстовый вопрос |
items[].select.options[].option.text | Выбранный вариант |
items[].main_input.text | Текст вопроса |
user.telegram_id | Кому отвечать |
data приходит строкой. Перед использованием разберите JSON:
$meta = json_decode((string)($_POST['data'] ?? ''), true);
$orderId = (int)($meta['order_id'] ?? 0);
$login = $_POST['items'][0]['input']['answer'] ?? '';
Что вы должны ответить
HTTP 200, заголовок Content-Type: application/json, поле result.
Выдать текст покупателю:
{
"result": true,
"data": {
"message": "Ваш ключ: <b>KEY-ABC-123</b>",
"is_repeat": false
}
}
| Поле | Описание |
|---|---|
result | true — заявка обработана |
data.message | HTML-текст. BOT-T отправит его покупателю в Telegram. Если поля нет — сообщение не уйдёт |
data.is_repeat | true — удалить заявку и заново показать форму. По умолчанию не повторять |
Ошибка (заявка помечается прочитанной, текст уходит в лог, покупателю не отправляется):
{
"result": false,
"message": "Тариф недоступен"
}
data.message не заменяет update-product. Чтобы ключ сохранился в заказе:
$meta = json_decode((string)($_POST['data'] ?? ''), true);
$orderId = (int)($meta['order_id'] ?? 0);
$key = 'KEY-ABC-123';
if ($orderId > 0) {
botShopOrder('update-product', [
'order_id' => $orderId,
'product' => $key,
]);
}
header('Content-Type: application/json');
echo json_encode([
'result' => true,
'data' => [
'message' => 'Ваш ключ: <b>' . htmlspecialchars($key) . '</b>',
'is_repeat' => false,
],
], JSON_UNESCAPED_UNICODE);
Повторный send-product здесь не нужен: текст уже уходит через data.message.
Когда что использовать
| Задача | Как |
|---|---|
| Узнать об оплате | Вебхук сценария 1 |
| Записать ключ в заказ | update-product |
| Отправить сохранённый ключ ещё раз | send-product |
| Собрать данные и сразу ответить в чат | Сценарий 2, data.message |
| Произвольное сообщение из конструктора | send-message или send-request |
Типичные ошибки
| Симптом | Что проверить |
|---|---|
| Вебхук оплаты не приходит | URL модуля API у категории, заказ оплачен |
| Заявка обратной связи не приходит | Интеграция CUSTOM, в «Публичный ключ» — ваш HTTPS URL, форма заполнена до конца |
Нельзя изменить содержимое неоплаченного... | update-product до оплаты или для отменённого заказа |
| Покупатель ничего не получил | Нет send-product или пустой product. В сценарии 2 нет data.message |
Нет telegram_id для заказа | Заказ без Telegram |
| Повторная выдача другого ключа | Идемпотентность по id заказа |
| Ответ CUSTOM не принят | Нет JSON, нет result, HTTP не 200 |
Чек-лист
Сценарий 1:
- У категории указан HTTPS URL уведомления после оплаты
- Endpoint читает
$_POST, отвечает 2xx - Повтор вебхука не создаёт новый ключ
- Вызываются
update-product, затемsend-product
Сценарий 2:
- Форма привязана к товару
- В интеграции CUSTOM указан ваш URL
- Ответ — JSON с
resultиdata.message - Если ключ должен храниться в заказе — ещё и
update-productпоdata.order_id