Розробка Telegram Mini App з інтеграцією 1С-Бітрікс
Telegram Mini App — це веб-застосунок, що відкривається всередині Telegram через WebApp API. З точки зору архітектури це звичайний SPA (React/Vue/Vanilla JS), але запущений у контексті Telegram: доступний об'єкт window.Telegram.WebApp, через який застосунок отримує дані користувача, кольорову схему, дані про сесію. Для інтернет-магазину на 1С-Бітрікс такий застосунок дозволяє винести каталог, кошик і оформлення замовлення прямо в месенджер без встановлення окремого мобільного додатку.
Архітектура: що де живе
Telegram Client
└─ Mini App (React SPA)
└─ HTTPS запити → Bitrix API (REST або кастомні ендпоінти)
└─ Валідація initData Telegram
└─ Бізнес-логіка: каталог, кошик, замовлення
Mini App не має прямого доступу до бази даних — все через API. Бітрікс виступає як бекенд, що надає JSON-відповіді. Аутентифікація користувача — через initData з Telegram WebApp (підпис HMAC-SHA256 по секретному токену бота).
Ініціалізація та валідація initData
При відкритті Mini App об'єкт window.Telegram.WebApp містить initData — рядок з даними користувача та хешем. Цей рядок потрібно передавати на сервер при кожному запиті та валідувати.
На стороні Mini App (React):
import { useEffect, useState } from 'react';
const tg = window.Telegram.WebApp;
export function useTelegramAuth() {
const [token, setToken] = useState<string | null>(null);
useEffect(() => {
tg.ready();
tg.expand();
const initData = tg.initData;
if (!initData) return;
// Надсилаємо initData на сервер для обміну на JWT-токен
fetch('/api/telegram/auth', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ init_data: initData }),
})
.then(r => r.json())
.then(data => setToken(data.token));
}, []);
return { token, user: tg.initDataUnsafe?.user };
}
На стороні Бітрікс — валідація підпису:
// /local/api/telegram/auth.php
namespace Local\TelegramMiniApp;
class InitDataValidator
{
private string $botToken;
public function __construct(string $botToken)
{
$this->botToken = $botToken;
}
public function validate(string $initData): bool
{
parse_str($initData, $params);
$hash = $params['hash'] ?? '';
unset($params['hash']);
// Сортуємо ключі, будуємо data-check-string
ksort($params);
$dataCheckString = implode("\n", array_map(
fn($k, $v) => "$k=$v",
array_keys($params),
array_values($params)
));
// Секрет: HMAC-SHA256 від токену бота з ключем "WebAppData"
$secretKey = hash_hmac('sha256', $this->botToken, 'WebAppData', true);
$expected = hash_hmac('sha256', $dataCheckString, $secretKey);
// Перевіряємо timestamp (не старше 24 годин)
$authDate = (int)($params['auth_date'] ?? 0);
if (time() - $authDate > 86400) {
return false;
}
return hash_equals($expected, $hash);
}
public function extractUser(string $initData): ?array
{
parse_str($initData, $params);
return json_decode($params['user'] ?? '{}', true);
}
}
Прив'язка Telegram-користувача до Бітрікс
При першому вході через Mini App потрібно зіставити Telegram user_id з покупцем у Бітрікс. Логіка:
class TelegramUserResolver
{
public function resolveOrCreate(array $tgUser): int
{
$tgId = (int)$tgUser['id'];
// Шукаємо користувача за користувацьким полем
$result = \CUser::GetList(
($by = 'ID'),
($order = 'ASC'),
['UF_TELEGRAM_ID' => $tgId],
['FIELDS' => ['ID']]
);
if ($row = $result->Fetch()) {
return (int)$row['ID'];
}
// Створюємо нового користувача
$user = new \CUser();
$userId = $user->Add([
'LOGIN' => 'tg_' . $tgId,
'NAME' => $tgUser['first_name'] ?? '',
'LAST_NAME' => $tgUser['last_name'] ?? '',
'PASSWORD' => md5(uniqid('', true) . $tgId),
'CONFIRM_PASSWORD' => md5(uniqid('', true) . $tgId),
'ACTIVE' => 'Y',
'GROUP_ID' => [2], // група «Покупці»
'UF_TELEGRAM_ID' => $tgId,
]);
return (int)$userId;
}
}
API-ендпоінти для Mini App
Каталог товарів, кошик і замовлення — через кастомні REST-обробники Бітрікс. Реєструємо маршрути:
// /local/routes/telegram.php — підключається з init.php
\Bitrix\Main\Routing\Router::getInstance()
->get('/api/telegram/catalog', [\Local\TelegramMiniApp\CatalogController::class, 'index'])
->get('/api/telegram/catalog/{id}', [\Local\TelegramMiniApp\CatalogController::class, 'show'])
->post('/api/telegram/cart/add', [\Local\TelegramMiniApp\CartController::class, 'add'])
->get('/api/telegram/cart', [\Local\TelegramMiniApp\CartController::class, 'index'])
->post('/api/telegram/order', [\Local\TelegramMiniApp\OrderController::class, 'create']);
Каталог через Highload API або \CIBlockElement:
class CatalogController
{
public function index(Request $request): JsonResponse
{
$elements = \CIBlockElement::GetList(
['SORT' => 'ASC'],
['IBLOCK_ID' => CATALOG_IBLOCK_ID, 'ACTIVE' => 'Y'],
false,
['nPageSize' => 20, 'iNumPage' => (int)$request->get('page', 1)],
['ID', 'NAME', 'PREVIEW_TEXT', 'PREVIEW_PICTURE', 'PROPERTY_PRICE', 'PROPERTY_ARTICLE']
);
$items = [];
while ($row = $elements->GetNextElement()) {
$fields = $row->GetFields();
$props = $row->GetProperties();
$items[] = [
'id' => (int)$fields['ID'],
'name' => $fields['NAME'],
'text' => $fields['PREVIEW_TEXT'],
'image' => \CFile::GetPath($fields['PREVIEW_PICTURE']),
'price' => (float)($props['PRICE']['VALUE'] ?? 0),
];
}
return new JsonResponse(['items' => $items]);
}
}
Оплата через Telegram Payments
Telegram підтримує вбудовану оплату через провайдерів (ЮKassa, Stripe та ін.). Для запуску платежу з Mini App:
// У Mini App після формування замовлення
async function initiatePayment(orderId: number) {
// Запитуємо invoice_link у сервера
const res = await fetch('/api/telegram/payment/invoice', {
method: 'POST',
headers: { Authorization: `Bearer ${token}` },
body: JSON.stringify({ order_id: orderId }),
});
const { invoice_url } = await res.json();
// Відкриваємо сторінку оплати Telegram
tg.openInvoice(invoice_url, (status) => {
if (status === 'paid') {
// Повідомляємо сервер, оновлюємо статус замовлення
confirmPayment(orderId);
}
});
}
На стороні Бітрікс — створення invoice через Bot API:
public function createInvoice(int $orderId, int $bitrixUserId): string
{
$order = \Bitrix\Sale\Order::load($orderId);
$response = $this->botApiPost('createInvoiceLink', [
'title' => 'Замовлення #' . $orderId,
'description' => 'Оплата замовлення ' . $order->getField('ACCOUNT_NUMBER'),
'payload' => json_encode(['order_id' => $orderId, 'user_id' => $bitrixUserId]),
'provider_token' => PAYMENT_PROVIDER_TOKEN, // токен ЮKassa в Telegram
'currency' => 'RUB',
'prices' => [['label' => 'Разом', 'amount' => (int)($order->getPrice() * 100)]],
]);
return $response['result']; // invoice_link
}
Склад робіт
- Реєстрація бота, налаштування Mini App через @BotFather
- React-застосунок: каталог, картка товару, кошик, оформлення замовлення
- Валідація initData на стороні Бітрікс
- Прив'язка Telegram-користувача до покупця в Бітрікс
- REST API: каталог, кошик, замовлення, статуси
- (Опціонально) Інтеграція Telegram Payments для оплати в один дотик
- Сповіщення покупцю через бота: зміна статусу замовлення
Терміни: MVP (каталог + кошик + замовлення) — 4–6 тижнів. Повна версія з оплатою та сповіщеннями — 8–12 тижнів.







