Telegram VPN bot with crypto payments
A self-hosted Telegram bot that sells VPN subscriptions for crypto. The customer picks a plan in the chat and pays on the SnapEX Pay page (USDT on TRC20, ERC20 or BEP20, plus other coins when SnapEX offers them for that amount). After the payment is confirmed, the bot creates or extends the user in your Marzban, 3x-ui or Remnawave panel and sends the subscription link to the same chat.
Free. Version 1.0.0.
What it does
- No wallet or blockchain node to run: the money goes to your SnapEX Pay merchant balance.
/startshows your plans as buttons; each tap creates a SnapEX Pay invoice and replies with a Pay button.- Supports Marzban, 3x-ui (both the 3.1+ clients API and the older inbound API) and Remnawave 2.x and 3.x. With
PANEL_TYPE=nonethe bot only confirms the payment and you hand out access yourself. - Signed webhook (HMAC-SHA256, 5-minute window); the invoice is re-read from the SnapEX Pay API and provisioned only when it is paid and belongs to the bot's order. Repeated deliveries provision an invoice once.
- Renewals: a returning customer (same Telegram account) is extended from the current expiry; a plan with a traffic limit starts a fresh quota.
- One container with long polling, so only the webhook port has to be reachable. Orders are kept in SQLite with a copy of the plan.
Install
- In the SnapEX Pay merchant cabinet create an API key with the
invoices.readandinvoices.writescopes. - Download and unpack the archive, run
cp .env.example .envand set the bot token, the SnapEX Pay key,PANEL_TYPE(marzban,3xui,remnawaveornone), the panel credentials andPLANS. - Start it:
docker compose up -d --build, then watchdocker compose logs -f bot. - The bot listens on port
8080(/webhookand/health). Put it behind a TLS reverse proxy such as Caddy or nginx. - In the cabinet add a webhook endpoint
https://<your bot host>/webhook, put itswhsec_…secret intoSNAPEX_WEBHOOK_SECRETand restart. Send/startto the bot and test a plan withSNAPEX_ENVIRONMENT=test.
Settings
| TELEGRAM_BOT_TOKEN, SHOP_NAME | Bot token from @BotFather; the shop name in /start and in the invoice description. |
|---|---|
| SNAPEX_API_KEY, SNAPEX_WEBHOOK_SECRET | Merchant API key (invoices.read, invoices.write) and the webhook secret (whsec_…). |
| SNAPEX_ENVIRONMENT, SNAPEX_FEE_ON | live or test invoices; who pays the SnapEX fee — merchant or customer. |
| PANEL_TYPE | marzban, 3xui, remnawave or none, plus the credentials of that panel. |
| PLANS | Comma-separated id:days:price_usd:traffic_bytes; 0 bytes = unlimited. |
Questions
Which panels does the bot support?
Marzban, 3x-ui (MHSanaei, both API versions) and Remnawave 2.x and 3.x. With PANEL_TYPE=none it only takes payments.
How is a customer matched to a VPN user?
The panel username is tg<telegram_id>, so each Telegram account maps to exactly one VPN user, and a repeat payment extends it.
What if I change prices later?
Orders keep a copy of the plan, so editing PLANS does not change orders that are already paid.
Can one payment be provisioned twice?
No. Repeated or concurrent webhook deliveries provision an invoice once, and every button tap gets its own invoice.
Does the server need an open port for Telegram?
No. The bot uses long polling; only the webhook port behind HTTPS has to be reachable for SnapEX Pay.
Other integrations
Ready to accept crypto?
Create a merchant account, get an API key and connect the module. 1% per payment, no monthly fee.