11 KiB
BotShop — панель управления несколькими Telegram-магазинами
Однопользовательская веб-панель на PHP, из которой обслуживается сразу несколько Telegram-ботов-магазинов. Каждому боту заводятся свои города, районы, товары, варианты и платёжные реквизиты; покупатель проходит в боте цепочку «город → район → товар → вариант → подтверждение» и получает карточку заказа с уникальной суммой к оплате (цена плюс случайная надбавка), оператор подтверждает поступление оплаты вручную в панели, после чего бот сообщает покупателю о подтверждении. Автоматической сверки платежей и приёма чеков нет по замыслу — решение принимает человек.
Проект не связан с радиотематикой остальных репозиториев владельца и стоит отдельно.
Стек
- PHP 8 без фреймворка и без Composer: один файл-роутер
public/index.php(панель + webhook), PDO/MySQL. - MySQL/MariaDB, схема в
database/schema.sql. - Nginx + php-fpm (настраивается установщиком), systemd-юнит для polling-воркера.
- Telegram Bot API (
https://api.telegram.org) — два режима: webhook и long polling черезgetUpdates. - Frontend: серверный HTML со встроенным CSS прямо в
index.php, без JS-сборки.
Структура
| Путь | Назначение |
|---|---|
install.sh |
Автоустановщик для Ubuntu/Debian: пакеты, MySQL, база и пользователь, импорт схемы, storage/config.php, учётка администратора, vhost Nginx, systemd-сервис botshop-polling. Разбирает опции --local, --dir, --db-*, --admin-*, --no-polling. |
public/index.php |
Всё приложение: сессии, вход, дашборд, разделы «Боты / Города / Районы / Товары / Варианты / Реквизиты / Заказы / Логи», страница установки /install, обработчик Telegram-webhook /webhook/<секрет>. |
public/.htaccess |
Rewrite всех запросов на index.php (для Apache; установщик настраивает Nginx, где то же делается через try_files). |
scripts/polling.php |
Демон для работы без домена и SSL: раз за разом опрашивает getUpdates по всем активным ботам, повторяет логику диалога из index.php, хранит offset'ы в storage/polling_offsets.json, помечает просроченные заказы. |
database/schema.sql |
15 таблиц: users, bots, bot_users, balance_ledger, shop_cities, shop_districts, shop_products, shop_product_variants, shop_stock_items, shop_payment_methods, shop_orders, shop_payments, support_tickets, telegram_updates, audit_logs, admin_logs. |
VERSION |
Версия панели (0.1.1). |
storage/ |
Создаётся установщиком, в git не хранится: config.php с реквизитами БД, логи, offset'ы polling. |
README.upstream.md |
Прежний README автора: описание сценария заказа, статусов и заявленного «безопасного scope» магазина. |
Как запустить
Установка на чистый сервер (от root):
sudo apt update
sudo apt install -y git curl
git clone <адрес репозитория> botshop-installer
cd botshop-installer
sudo bash install.sh --local
В конце установщик печатает адрес админки (http://IP/login), email и сгенерированный пароль администратора, имя базы и пароль БД — их нужно сохранить.
Ручная установка без install.sh: создать базу, залить database/schema.sql, направить веб-сервер на каталог public/, открыть /install и заполнить форму — страница сама создаст storage/config.php и администратора.
Локальный режим (без домена и SSL) работает через polling:
systemctl status botshop-polling --no-pager
journalctl -u botshop-polling -f
Режим webhook: добавить бота в разделе «Боты» и нажать «Установить webhook» — панель вызовет setWebhook на адрес <схема>://<хост>/webhook/<webhook_secret>. Telegram требует HTTPS, поэтому этот режим применим только на домене с сертификатом; в репозитории настройки SSL нет.
Важно: install.sh не устанавливает код из текущего каталога — он клонирует и обновляет https://github.com/viktor138irk/bot.git. После переезда на Gitea переменную REPO_URL в начале install.sh нужно поменять, иначе установка и git pull будут тянуть старый репозиторий с GitHub.
Конфигурация
Переменных окружения нет. Настройки задаются двумя способами.
- Файл
storage/config.php(создаётся установщиком или страницей/install, в git не попадает):
| Ключ | Назначение | Пример |
|---|---|---|
db_host |
Хост MySQL | localhost |
db_name |
Имя базы | botshop |
db_user |
Пользователь БД | botshop_user |
db_pass |
Пароль БД | см. storage/config.php |
-
Параметры установщика (
install.sh):--dir(каталог установки, по умолчанию/var/www/botshop),--db-name,--db-user,--db-pass,--admin-email(по умолчаниюadmin@local.test),--admin-pass,--no-polling. Пароли БД и администратора при отсутствии генерируются из 24 символов. -
Настройки бота — в панели, раздел «Боты», хранятся в таблице
bots:
| Поле | Назначение | Значение по умолчанию |
|---|---|---|
token |
Токен Telegram-бота, хранится в базе в открытом виде | — |
webhook_secret |
Случайный сегмент URL webhook | генерируется |
status |
active / paused / error; polling-воркер берёт только active |
paused |
welcome_text |
Первое сообщение бота | «Выберите город:» |
min_add, max_add |
Диапазон случайной надбавки к сумме заказа, рублей | 1 и 19 |
order_ttl_minutes |
Срок жизни заказа до статуса expired |
30 |
referral_percent, *_pay_enabled, referral_enabled |
Поля в схеме есть, кодом не используются | — |
Состояние
Прототип, заброшенный на ранней стадии. Все 14 коммитов сделаны в один день — 2026-05-18, последний коммит 2026-05-18.
Рабочей является только базовая ветка сценария: добавление бота, справочники, оформление заказа, ручное подтверждение оплаты оператором. Схема базы (коммит «Расширена схема под баланс рефералку и автовыдачу») ушла заметно дальше кода: баланс, рефералы, склад цифровых товаров, платежи и тикеты поддержки описаны в SQL, но ни панель, ни воркер с этими таблицами не работают. VERSION содержит 0.1.1, README.upstream.md — 0.2.1; фактическому коду соответствует 0.1.1.
Что не доделано
- Расхождение статусов заказа между кодом и схемой. В
schema.sqlстатус называетсяwaiting_payment, аpublic/index.phpиscripts/polling.phpфильтруют поstatus='waiting_pay'. Из-за этого не работают: пометка просроченных заказов, счётчик «Ожидают оплату» на дашборде, кнопки «Оплачено»/«Отклонить» в списке заказов (условие$r['status']==='waiting_pay'никогда не выполняется) и проверка уникальности суммы вgenerateAmount(). Это первое, что нужно чинить. - Статусы
payment_review,delivered,refunded,rejectedиз схемы кодом не выставляются; послеpaidзаказ никуда не двигается, автовыдача товара изshop_stock_itemsне реализована. - Не реализованы: баланс (
balance_ledger), реферальная программа, поддержка (support_tickets), журналaudit_logs/admin_logs, оплата с баланса и BTC, оплата картой через провайдера. В боте нет главного меню, команды/startне различаются — любое сообщение сбрасывает диалог на выбор города. - В панели нет редактирования и удаления записей: разделы городов, районов, товаров, вариантов и реквизитов умеют только добавлять и показывать список. Нет пагинации (жёсткие
LIMIT 200/LIMIT 300), нет поиска и фильтров. - Действия «Оплачено» и «Отклонить» выполняются GET-ссылками без CSRF-проверки, тогда как формы токен проверяют.
- Ролей нет: поле
users.roleесть, но код проверяет только факт входа; учётка администратора одна. - Логи
storage/logs/создаются, но приложение в них ничего не пишет; ошибки polling идут в journald, ошибки панели — в лог PHP. - Тестов, CI, линтеров и файла зависимостей нет. Маркеров TODO/FIXME в коде нет.
- Токены ботов и платёжные реквизиты (номера карт, телефон СБП) хранятся в базе в открытом виде.