Repository navigation
Releases: JumpCodeFrog/telegram-shop-bot
Release list
v3.1.0
Telegram Shop Bot v3.1.0
Seven ways to get paid. One ledger that never loses a cent.
v3.1 is the payments release: four new payment rails join Stars and CryptoBot,
refunds arrive with a guarded two-tap flow, and every payment fact — captured,
quarantined, or refunded — is durably attributed to the component that recorded
it. Fully backward compatible: all new rails are off until configured, and the
database migrations are additive.
💳 Four new payment rails
- YooKassa — RUB cards. A "Pay by card" button appears at checkout and in
the Mini App for non-subscription carts; the buyer pays on YooKassa's
checkout page. Notifications are unsigned, so settlement happens only after
an authoritative API re-fetch validates provider, amount, currency, and order
binding. A backup poller re-scans the last 24 hours of succeeded payments
every 60 seconds, so a webhook lost to downtime or a network partition still
settles — and money arriving after stock sold out is quarantined for review,
never silently settled. - Stripe — USD cards. HMAC-signed webhooks settle straight from the signed
body — no API refetch. Raw-HTTP integration, no SDK dependency. Orders below
Stripe's $0.50 minimum are refused at payment. - TON — on-chain transfers. The buyer gets the wallet address, the exact
nanoton amount, and a mandatoryorder-<id>memo (aton://deeplink
prefills all three). A polling worker replays memo-matched transfers;
settlement is overpay-tolerant (the ledger records the actual received
amount) and underpays are quarantined. Integer nanotons end to end — a rate
change can never reprice an existing order. - NOWPayments — 300+ coins. Hosted invoices settle via HMAC-SHA512-signed
IPN callbacks verified over the canonicalized request body.⚠️ Run one
live test payment before enabling this rail in production to confirm the
byte-level canonicalization agreement — verification fails closed, so a
mismatch can reject genuine callbacks but never accept a forged one.
Subscriptions remain Stars-only by design.
🛡 Money you can trust
- Durable payment barriers. Webhook and polling acknowledgements happen
only after a charge is settled or durably quarantined — provider redeliveries
can never lose or double a payment. - Quarantine, not guesswork. Mismatched, malformed, or unexpected provider
facts land in a review queue instead of touching orders; every rail's
quarantine behavior is documented per reason class in
docs/payment-operations.md. - Immutable ledger. Captures, refunds, anomalies, and resolutions are
append-only; every new row now carries a durableactor(migration 023):
which ingress wrote it —webhook:<provider>,worker:<provider>,
admin:<id>, or a CLI operator.
🧾 Payment operations for admins
/refund <order_id> [amount]— two-tap preview→confirm refunds with the
confirm re-validating the ledger at tap time (TOCTOU-safe). Provider first,
ledger record second; a crash between them is recoverable, a double-tap is a
no-op, and the balance rail's re-run credits exactly once. Stars, Stripe,
YooKassa, and balance execute in-bot; crypto/TON/NOWPayments render honest
manual-dashboard guidance./payreview— the quarantine queue in chat: one card per case,
per-target reason codes and actor, and shape-gated action buttons that offer
only what the ledger can actually accept (dead buttons are gone; ambiguous
cases point at the CLI).payment-reviewCLI — list/preview/resolve plusingest-starsand
ingest-providerfor recording provider facts with preview-then---apply
discipline; a memo-less TON transfer is now resolvable by attaching it to the
intended order./paystatus— one truthful line per rail: configured or not, exchange
rates, and the webhook URLs to register — never printing a secret.
🛠 Admin & shop management
- Full admin panel: products, categories, photos, promos, button styles
(/btnstyle), order cards (/order <id>), and/setbalancefor audited
balance adjustments. - Balance payments — buyers with a positive USD balance check out
synchronously with an idempotent debit through the same guarded ledger path
as the external rails.
🔍 Observability
- Every Telegram update is processed under one per-update context (30s budget,
cancelled with the process on shutdown) carrying atrace_idthat appears in
the middleware and payment logs — one update's whole path is a single
grep trace_id=<id>away. - Settlement and refund logs carry the structured
actorfield end to end.
⬆️ Upgrade notes
- Back up the database before first start. Migrations 017–023 apply
automatically and are additive (new tables/columns, ledger provider CHECK
rebuilds); the ledger is immutable, so the newactorcolumn is write-once
at ingress — pre-upgrade rows keepNULL("not recorded") by design. - New optional environment variables:
YOOKASSA_SHOP_ID/YOOKASSA_SECRET_KEY
/YOOKASSA_RETURN_URL/USD_TO_RUB_RATE;STRIPE_SECRET_KEY/
STRIPE_WEBHOOK_SECRET/STRIPE_RETURN_URL;TON_WALLET_ADDRESS/
USD_PER_TON(TON_API_KEYoptional);NOWPAYMENTS_API_KEY/
NOWPAYMENTS_IPN_SECRET/NOWPAYMENTS_RETURN_URL. Unset rails stay fully
hidden — a half-configured rail shows WARN in/paystatusanddoctor. - Register the webhooks for every rail you enable:
<WEBHOOK_URL>/{yookassa,stripe,nowpayments}-webhook(TON has none — it
polls). - No breaking changes; no required configuration changes for existing
Stars/CryptoBot deployments.
Telegram Shop Bot v3.1.0 (RU)
Семь способов принять оплату. Один ledger, который не теряет ни копейки.
v3.1 — релиз платежей: четыре новых платёжных рельса в дополнение к Stars и
CryptoBot, возвраты с защищённым двухтаповым сценарием и дurable-атрибуция
каждого платёжного факта — кто его записал. Полная обратная совместимость:
новые рельсы выключены до настройки, миграции только добавляют.
💳 Четыре новых платёжных рельса
- YooKassa — карты, RUB. Кнопка «Pay by card» в чекауте и Mini App; оплата
на странице YooKassa. Уведомления не подписаны, поэтому settle — только после
авторитетного re-fetch через API (провайдер, сумма, валюта, привязка к
заказу). Резервный поллер каждые 60 секунд пересканирует успешные платежи за
24 часа: потерянный вебхук всё равно доведёт заказ до оплаты, а деньги,
пришедшие после распродажи, уходят в карантин, а не «проталкиваются». - Stripe — карты, USD. Подписанные HMAC-вебхуки сеттлят прямо из подписанного
тела — без повторного запроса к API. Чистый HTTP, без SDK. Заказы ниже
$0.50 отклоняются до оплаты. - TON — он-чейн переводы. Покупатель получает адрес кошелька, точную сумму
в нанотонах и обязательный memoorder-<id>(deeplinkton://заполняет всё
сам). Поллер разбирает переводы по memo; settle терпителен к переплате
(в ledger пишется фактически полученное), недоплата — в карантин. Курс
фиксируется на заказе и никогда не переоценивается задним числом. - NOWPayments — 300+ монет. Hosted-инвойсы, settle по подписанному
HMAC-SHA512 IPN с канонизацией тела.⚠️ Перед включением в проде — один
живой тестовый платёж для подтверждения канонизации (проверка fail-closed:
при расхождении настоящие IPN отклонятся, но подделка никогда не пройдёт).
Подписки остаются Stars-only — осознанно.
🛡 Деньги, которым можно доверять
- Барьеры дurable-обработки. ACK вебхука и продвижение offset polling'а —
только после settle или durable-карантина: повторные доставки провайдера не
теряют и не дублируют платежи. - Карантин вместо догадок. Несовпадающие/битые/неожиданные факты — в очередь
на разбор, не в заказы; поведение каждого рельса задокументировано по
классам причин вdocs/payment-operations.md. - Неизменяемый ledger. Захваты, возвраты, аномалии и резолюции —
append-only; каждая новая строка теперь несёт durableactor(миграция 023):
кто записал —webhook:<провайдер>,worker:<провайдер>,admin:<id>или
CLI-оператор.
🧾 Платёжные операции для админов
/refund <заказ> [сумма]— возвраты с preview→confirm: при подтверждении
ledger перепроверяется заново (защита от гонок). Сначала провайдер, потом
запись; сбой между ними — восстановим, двойной тап — no-op, повторный возврат
по балансу кредитует ровно один раз. Stars, Stripe, YooKassa и баланс
исполняются в боте; crypto/TON/NOWPayments честно ведут в кабинет провайдера./payreview— очередь карантина в чате: карточка на случай, коды причин
и actor по каждой цели, кнопки только те, что ledger реально примет (мёртвых
кнопок больше нет; неоднозначное — в CLI).- CLI
payment-review— list/preview/resolve +ingest-stars/
ingest-providerс дисциплиной preview-then---apply; TON-перевод без memo
теперь разрешим привязкой к заказу. /paystatus— по строке на рельс: настроен или нет, курсы, какие вебхуки
зарегистрировать — без печати секретов.
🛠 Управление магазином
- Полная админка: товары, категории, фото, промокоды, стили кнопок
(/btnstyle), карточка заказа (/order <id>),/setbalanceс аудитом. - Оплата балансом — синхронный чекаут с идемпотентным списанием через тот
же защищённый путь, что и внешние рельсы.
🔍 Наблюдаемость
- Каждое обновление Telegram обрабатывается в едином per-update контексте
(30 секунд, отменяется при shutdown) сtrace_idво всех логах цепочки —
путь события собирается однимgrep trace_id=<id>. - Логи settle/refund несут структурированное поле
actorнасквозь.
⬆️ Заметки по обновлению
- Сделайте бэкап базы перед первым запуском. Миграции 017–023 применяются
автоматически и только добавляют; ledger неизменяем, поэтому колонкаactor
пишется один раз на входе — у строк до обновления останется NULL («не
записано»), это by design. - Новые необязательные переменные окружения:
YOOKASSA_*+ `USD_TO_RUB_RA...
v3.0.1
Changelog
- f235959: feat(release): add Windows amd64 and arm64 archives (@JumpCodeFrog)
- 2cb5649: feat(release): expose SHA-256 checksums and verification guide (@JumpCodeFrog)
- 563bd3d: fix(ci): preserve coverage arguments on Windows (@JumpCodeFrog)
- 7aedb7c: fix(v3.0.1): correct checkout totals and SQLite payment operations (@JumpCodeFrog)
SHA-256 verification
Download checksums.txt and your archive from this release. Verify the
archive before extracting or running it. SHA-256 checks file integrity;
it is not a digital signature of the author.
Windows (PowerShell):
Get-FileHash -LiteralPath .\telegram-shop-bot_3.0.1_windows_amd64.zip -Algorithm SHA256Compare the hash with the line for that exact filename below or in
checksums.txt (case does not matter). Use windows_arm64.zip for ARM64.
Linux (run in the folder containing the archive and checksums.txt):
sha256sum --check --ignore-missing checksums.txtYour downloaded archive must report OK. Do not use a file that fails verification.
d9d59523789163d04b6ba651d5d1457cba2fc20eac88cd9390fd61a829436684 telegram-shop-bot_3.0.1_linux_amd64.tar.gz
d571fd6aa3205d6ac7be10c2f005c2a5397da90b63157e5e062327b26a8aeb92 telegram-shop-bot_3.0.1_linux_arm64.tar.gz
bb80ab8bf681fe1e4b10521d516f5a95205ff55b682305de41f5146e336066b1 telegram-shop-bot_3.0.1_windows_amd64.zip
32b3b801d2e9be3e4420210b9d6e97ba2c37b934fe83cf2c8b171a39415aa4b2 telegram-shop-bot_3.0.1_windows_arm64.zip
Docker
docker pull ghcr.io/jumpcodefrog/telegram-shop-bot:v3.0.1Quick Start
Download the archive for your operating system and processor: amd64 for
Intel/AMD PCs, or arm64 for ARM devices. Extract the entire archive and
open a terminal in that folder; keep locales/ next to the executable.
Go, Make, and Docker are not required for the downloaded binary.
Windows (PowerShell):
.\telegram-shop-bot.exe quickstartLinux:
./telegram-shop-bot quickstartThe guided setup asks for the BotFather token and your Telegram user ID,
validates them, creates .env, runs diagnostics, and starts the shop.
See Getting Started for source and Docker paths.
v3.0.0
Telegram Shop Bot v3.0.0
One guided command to launch. A durable payment core when money gets complicated.
v3 makes the shop dramatically easier to start and makes Telegram Stars and CryptoBot payments deterministic, auditable, and recoverable.
🚀 One-command setup
- Run
telegram-shop-bot quickstartand answer only two questions: the BotFather token and your Telegram admin ID. - The initializer validates the bot with Telegram, derives
BOT_USERNAME, creates.envatomically without overwriting an existing file, and applies private permissions on Unix. - New
doctordiagnostics check configuration, SQLite migrations, optional Redis, Telegram identity, webhook state, and pending updates without exposing secrets. init,doctor,quickstart,run,version, andhelpship in the same binary. Running the binary without arguments remains compatible with previous releases.
💳 Durable commerce ledger
- Order, payment, and fulfillment now have independent states instead of sharing one overloaded order status.
- Captures, refunds, anomalies, payment attempts, and operator resolutions are stored in append-only timelines.
- Provider ID, payer, amount, currency, and occurrence time are validated before settlement.
- Exact replays remain idempotent: stock, loyalty rewards, referrals, and subscription access are not applied twice.
- Telegram webhook and polling acknowledgements wait until every Stars charge is either settled or durably quarantined.
- Recurring Stars payment and entitlement updates commit atomically; refunds revoke or roll back access consistently.
🧰 Guarded payment operations
reconcile-starsperforms a bounded, read-only comparison between Telegram and the local ledger.payment-reviewlists quarantined Stars and CryptoBot facts with redacted output.- Recovery is preview-first and requires explicit
--applyplus exact order confirmation. - Revenue analytics now separates gross captures, refunds, and net revenue.
🔐 Webhook and CryptoBot hardening
WEBHOOK_URLis now the public base URL. Telegram uses/telegram-webhook; CryptoBot uses/cryptobot-webhook.- Every public Telegram webhook requires a strong
TELEGRAM_WEBHOOK_SECRET, regardless of application mode. - CryptoBot now uses exact decimal conversion, provider occurrence timestamps, durable malformed-fact preservation, and mutable-head-safe pagination.
- Transient SQLite lock conflicts are retried through a bounded settlement path.
- Startup transport errors are sanitized so BotFather tokens do not appear in logs.
⚠️ Upgrade notes
- Create a verified SQLite backup before the first v3 start.
- Migrations
017_commerce_ledger.sqland018_provider_fact_immutability.sqlapply automatically. - Set
WEBHOOK_URLto the HTTPS base URL only; remove old/webhook/...suffixes. - When webhook mode is enabled, configure a 32–256 character
TELEGRAM_WEBHOOK_SECRET. - Forks calling the Go payment service directly should migrate to
ConfirmPaymentReceiptwith a validated provider receipt. - Monitor the first live recurring Stars renewal after upgrading.
Docker
docker pull ghcr.io/jumpcodefrog/telegram-shop-bot:v3.0.0Quick start
./telegram-shop-bot quickstartTelegram Shop Bot v3.0.0 — по-русски
Одна команда для запуска. Надёжный платёжный контур для реальных денег.
🚀 Проще начать
telegram-shop-bot quickstartспрашивает только BotFather-токен и Telegram ID администратора, проверяет их, создаёт приватный.env, запускает диагностику и магазин.- Новый
doctorпроверяет конфигурацию, SQLite, Redis, Telegram и webhook без вывода секретов. - Все команды находятся в одном бинарнике; запуск без аргументов работает как раньше.
💳 Платежи под контролем
- Состояния заказа, оплаты и исполнения разделены.
- Captures, refunds, anomalies и решения оператора сохраняются в неизменяемом журнале.
- Повтор одного платежа не списывает товар, не начисляет бонусы и не продлевает подписку второй раз.
- Stars webhook и polling подтверждают update только после сохранённого settlement или quarantine.
- Оплата подписки и выдача доступа проходят атомарно; возврат корректно отзывает доступ.
- Аналитика показывает gross, refunds и net revenue отдельно.
🧰 Восстановление без опасной автоматики
reconcile-starsвыполняет только чтение и сверку с Telegram.payment-reviewпоказывает спорные операции без секретов и требует preview,--applyи точное подтверждение заказа.- CryptoBot получил точные суммы, provider timestamps и пагинацию без пропуска новых оплаченных инвойсов.
⚠️ Перед обновлением
- Сделайте проверенный бэкап SQLite.
- Миграции
017и018применятся автоматически. - Укажите в
WEBHOOK_URLтолько базовый HTTPS URL. - При webhook-режиме задайте сильный
TELEGRAM_WEBHOOK_SECRETдлиной 32–256 символов. - Проверьте первое живое продление Stars после обновления.
Полный список изменений: CHANGELOG.md.
v2.0.0
Telegram Shop Bot v2.0.0
The biggest release yet: two waves of critical payment fixes, a revived loyalty & referral economy, product reviews, photo galleries, Stars subscriptions, an embedded Telegram Mini App, and full five-language i18n — verified by a new end-to-end test suite running the whole buyer journey against a mock Bot API.
🔴 Critical fixes
- False payment confirmation — the CryptoBot polling worker marked unpaid (
active) invoices as paid every 30 s, confirming orders and draining stock without money. Now onlystatus == "paid"invoices are processed. - Unvalidated Stars pre-checkout — payments were approved after merely parsing the payload. The bot now verifies the order exists, belongs to the payer, is
pending, and the invoice amount matches. - Subscriptions were never persisted — a wrong FK in migration 014 made every subscription insert fail (found by the E2E suite; fixed in migration 016).
- Referral links never attached the referrer —
SetReferreraddressed the wrong column (found by the E2E suite). - Stock check ignored quantity — buying 10 units with 1 in stock passed checkout and then failed inside payment confirmation, causing endless webhook retries. Idempotent webhook replies (HTTP 200 on repeats) end CryptoBot retry storms for good.
- Cashback no longer loses points to float truncation; graceful shutdown drains all workers before closing the DB; SQLite runs in WAL with busy_timeout; backups use
VACUUM INTO(no externalsqlite3binary — works in Docker) with keep-7 rotation.
✨ New features
- Loyalty & referrals actually work: 1–10 % cashback in points on every paid order (all three payment paths), level upgrades, referrer gets 100 pts for an invited user's first purchase, the newcomer gets a personal one-off
REF-…promo (−10 %, 30 days). Race-proof: a concurrent double confirmation awards exactly once (property-tested). - Product reviews & ratings — 1–5 ⭐ invitation after delivery, optional text, average rating on the product card, admin moderation via
/reviews. - Photo upload & galleries — admins send photos straight to the chat (up to 10 per product), buyers get a media-group gallery.
- Stars subscriptions — 30-day recurring products,
/mysubswith one-tap cancel, expiry worker with reminders. Recurring renewals are mock-verified only — watch the first live renewal. - Telegram Mini App — catalog → cart → checkout in a web app embedded into the binary (no build toolchain), REST API with Telegram
initDataHMAC auth. SetWEBAPP_URLto enable. - Redesigned main menu — dense two-column colored layout;
/searchand/wishlistare fully interactive now. - Admin analytics — 14-day revenue chart, top-10 buyers, promo report, date-filtered CSV export; all five Prometheus metrics live with refreshed Grafana panels.
- Forum-topic admin notifications — route order events to supergroup topics via
ADMIN_GROUP_ID/TOPIC_*. - Full i18n — 5 languages everywhere including the admin panel; regional tags (
ru-RU,zh-hans) resolve correctly; es/de/zh translations completed.
⚠️ Breaking changes
OrderService.ConfirmPaymentnow returns(*PaymentOutcome, error); worker constructors changed signatures.- Default fallback language is English (was Russian).
- WAL mode adds
-wal/-shmfiles next to the database; copy backups viaVACUUM INTO, notcp.
Migrations 012–016 apply automatically on startup — both clean installs and v1.x upgrades are tested.
Telegram Shop Bot v2.0.0 (RU)
Самый большой релиз: критические фиксы платежей, работающие лояльность и рефералка, отзывы, галереи фото, подписки Stars, встроенный Mini App и полный перевод на 5 языков — всё проверено новым E2E-набором, прогоняющим полный путь покупателя на mock Bot API.
🔴 Критические исправления
- Ложное подтверждение оплаты — поллинг CryptoBot каждые 30 с помечал неоплаченные инвойсы оплаченными и списывал склад. Теперь обрабатываются только
paid. - Stars pre-checkout без проверок — теперь проверяются заказ, владелец, статус и сумма.
- Подписки не сохранялись (битый FK, миграция 016) и рефералы не привязывались — оба бага найдены E2E-тестами.
- Проверка остатка не учитывала количество — плюс идемпотентный вебхук: конец бесконечных ретраев CryptoBot.
- Кэшбэк больше не теряет баллы на округлении; graceful shutdown дожидается воркеров до закрытия БД; SQLite в WAL; бэкапы через
VACUUM INTO(работают в Docker) с ротацией 7 шт.
✨ Новое
- Лояльность и рефералка работают: кэшбэк 1–10 % баллами, уровни, рефереру 100 баллов за первую покупку приглашённого, новичку персональный промокод
REF-…(−10 %, 30 дней). Гонки исключены property-тестом. - Отзывы и рейтинги, загрузка фото в чат + галереи, подписки Stars (
/mysubs, отмена, напоминания; продление проверено только на моках), Mini App (WEBAPP_URL), новое 2-колоночное меню, живые/searchи/wishlist, аналитика админки с графиком и CSV по датам, Topics-уведомления, полный i18n на 5 языках включая админку.
⚠️ Ломающие изменения
ConfirmPaymentвозвращает(*PaymentOutcome, error); изменились конструкторы воркеров.- Язык по умолчанию — английский (был русский).
- WAL добавляет файлы
-wal/-shm; бэкапы — толькоVACUUM INTO, неcp.
Миграции 012–016 применяются автоматически: чистая установка и апгрейд с v1.x протестированы.
Полный список изменений — в CHANGELOG.md.
v1.2.0
Changelog
- 08ae8f2: fix(release): set CGO_ENABLED=0 for cross-compilation (arm64) (@JumpCodeFrog)
- 4a7bc57: fix(release): use slim Dockerfile.release for GoReleaser Docker builds (@JumpCodeFrog)
- 422f4d4: fix: resolve golangci-lint warnings (errcheck, unused, staticcheck) (@JumpCodeFrog)
- c20479e: release: v1.2.0 — UX overhaul, colored buttons, admin customization (@JumpCodeFrog)
Docker
docker pull ghcr.io/jumpcodefrog/telegram-shop-bot:v1.2.0Quick Start
cp .env.example .env
# fill in BOT_TOKEN and ADMIN_IDS
docker compose up -dSee Getting Started for the full guide.