Telegram bot, FastAPI API, and React web app for selling VPN subscriptions with Remnawave integration.
ENGLISH | Π Π£Π‘Π‘ΠΠΠ
Important
The current main branch does not ship a standalone web admin panel in the default runtime stack.
Administrative control lives in the Telegram dashboard and operator flows inside the bot.
Tip
If you already know snoups/remnashop, the deployment flow here should feel familiar.
The environment setup, Docker stack, and Nginx wiring are intentionally close in day-to-day operation.
AltShop is a production-oriented stack for selling and servicing VPN subscriptions. It combines:
- a Telegram bot on
aiogram - a FastAPI backend with cookie-based web authentication
- a separate React/Vite web portal
- PostgreSQL, Valkey, Taskiq workers, and Nginx
- Remnawave integration for subscription lifecycle and synchronization
The current project surface is documented in docs/README.md.
| Role | What they get |
|---|---|
| Service owner | Product catalog, branding, access rules, payment gateways, referrals, partner mechanics, backups, and Remnawave sync |
| Admin/operator | Telegram dashboard for users, plans, gateways, notifications, broadcasts, imports, partner withdrawals, and operational settings |
| Buyer | Telegram and web purchase flows, trial access, device management, promocodes, referral rewards, partner cabinet, and account recovery |
After deployment, a customer can:
- sign in through username/password or Telegram auth
- see access requirements before registration
- accept rules and pass channel gating if enabled
- open the web cabinet and view subscriptions, transactions, and notifications
- buy a new subscription, renew an existing one, or add another one
- get a trial subscription if your project allows it
- choose a plan, duration, device type, payment method, and payment asset
- manage devices, generate connection links, and revoke old devices
- activate promocodes and review activation history
- link Telegram to a web account
- verify email, reset password by code or link, and change password in profile
- use referral links, referral QR codes, and points exchange flows
- open the partner cabinet, inspect earnings, and request withdrawals
The built-in Telegram dashboard currently covers:
- access modes:
PUBLIC,INVITED,PURCHASE_BLOCKED,REG_BLOCKED,RESTRICTED - rules acceptance and mandatory channel subscription gating
- user search, recent users, blacklist, and detailed user cards
- subscription editing and assignment changes
- plan configuration, durations, prices, availability, and squads
- promocode creation and reward configuration
- payment gateway activation, credentials, webhook settings, display order, and default currency
- referral program rules, eligible plans, reward strategy, and points exchange setup
- partner program percentages, tax model, gateway commissions, minimum withdrawal, and withdrawal review queue
- multi-subscription limits
- branding texts, project name, web title, verification messages, and banners
- user and system notification toggles
- broadcasts and audience segmentation
- backup creation, restore, retention, and Telegram delivery
- Remnawave integration views and import or sync flows
- statistics and operational snapshots
- public, invited, purchase-blocked, registration-blocked, or restricted entry mode
- required rules acceptance
- required Telegram channel subscription
- single-subscription or multi-subscription mode
- locale defaults and enabled locales
- plans and durations
- plan ordering and availability
- renew vs additional purchase flows
- default settlement currency
- per-gateway pricing behavior
The current codebase supports 14 gateway types:
- Telegram Stars
- YooKassa
- YooMoney
- Cryptomus
- Heleket
- CryptoPay
- T-Bank
- Robokassa
- Stripe
- Mulenpay
- CloudPayments
- Pal24
- Wata
- Platega
Telegram Stars is the only gateway enabled by default. The others must be configured and activated by the operator.
- referral reward type: points or extra days
- reward strategy and eligible plans
- points exchange into subscription days, gift subscriptions, discounts, and traffic
- partner level percentages
- gateway commission model
- tax percent
- minimum withdrawal amount
- project name and web title
- localized verification and recovery messages
- support username links
- banners and localized text content
- web domain and proxy trust rules
- web auth JWT secret
- CORS origins
- SMTP for verify and reset flows
- backup retention and Telegram backup delivery
cp .env.example .envAt minimum:
APP_DOMAINAPP_CRYPT_KEYBOT_TOKENBOT_SECRET_TOKENBOT_DEV_IDBOT_SUPPORT_USERNAMEWEB_APP_JWT_SECRETREMNAWAVE_TOKENREMNAWAVE_WEBHOOK_SECRETDATABASE_PASSWORDREDIS_PASSWORD
For a stable production setup:
- set
APP_ORIGINSto the real frontend origin list used by browsers - keep
APP_TRUSTED_PROXY_IPSaligned with the actual reverse proxy addresses - set
WEB_APP_URLif the frontend is served from a dedicated origin - do not set
BOT_MINI_APP=true; usefalse, an empty value, or the exact web app URL
If you want email verification and password recovery:
- set
EMAIL_ENABLED=true - fill
EMAIL_HOST - fill
EMAIL_FROM_ADDRESS - add SMTP credentials if required by your provider
Recommended target paths for the pull-based VPS stack:
acme.sh --issue --standalone -d '<domain>' \
--key-file /opt/altshop/nginx/remnabot_privkey.key \
--fullchain-file /opt/altshop/nginx/remnabot_fullchain.pemThe release workflow publishes:
ghcr.io/dizzzable/altshop-backendghcr.io/dizzzable/altshop-nginx
If GitHub creates them as private packages on the first push, switch both packages to Public once in the repository Packages settings. After that, the VPS can pull updates without docker login.
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -dIf the VPS was originally deployed manually and does not have docker-compose.prod.yml yet, bootstrap it in one command:
curl -fsSL https://raw.githubusercontent.com/dizzzable/altshop/main/scripts/bootstrap-prod-vps.sh | shOptional production overrides:
ALTSHOP_IMAGE_TAGto pin a backend release instead oflatestALTSHOP_NGINX_IMAGE_TAGto pin an nginx/web release instead oflatestALTSHOP_DB_VOLUME_NAMEandALTSHOP_REDIS_VOLUME_NAMEif the old server uses custom named Docker volumesNGINX_SSL_FULLCHAIN_PATHandNGINX_SSL_PRIVKEY_PATHif your certificates live outside/opt/altshop/nginx
https://<APP_DOMAIN>/webapp/https://<APP_DOMAIN>/api/v1/auth/branding
Recommended first actions:
- Review access mode and channel or rules requirements.
- Create or verify plans, durations, and pricing.
- Activate and configure payment gateways.
- Review branding and support links.
- Configure referral and partner settings if you use them.
- Check backup settings and notification behavior.
If you intentionally deploy from local sources instead of GHCR, keep using the existing build-based stack:
nginx/fullchain.pem
nginx/privkey.key
docker compose up --buildThe default Docker stack contains 7 services:
webapp-buildaltshop-nginxaltshop-dbaltshop-redisaltshopaltshop-taskiq-workeraltshop-taskiq-scheduler
Public surface:
/webapp/for the SPA/assets/for frontend assets/api/v1/*for the backend API/telegramfor Telegram webhook traffic/remnawavefor Remnawave webhook traffic/payments/*for payment webhooks
altshop/
|-- src/ backend application code
|-- web-app/ React/Vite frontend
|-- assets/ translations and default runtime assets
|-- nginx/ Nginx config and TLS mount paths
|-- docs/ canonical and historical documentation
|-- scripts/ maintenance and audit helpers
|-- docker-compose.yml default deployment contract
`-- Dockerfile backend container image
This public GitHub mirror intentionally excludes internal-only QA artifacts.
tests/stays local and is not required for runtime deployment- temporary
mypy-wave*.inifiles stay local and are not part of the product - GitHub Actions here only validates the public frontend surface
- Ruff configuration lives in
pyproject.toml - there is no separate
ruff.iniin this repository
Public mirror checks:
uv sync --locked --group dev
uv run python -m ruff check src
uv run python -m mypy srcFrontend:
cd web-app
npm ci
npm run lint
npm run type-check
npm run buildIf you work in the private internal workspace, you can additionally run the local backend pytest suite there.
Start here:
Canonical documents:
docs/01-project-overview.mddocs/05-api.mddocs/06-bot-dialogs.mddocs/07-payment-gateways.mddocs/08-configuration.mddocs/09-deployment.mddocs/10-development.md
MIT. See LICENSE.