Каталог товаров в Telegram Mini App на Vue: Pinia, localStorage и оплата через Invoice

Mini App — это полноценный веб‑интерфейс внутри Telegram. Для каталога товаров удобно разделить ответственность: фронтенд на Vue 3 (Pinia + localStorage) отвечает за UI и состояние корзины, бэкенд на PHP (Laravel или Yii2) отдаёт список товаров, проверяет initData и при необходимости создаёт счёт через sendInvoice.

Архитектура и поток данных

1. Пользователь открывает Mini App по глубокой ссылке https://t.me/YourBot/YourApp?startapp=catalog. 2. При загрузке Vue‑приложение вызывает Telegram.WebApp.ready() и читает Telegram.WebApp.initData. 3. Фронтенд шлёт initData на эндпоинт /api/catalog (POST, JSON). Бэкенд валидирует подпись (HMAC‑SHA256 от токена бота) и возвращает массив товаров. 4. Товары рендерятся в списке. Добавление в корзину мутирует Pinia‑store; после каждого изменения store сериализуется в localStorage.
5. Нажатие «Оплатить» запускает один из двух сценариев:

  • Telegram Invoice — бэкенд вызывает sendInvoice и возвращает invoice_url; фронтенд делает Telegram.WebApp.openInvoice(url).
  • Внешний платёж — бэкенд создаёт заказ в своей БД, генерирует lead_id = bin2hex(random_bytes(7)), сохраняет его и возвращает URL платёжного шлюза. Фронтенд открывает его через Telegram.WebApp.openLink(url).
6. После успешной оплаты бот получает pre_checkout_query и successful_payment (или вебхук от платёжного шлюза) и завершает заказ.

Получение товаров и валидация initData на PHP

Корзина на Pinia с персистом в localStorage

В main.js вызываем useCartStore().load() сразу после создания приложения.

Оформление заказа: Telegram Invoice

Бэкенд формирует параметры счёта и вызывает sendInvoice через cURL. Важно: payload — строка ≤ 128 байт, туда кладут lead_id.

Фронтенд получает URL и делает:

Внешний платёжный шлюз

Если бизнес требует собственный эквайринг, бэкенд создаёт заказ, генерирует lead_id = bin2hex(random_bytes(7)) (14 символов, укладывается в 64‑байтовый callback_data), сохраняет запись в БД и возвращает URL платёжной страницы. Фронтенд открывает её через Telegram.WebApp.openLink(url). После оплаты шлюз шлёт вебхук на ваш эндпоинт; там проверяете подпись, находите заказ по lead_id и меняете статус.

Безопасность, лимиты и идемпотентность

  • initData — всегда проверяйте HMAC на сервере; не доверяйте данным из Mini App без валидации.
  • callback_data — не превышайте 64 байта. Для идентификаторов заказов используйте короткие hex‑строки (14 символов) или числовые ID.
  • Webhook — настройте secret_token при setWebhook. В контроллере сверяйте заголовок X-Telegram-Bot-Api-Secret-Token. Сохраняйте обработанные update_id в таблице (уникальный индекс) — это гарантирует идемпотентность при повторной доставке.
  • sendInvoiceprovider_token выдаётся @BotFather для каждого платёжного провайдера. Тестовый токен работает только в тестовом режиме.
  • Локальное хранениеlocalStorage очищается пользователем; при критических данных дублируйте корзину на сервере (например, при авторизации пользователя).

Типичные ошибки и отладка

Ошибка 400 Bad Request при sendInvoice — чаще всего неверный provider_token или сумма в amount не кратна минимальной единице валюты (копейки для RUB). Проверьте ответ Telegram: поле description содержит подробности.

initData валидация падает — убедитесь, что на бэкенде используется тот же токен бота, что и в @BotFather. Пробелы и переносы строк в data_check_string должны совпадать с документацией (сортировка по ключам, разделитель \n).

Корзина теряется после перезахода — проверьте, что useCartStore().load() вызывается до первого рендера списка. Добавьте console.log в load() для диагностики.

Для локальной разработки удобно пробросить вебхук через ngrok и смотреть сырые апдейты в логах. В продакшене используйте очередь (RabbitMQ, Redis Streams) для обработки pre_checkout_query и successful_payment — это снимает нагрузку с PHP‑воркеров.

Готовый проект можно развернуть на BotCreator — платформа упрощает настройку вебхуков, хранение секретов и мониторинг ошибок. https://botservice.biz

Новые статьи — в Telegram

Разбираем, что автоматизировать в бизнесе и как это работает на практике. Без спама.