This repository contains a FastAPI backend, a Telegram WebApp mini app and a lightweight admin dashboard for selling digital sticker packs with Stripe payments.
- FastAPI backend with SQLite (configurable) storage for stickers and purchases.
- Admin authentication via bearer token with hashed password stored in environment variables.
- Sticker management endpoints for creating, updating, deleting and toggling sticker visibility.
- Stripe checkout integration including webhook handler to mark purchases as fulfilled.
- Telegram mini app frontend (
frontend/mini-app) that lists stickers and launches the Stripe checkout session. - Admin dashboard frontend (
frontend/admin) to login, upload, edit, activate/deactivate, and delete stickers through the browser.
Copy the example environment file and update the values:
cp backend/.env.example backend/.envSet the following values:
SECRET_KEY: random string for JWT signing.ADMIN_PASSWORD_HASH: bcrypt hash of the admin password. Generate using Python:from passlib.context import CryptContext print(CryptContext(schemes=["bcrypt"]).hash("your-password"))
STRIPE_SECRET_KEY: Stripe secret key (sk_live_...orsk_test_...).STRIPE_SUCCESS_URL/STRIPE_CANCEL_URL: URLs to send customers after checkout.STRIPE_WEBHOOK_SECRET: Secret from your Stripe webhook endpoint (forcheckout.session.completed).
cd backend
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtuvicorn app.main:app --reloadThe backend serves static files from backend/static at http://localhost:8000/static.
The frontends are static and can be hosted by any static server. During development you can use python -m http.server:
# Mini app
cd frontend/mini-app
python -m http.server 5173
# Admin dashboard
cd ../admin
python -m http.server 4173Configure the global API_BASE_URL in each HTML file (or inject it at runtime) so the frontends can reach your backend (defaults to http://localhost:8000).
- Create a Telegram bot via @BotFather and enable WebApp support.
- Host the mini app frontend and configure the WebApp URL in BotFather to point to the hosted
index.html. - In your backend, expose an endpoint for Stripe webhooks and configure the webhook URL inside the Stripe dashboard.
To test webhooks locally, use the Stripe CLI:
stripe listen --forward-to localhost:8000/payments/webhook- Navigate to the hosted admin dashboard.
- Login using the password that matches
ADMIN_PASSWORD_HASH. - Upload new stickers using the form. Uploaded images are stored under
backend/static/stickersand automatically linked in the mini app. - Click Edit next to a sticker to load its data into the form, update any fields (and optionally upload a replacement image), then submit to save.
- Use Activate/Deactivate to control visibility in the mini app or Delete to remove a sticker entirely.
The repository includes Docker images and a docker-compose.yml file so you can run the entire stack on any host that supports Docker.
-
Create and populate
backend/.envusing the values described above. -
Build and start the containers:
docker compose up -d --build
The backend is available at
http://localhost:8000and the frontends athttp://localhost:8080. The Telegram mini app is served from the root path, while the admin dashboard is exposed at/admin/. -
Tail the logs to verify startup and Stripe webhook handling:
docker compose logs -f backend
-
When you are ready to stop the stack run
docker compose down. Add the--volumesflag if you want to remove the SQLite database and uploaded sticker images that are stored in the named volumes.
The frontend container rewrites a small config.js file at boot to point to the backend API. By default both mini app and admin dashboard talk to the internal http://backend:8000 service defined in the compose file.
- Set
API_BASE_URLto update both experiences at once. - Or set
MINI_APP_API_BASE_URL/ADMIN_API_BASE_URLseparately if they should call different backends.
For production deployments place the containers behind a TLS-terminating proxy (for example, Nginx, Caddy, or a cloud load balancer). Point Telegram’s WebApp configuration to https://your-domain/ (mini app) and access the admin dashboard at https://your-domain/admin/.
Expose https://your-domain/payments/webhook to Stripe so completed checkout sessions mark purchases as fulfilled. When running behind a reverse proxy be sure to forward the raw request body and Stripe-Signature header to the backend container.
backend/
app/
main.py
config.py
database.py
models.py
schemas.py
auth.py
routes/
admin.py
stickers.py
payments.py
requirements.txt
static/
stickers/
frontend/
mini-app/
index.html
main.js
styles.css
admin/
index.html
main.js
styles.css
README.md