*Last updated: July 2026*
Building a Telegram bot that accepts cryptocurrency payments is easier than you think. In this guide, we'll walk through creating a production-ready bot that handles Bitcoin and Monero payments automatically.
Telegram has 800M+ monthly active users, and crypto payments are borderless with near-zero fees. Combining them gives you:
import requests
import json
from datetime import datetime
BOT_TOKEN = "YOUR_BOT_TOKEN"
API_BASE = f"https://api.telegram.org/bot{BOT_TOKEN}"
def send_message(chat_id, text):
"""Send a message to a Telegram chat."""
url = f"{API_BASE}/sendMessage"
data = {
"chat_id": chat_id,
"text": text,
"parse_mode": "Markdown"
}
return requests.post(url, json=data).json()
For Bitcoin, use a new address for each payment to track transactions:
import hashlib
import time
def generate_payment_id(user_id, product_id):
"""Generate a unique payment ID."""
raw = f"{user_id}-{product_id}-{int(time.time())}"
return hashlib.sha256(raw.encode()).hexdigest()[:16]
def get_btc_address(payment_id):
"""In production, use a wallet API like Blockstream or BTCPay."""
# For demo, return a static address
return "your_btc_address_here"
Check the blockchain for incoming transactions:
def check_payment(address, expected_amount):
"""Check if payment was received via blockchain API."""
url = f"https://blockstream.info/api/address/{address}/utxo"
try:
resp = requests.get(url, timeout=10)
if resp.status_code == 200:
utxos = resp.json()
total = sum(utxo.get("value", 0) for utxo in utxos)
expected_sats = int(expected_amount * 100_000_000)
return total >= expected_sats
except Exception as e:
print(f"Payment check error: {e}")
return False
def handle_buy_command(chat_id, user_id, product_id):
"""Process a /buy command."""
payment_id = generate_payment_id(user_id, product_id)
btc_address = get_btc_address(payment_id)
message = f"""
๐ *Purchase Request*
Product: {product_id}
Payment ID: `{payment_id}`
Amount: 0.001 BTC
Send exactly 0.001 BTC to:
`{btc_address}`
โฑ Payment expires in 24 hours.
After payment, use /status {payment_id} to check.
"""
send_message(chat_id, message)
Once payment is confirmed, deliver the product automatically:
def deliver_product(chat_id, product_id):
"""Deliver product after payment confirmation."""
# In production, this would:
# 1. Generate download link
# 2. Send it to the user
# 3. Log the transaction
message = f"""
โ
*Payment Confirmed!*
Your product `{product_id}` is ready.
Download your files here:
https://your-domain.com/download/{product_id}
Thank you for your purchase!
"""
send_message(chat_id, message)
1. Use a proper wallet: Don't reuse addresses. Use a wallet API like BTCPay Server or Blockstream Green.
2. Handle confirmations: Wait for 1-3 blockchain confirmations for large amounts.
3. Store payment state: Use a database to track payments, not just memory.
4. Add error handling: Network requests fail. Always handle timeouts and errors.
5. Monitor your bot: Set up logging and alerts for failed payments or deliveries.
Here's a minimal but complete bot:
import requests
import json
import time
from pathlib import Path
BOT_TOKEN = "YOUR_TOKEN"
API = f"https://api.telegram.org/bot{BOT_TOKEN}"
PAYMENTS_FILE = Path("payments.json")
def load_payments():
if PAYMENTS_FILE.exists():
return json.loads(PAYMENTS_FILE.read_text())
return {}
def save_payments(payments):
PAYMENTS_FILE.write_text(json.dumps(payments, indent=2))
def send(chat_id, text):
requests.post(f"{API}/sendMessage", json={
"chat_id": chat_id, "text": text, "parse_mode": "Markdown"
})
def check_btc(address):
resp = requests.get(f"https://blockstream.info/api/address/{address}/utxo", timeout=10)
return sum(u["value"] for u in resp.json()) > 0
# Bot logic would go here...
Don't want to build it yourself? We have a complete, tested Telegram bot with crypto payments at [our store](https://petroleum-board-hawaii-lol.trycloudflare.com).
What you get:
[Browse the collection โ](https://petroleum-board-hawaii-lol.trycloudflare.com)
Browse 120+ Python tools with crypto payments and instant delivery.
Browse Products โ