How a 'Simple' Telegram Bot Turned Into a Full Payment System
Software Engineer and Technical writer
I was busy working on a usage-based billing platform—the kind where you calculate cost based on video duration, file size, bandwidth, and other metrics that make your brain sweat. Still on it.
Then my friend called.
"Bro, can you help me build a simple Telegram bot? Just something small."
In tech, "simple" is a myth. Like "just one more episode." But it was the weekend. I needed a break. I said:
"Sure, what could go wrong?"
By mid-week, the so-called "simple bot" was processing live cryptocurrency payments, activating user subscriptions, verifying webhooks, and maintaining real-time state across concurrent users.
And the wild part?
In less than a week, it processed more than $1,000+ in real subscription payments. Zero duplicate payments, zero lost data, zero panics.
What Made It Interesting
Users were messaging the bot like:
/subscribe → pick plan → pay → wait → get activated
But behind that flow was a complex web of engineering problems that I had to solve in real-time.
Problem 1: Multiple Users Doing Subscription Flow at the Same Time
Users can select plans, generate invoices, and submit payments—all at once.
Without proper concurrency control, that meant:
- Duplicate invoices
- Sessions overwrite each other
- Subscriptions activating twice
Engineering move: Built a thread-safe session manager using a read/write lock with sync.RWMutex.
- Reads are concurrent
- Writes are exclusive
- No collisions
- Must not have duplicated state
Result: Every user gets their own isolated "bubble" of logic throughout the subscription flow.
Problem 2: Crypto Payment Webhooks Are Chaotic
Payment gateways send webhooks like:
- Once, twice, or multiple times
- Or never (depending on mood)
If we process a webhook twice → same user gets double subscription time. If we trust it blindly → any random JSON can activate a paid plan.
The Solution: Webhook handler with signature verification, idempotency, and ACID database transaction.
- Verify cryptographic signature (reject spoofed payments)
- Validate that the amount matches the invoice
- Run DB updates inside a transaction
- Mark invoice paid, activate subscription, commit only if everything succeeds
Result: No double activation. No lost payments. Money comes in → subscription gets activated exactly once.
Problem 3: Database Failures Happen
Network hiccups, connection exhaustion—PostgreSQL can timeout without warning. If the system panics here, people lose money.
Engineering move:
- Automatic retry with exponential backoff + jitter
- Circuit breaker if DB keeps failing
Result: The bot remains online even if the database goes offline.
Problem 4: Sessions Need to Clean Up After Themselves
Users start paying, get distracted, and disappear. If we don't manage the session lifecycle:
- Memory leaks
- Zombie sessions
- Abandoned states
Solution: Background goroutine that periodically removes stale sessions.
Result: No leaks. No accumulation. System stays lightweight.
Problem 5: User Experience Must Be Fast
Telegram expects responses in under 30 seconds. Realistically, users expect less than a second.
Optimizations:
- Connection pooling
- Caching exchange rates
- Preparing SQL statements
- Async cleanup jobs
Results (In One Week)
Real payments processed: $1,000+ already, with much more to come.
Not bad for "just a Telegram bot".
What I Learned
- A weekend project can turn into a mini payment orchestration system
- Resilience isn't an afterthought—it's built for failure from day one
- The difference between a hack and engineering is predictable behavior
Want to see the architecture behind this system? Check out my Process page for detailed diagrams and implementation patterns.
