TKBK Studio
TKBK Studio
Витрина внутри Telegram: каталог, корзина и оплата Stars или картой через ЮKassa
Полноценная витрина, которая открывается прямо в Telegram по кнопке бота. Покупатель листает каталог, собирает корзину и платит, не выходя из мессенджера, — без сайта, регистрации и ввода адреса вручную.
Оплата встроенными средствами Telegram: Telegram Stars для цифровых товаров или банковская карта через ЮKassa для физических. Сервер сам пересчитывает заказ по каталогу и ещё раз сверяет его перед списанием, поэтому подменить цену из браузера нельзя. Подпись данных Mini App проверяется по HMAC-SHA256, как требует Telegram.
Товары лежат в одном JSON-файле и обновляются на лету. Интерфейс подстраивается под светлую и тёмную тему Telegram, о каждом оплаченном заказе вам приходит уведомление. Код простой — Node.js и Fastify без сборщика, легко доработать под себя.
Для кого: Кофейни, магазины, мастерские, продавцы цифровых товаров
Ключи и токены не вводятся на сайте — их кладут в файл .env на своём сервере.
BOT_TOKENТокен бота — Создайте бота у @BotFather → /newbotPUBLIC_URLАдрес витрины (HTTPS) — Домен с HTTPS, где запущен сервер, например https://shop.example.ruADMIN_CHAT_IDЧат для заказов — Отправьте боту /id в личке или в группеPAYMENTS_PROVIDER_TOKENТокен ЮKassa — @BotFather → /mybots → бот → Payments; не нужен для Stars# {{BRAND}} — магазин в Telegram Mini App
Витрина, которая открывается прямо внутри Telegram: каталог с категориями, корзина, оплата
Telegram Stars или банковской картой через ЮKassa. Покупатель не уходит из мессенджера,
вы получаете уведомление о каждом оплаченном заказе.
## Что умеет
- Каталог с категориями из файла `catalog/products.json` — правите файл, витрина обновляется без перезапуска.
- Корзина хранится на телефоне покупателя (localStorage) и переживает закрытие приложения.
- Цвета подстраиваются под тему Telegram (светлая/тёмная, `themeParams`).
- Кнопка Telegram (MainButton) «Оформить» → проверка заказа → «Оплатить».
- Оплата: Telegram Stars (`XTR`, без договора с банком) или картой через ЮKassa (рубли).
- Безопасность: подпись `initData` проверяется по HMAC-SHA256, цены считает сервер,
перед списанием денег заказ сверяется с каталогом ещё раз.
- После оплаты: сообщение покупателю, уведомление админу, запись в `data/orders.jsonl`.
- Бот: `/start` — приветствие с кнопкой магазина, `/id` — узнать chat_id.
## Как устроено
```
catalog/products.json товары (id, title, description, price, category, image)
public/ витрина: index.html, app.js, styles.css (без сборщика)
src/config.js название, цвет, приветствие, валюта — меняйте здесь
src/server.js API: /api/config, /api/products, /api/order, webhook бота
src/bot.js /start, /id, проверка перед оплатой, уведомления
src/cart.js расчёт заказа и счёта (покрыт тестами)
src/telegram.js проверка initData и вызовы Bot API
```
## Запуск за 5 минут (Docker)
1. Создайте бота: в Telegram откройте [@BotFather](https://t.me/BotFather) → `/newbot` → скопируйте токен.
2. Нужен публичный адрес с HTTPS (Telegram открывает Mini App только по HTTPS) — домен
на вашем сервере или туннель для теста (см. ниже).
3. Скопируйте `.env.example` в `.env` и заполните `BOT_TOKEN`, `PUBLIC_URL`, `ADMIN_CHAT_ID`
(и `PAYMENTS_PROVIDER_TOKEN` для оплаты в рублях).
4. Запустите:
```bash
docker compose up -d --build
docker compose logs -f
```
5. Откройте бота в Telegram и отправьте `/start` — появится кнопка «Открыть магазин».
При запуске сервер сам регистрирует webhook (`PUBLIC_URL/telegram/webhook`) и кнопку меню бота.
## Запуск без Docker
Нужен Node.js 20.16 или новее (рекомендуем 22 LTS).
```bash
npm install
cp .env.example .env # заполните значения
npm start
```
Тесты: `npm test`.
### HTTPS для теста на своём компьютере
```bash
cloudflared tunnel --url http://localhost:3000
```
Скопируйте выданный адрес `https://…trycloudflare.com` в `PUBLIC_URL` и перезапустите сервер.
Для постоянной работы поставьте перед сервером Caddy — он сам выпустит сертификат:
```
shop.example.ru {
reverse_proxy localhost:3000
}
```
## Где взять токены
- **BOT_TOKEN** — @BotFather → `/newbot` (или `/mybots` → бот → API Token).
- **ADMIN_CHAT_ID** — отправьте боту `/id` в личке или в группе, куда должны приходить заказы
(бота нужно добавить в группу).
- **PAYMENTS_PROVIDER_TOKEN** (только для рублей) — @BotFather → `/mybots` → бот → **Payments** →
ЮKassa. Сначала подключите тестовый режим (токен с `TEST`), проверьте оплату тестовой картой,
затем замените на боевой.
## Оплата: Stars или карта
Валюта задаётся в `src/config.js` (`currency`):
- `XTR` — Telegram Stars. Telegram требует Stars для цифровых товаров и услуг внутри Mini App.
Цены в `products.json` — целые числа звёзд.
- `RUB` — карта через ЮKassa, для физических товаров. Цены — в рублях (можно с копейками).
`askContacts` в `src/config.js`: `none`, `phone` (имя и телефон) или `address` (плюс адрес доставки).
## Подключить Mini App в @BotFather
Сервер при запуске сам ставит кнопку меню «Магазин». Вручную это делается так:
- **Кнопка меню:** @BotFather → `/mybots` → бот → Bot Settings → Menu Button → укажите `PUBLIC_URL`.
- **Отдельная ссылка `t.me/имя_бота/shop`:** @BotFather → `/newapp` → выберите бота,
укажите название, описание, картинку 640×360 и `PUBLIC_URL`.
## Товары
`catalog/products.json` — массив товаров:
| Поле | Что это |
|---|---|
| `id` | латиница, цифры, `-` и `_`, до 24 символов; не меняйте у проданных товаров |
| `title`, `description` | название и описание |
| `price` | цена: рубли (например `199.9`) или звёзды (целое число) |
| `category` | категория для фильтра |
| `image` | эмодзи, ссылка `https://…` или файл из `public/` (например `/img/latte.jpg`) |
| `available` | `false` — скрыть товар, не удаляя его |
## FAQ
**Кнопка не открывает магазин / белый экран.** Проверьте, что `PUBLIC_URL` открывается в браузере
по HTTPS и что после его изменения сервер перезапущен.
**Ошибка «Не удалось создать счёт».** Смотрите логи: чаще всего неверный `PAYMENTS_PROVIDER_TOKEN`
или сумма вне лимитов Telegram для валюты (минимум для рублей — около 100 ₽).
**Где хранятся заказы?** Уведомление приходит в `ADMIN_CHAT_ID`, а копия пишется в `data/orders.jsonl`
(в Docker — том `shop-data`: `docker compose exec shop cat data/orders.jsonl`).
**Как вернуть Stars?** Через метод Bot API `refundStarPayment` с `telegram_payment_charge_id`
из уведомления о заказе.
**Нужны чеки по 54-ФЗ?** ЮKassa принимает данные чека в `provider_data` счёта — добавьте их
в `invoiceParams` в `src/server.js` (см. документацию ЮKassa для Telegram Payments).
**Как поменять название, цвет, приветствие?** В `src/config.js` (объект `SETTINGS`)
и в `public/index.html` (заголовок страницы).
Услуги, мастера, свободные окна на 14 дней, напоминания за сутки и за 2 часа, предоплата и отзывы
Оценка 0–10 после заказа: довольных — на Яндекс Карты, 2ГИС и WB, недовольных — сразу к менеджеру
Оплата звёздами или картой, одноразовые ссылки, напоминания о продлении и автоисключение по окончании