# 🛍 Shop bot (Telegram)

A lightweight and stable bot for selling digital goods with automatic delivery.
Stack: **aiogram 3 + SQLAlchemy (async) + SQLite**. No unnecessary dependencies.

## Features

**For customers**
- 🛍 Catalog: categories → items → purchase with balance
  (item buttons are colored — 🟢 green in stock, 🔴 red sold out — via the Bot API button `style`)
- ⚡ Instant automatic delivery from stock (key / login / link / account)
- 🔐 Built-in Google Authenticator: if an item has a 2FA secret attached, the buyer taps a button and gets the current code (refreshes every 30 sec)
- 🔧 "More" section → **standalone 2FA code generator**: paste any secret and get codes right in the bot (not tied to a purchase)
- 💰 Add balance: automatic payment via CryptoBot when configured, otherwise an
  admin-approved request
- 👤 Profile: balance, purchase count, referral link
- 🧾 Purchase history (with a 2FA button on the relevant items)
- 🎁 Referrals: a percentage of invited friends' top-ups
- 🏆 Weekly leaderboard: top buyers of the week; resets every 7 days and pays the top two
  a bonus to their balance (🥇 +0.5, 🥈 +0.25) with a notification
- ⭐ Reviews: after a purchase the buyer rates the item (1–5 stars) and leaves a note; reviews show on the item card (numbered) with an average rating

**For admins**
- ➕ Categories and items (add / delete)
- ✎ Edit item: change name, description, price, or hide/show it — from the panel
- 🔢 Fractional prices & amounts supported (e.g. `0.5`, `0,25` — comma or dot)
- 📦 Stock upload as text **or a .txt file**, positions separated by `&`
- 🔐 Auto 2FA binding: a `2fa: SECRET` line in an item block enables code generation
- 💵 Manual balance credit / deduction
- ✅ Approve top-up requests right from the chat
- 📊 Statistics (users, sales, revenue, stock left)
- 📣 Broadcast to all users
- ⚙ Settings (edited live from the panel, no restart):
  - **⊙ Support** — support contact shown in the "More" menu
  - **🔔 Required channel** — mandatory subscription: non-admin users are blocked until
    they join the channel (with a "✓ I've subscribed" re-check button)
  - **⭐ Reviews group** — every new review is auto-posted here
  - **🛍 Shop channel** — where promo posts are published
  - **💳 CryptoBot token / 🪙 asset** — paste your Crypto Pay token to turn on
    automatic top-ups (invoice created on the spot, balance credited once paid)
- 🖼 Promo post: pick an item → preview → publish a "just added, in stock now" post with a
  **🛒 Buy now** button (a deep-link that opens the item card inside the bot)

> **Channels/groups:** add the bot as an **admin** of the required channel and the shop
> channel (so it can check membership / post), and as a member of the reviews group. Set
> each via **◆ Admin panel → ⚙ Settings**. Use `@username` for public chats or the numeric
> `-100…` id for private ones (send `-` to clear a field).

## Install (Windows)

1. Install Python 3.11+.
2. Run `setup.bat` (creates a venv and installs dependencies).
3. Copy `.env.example` → `.env` and fill in:
   - `BOT_TOKEN` — token from [@BotFather](https://t.me/BotFather)
   - `ADMIN_IDS` — your Telegram ID (find it: [@userinfobot](https://t.me/userinfobot))
4. Run `start.bat`.

## Install (manual / Linux)

```bash
python -m venv .venv
source .venv/bin/activate      # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env           # fill in BOT_TOKEN and ADMIN_IDS
python main.py
```

## How to start selling

1. In the bot tap **◆ Admin panel** (or the `/admin` command).
2. Create a category → add an item → upload stock (positions to deliver).
3. A user tops up their balance → you approve → they buy → they get the item instantly.

## Payments (Add balance)

The **➕ Add balance** button asks for an amount, then the method is chosen automatically
by config:

- **CryptoBot (automatic).** Set the Crypto Pay token either in the **admin panel**
  (◆ Admin panel → ⚙ Settings → 💳 CryptoBot token) or in `.env` as `CRYPTO_PAY_TOKEN`
  (get it in [@CryptoBot](https://t.me/CryptoBot) → Crypto Pay → Create App). Then the bot
  creates an invoice right away; the user pays in @CryptoBot and taps **✓ I paid — check** —
  the balance is credited automatically. Asset is the panel's 🪙 value or `CRYPTO_PAY_ASSET`
  (default `USDT`).
- **Manual (admin approval).** If no token is set, a request is sent to admins who
  approve/decline it from the chat.

Referral bonuses are paid on every credited top-up regardless of the method.

## Stock upload (including accounts with 2FA)

In "↑ Add stock" pick an item and send the positions — **as text or a .txt file**.
Positions are separated by a line with the `&` symbol. One block = one unit of the item
(can be multi-line). To bind Google Authenticator to an account, add a line with the
secret (`2fa:`, `totp:` or `secret:`).

```
login1@mail.com:password1
extra mail: mail1@mail.com:mailpass1
2fa: JBSWY3DPEHPK3PXP
&
login2@mail.com:password2
2fa: KRSXG5CTMVRXEZLU
&
login3@mail.com:password3
(this one — no 2FA)
```

A ready template is next to this file: `example_stock.txt`.

After purchase, an item with 2FA shows a **⬡ Get 2FA code** button —
the bot computes the current code itself (like the Google Authenticator app).
The secret is accepted with spaces and in any case, and also from an `otpauth://` link.

## Structure

```
main.py               — entry point
app/
  bootstrap.py        — bot startup
  config.py           — settings from .env
  db.py               — SQLAlchemy engine and sessions
  models.py           — tables (User, Category, Item, Stock, Purchase, Review, Setting, TopUp)
  runtime.py          — admin-editable settings (support, channels) cached from the DB
  middlewares.py      — mandatory-subscription gate
  leaderboard.py      — weekly top-buyer rewards + reset (background loop)
  keyboards.py        — keyboards
  states.py           — FSM states
  common.py           — shared helpers
  services/totp.py    — 2FA code generation
  handlers/
    user.py           — start (+ deep-link item cards), profile, purchases, top-up
    catalog.py        — catalog and buying
    admin.py          — admin panel (+ settings, promo posts, /payout test cmd)
    other.py          — "More" section + 2FA generator + subscription re-check
    reviews.py        — post-purchase ratings & reviews (auto-posted to reviews group)
```

Data is stored in `shop.db` (SQLite) — created automatically on first run.
