Shopbot - маркетплейс цифровых ключей для игр. Несколько магазинов, у каждого свои товары; витрина открывается как WebApp внутри Telegram, оплата — Telegram Stars, купленные ключи бот присылает в чат.
- Маркетплейс: несколько магазинов, у каждого владелец и сотрудники.
- Витрина (WebApp): каталог с поиском, фильтром по категориям и бесконечной подгрузкой, страница товара, корзина (на сессии), история заказов, профиль.
- Оплата Telegram Stars:
createInvoiceLink(currency=XTR), выдача ключей и уведомление владельцев магазина вsuccessful_payment, возврат звёзд (refundStarPayment). - Авторизация через
initDataиз Telegram WebApp (HMAC-SHA256). - Своя админ-панель (
/panel/, Bootstrap 5): дашборд с графиками, CRUD товаров и ключей, заказы, магазины, пользователи. Разграничение доступа: супер-админ / владелец / сотрудник. - Поддержка (тикеты): пользователь создаёт обращения в WebApp, они улетают в чат
поддержки (
SUPPORT_CHAT_ID) с кнопкой «Ответить»; ответ из чата приходит пользователю в бот.
Django 5 · Django REST Framework · aiogram 3 · PostgreSQL 16 · Bootstrap 5 + Chart.js · Pillow · gunicorn · Docker / docker-compose · nginx + Let's Encrypt.
shopbot/ # Django-проект (manage.py здесь)
├── shopbot/settings/ # base / development / production (выбор по DJANGO_ENV)
├── webapp/ # витрина + ВСЕ модели + DRF API + Telegram-auth
│ ├── models.py # Модели
│ ├── views.py # HTML-вьюхи
│ ├── api.py # auth, корзина, инвойс, возврат
│ └── management/commands/ # вспомогательные команды
├── panel/ # админ-панель
└── bot/ # Telegram-бот (aiogram): /start, оплата, уведомления
- TelegramUser (
AbstractUser):telegram_id(NOT NULL, unique),telegram_username,avatar_url. - Shop + ShopMembership (роль owner/staff) — пользователь может состоять в нескольких магазинах.
- Category (дерево через self-FK), Product (
price_stars,stock/in_stock— property). - ProductKey (
is_sold,order_item), Order (status,telegram_payment_charge_id), OrderItem (shopденормализован для статистики,delivered_keysJSON). - SupportTicket (
subject,status) + SupportMessage (is_staff, append-only) — обращения в поддержку.
- Витрина собирает session-корзину →
POST /api/create-invoice/. - Сервер проверяет наличие ключей и дёргает
createInvoiceLink:currency="XTR",provider_token="", сумма — целое число звёзд (без деления на 100).payload— состав заказа. - Фронт открывает счёт через
Telegram.WebApp.openInvoice(link). - Бот:
pre_checkout_queryпроверяет ключи →successful_paymentсоздаётOrder+OrderItem, резервирует ключи (select_for_update), сохраняетtelegram_payment_charge_id, шлёт ключи покупателю и уведомляет владельцев магазина. - Возврат:
POST /api/orders/<pk>/refund/→refundStarPayment, ключи возвращаются в наличие.
- Пользователь пишет обращение в WebApp (Профиль → «Поддержка»,
/support/). СохраняетсяSupportTicket+SupportMessage(старые сообщения не редактируются, можно только дополнять). - Бот шлёт обращение в чат
SUPPORT_CHAT_ID: тема (≤500 симв.), статус и кнопка «Ответить». - Сотрудник жмёт «Ответить» → бот показывает всю переписку и ждёт текст (FSM); ответ
сохраняется (
is_staff=True), статус →answered, и отправляется пользователю в чат. SUPPORT_CHAT_IDв.envобязателен. Узнать id чата — через@getidsbot/@userinfobot.
- Супер-админ (
is_superuser) - видит всё: все магазины, заказы, пользователи, глобальная статистика. - Владелец (ShopMembership owner) - свои магазины: товары, ключи, заказы, статистика, сотрудники.
- Сотрудник (staff) - товары и ключи магазинов, где состоит.
Продавец входит в панель через витрину: Профиль → «Панель управления»
(или «Стать продавцом» → /panel/shops/create/). Супер-админ логинится на /admin/login/.
Общее: создать .env в shopbot/ по образцу .env.example.
- Необязательны:
DEBUG,MAIN_PAGE_URL,TELEGRAM_API_URL,DJANGO_SECRET_KEY. DB_HOSTдолжен бытьdb(имя сервиса в docker-compose).
Сервисы compose: db (PostgreSQL) · web (Django, 127.0.0.1:9000 на хосте) · bot (polling).
Telegram WebApp требует HTTPS, поэтому локально поднимаем стек в Docker, а HTTPS получаем через обратный SSH-туннель до VPS (там nginx + сертификат уже настроены).
docker compose up -d --build
docker compose exec web python manage.py migrate
docker compose exec web python manage.py createsuperuser # спросит telegram_id
docker compose exec web python manage.py seed_test_data # магазины, товары, ключиПрокинуть локальный web на VPS:
ssh -R 9000:127.0.0.1:9000 user@your_domainЗатем открыть бота — WebApp ходит на домен VPS, а запросы попадают в локальный контейнер.
Используется docker-compose.prod.yml (gunicorn, DJANGO_ENV=production, без bind-mount кода).
В .env обязательно задать ALLOWED_HOSTS и CSRF_TRUSTED_ORIGINS.
docker compose -f docker-compose.prod.yml up -d --build
docker compose -f docker-compose.prod.yml exec web python manage.py createsuperuserМиграции и collectstatic выполняются автоматически при старте сервиса web.
Статику в проде раздаёт хостовой nginx; имена статики
хешируются (ManifestStaticFilesStorage) — Telegram агрессивно кэширует static/JS.
Хостовой nginx проксирует на web и раздаёт static/media (замените YOUR_DOMAIN и пути):
server {
listen 443 ssl;
server_name YOUR_DOMAIN www.YOUR_DOMAIN;
ssl_certificate /etc/letsencrypt/live/YOUR_DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/YOUR_DOMAIN/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location /static/ { alias /path/to/ShopBot/shopbot/static/; }
location /media/ { alias /path/to/ShopBot/shopbot/media/; }
location / {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name YOUR_DOMAIN www.YOUR_DOMAIN;
return 301 https://$host$request_uri;
}# Тестовые данные (магазины, товары, обложки Steam CDN, ключи) — идемпотентно
docker compose exec web python manage.py seed_test_data
# Догенерировать ключи к товарам
docker compose exec web python manage.py generate_product_keys
# Запустить бота вручную (в Docker это делает сервис bot)
docker compose exec web python manage.py start_telegram_bot
# Полный сброс БД
docker compose down -vTELEGRAM_TEST=True в .env → бот и инвойсы идут на тестовый сервер Telegram,
где Stars бесплатные. Требуется отдельный бот, созданный в тестовом окружении Telegram
(другой DC, свой @BotFather). На обычном (прод) токене тест-режим даст Unauthorized.
Для дебага вашего webapp можно включить настройку в телеграме
Будет открываться devtools как в браузере по пкм
Очень полезна при разработке














