DEV Community

sonu-dops
sonu-dops

Posted on

How to Accept USDT (TRC-20) in Telegram Bots Without Storing Private Keys (Zero-Custody Guide)

title
:
How to Accept USDT (TRC-20) in Telegram Bots Without Private Keys (Zero-Custody Guide)
published
:
true
description
:
Learn how to accept USDT (TRC-20) payments in Telegram bots without storing private keys on your server using TronGate API.
tags
:
telegram, python, web3, crypto
canonical_url
:
https://c2cdeal.store
How to Accept USDT (TRC-20) in Telegram Bots Without Private Keys (Zero-Custody Guide)

Monetizing a Telegram bot with cryptocurrency (especially USDT on TRON, due to low gas fees and massive global adoption) is one of the fastest ways to build profitable micro-SaaS bots.

However, almost every developer implements crypto payments in one of two flawed ways:

The Dangerous Way: Storing a wallet's private key / seed phrase on the server and using Python/Node libraries to sign sweep transactions. If your server is ever compromised, your entire wallet is drained.
The Expensive Custodial Way: Using commercial merchant gateways that charge 2%–5% transaction fees, require tedious KYC, and can freeze your account at any moment.

There is a third, much cleaner architecture: The Receive-Only Public Verifier Model.

🏗 The Architecture: Zero-Custody Verification

In this architecture, your bot never touches private keys.

text
Customer
│
▼
Telegram Bot (/buy)
│
▼
Calls TronGate API (/orders/create)
│
▼
Bot returns public TRON address & exact amount
│
▼
Customer sends USDT TRC-20 directly to YOUR personal wallet
│
▼
TronGate checks TRON Mainnet public blocks
│
▼
Webhook or /poll-verify returns { "status": "PAID" }
│
▼
Bot unlocks VIP access!
Why this works:
Zero Custody: Customer USDT goes directly from their wallet into your personal wallet.
Zero Key Risk: The agent or bot has no private key, no seed phrase, and cannot send funds.
Instant Finality: TRON finality takes ~3–10 seconds.
Replay Protected: Every transaction hash can only be credited once.
🛠 Step-by-Step Python Implementation
Step 1: Install Dependencies
bash
pip install requests python-dotenv
Step 2: Create a Payment Order

When a user runs /buy, call TronGate to generate a unique order:

python
import requests

TRONGATE_URL = "https://c2cdeal.store/api/v1"

def create_order(user_id: int):
response = requests.post(
f"{TRONGATE_URL}/orders/create",
json={
"amount_usdt": "5.0",
"metadata": {"telegram_user_id": user_id}
}
).json()

# Returns: order_id, amount_usdt, recipient_address, payment_uri
return response
Enter fullscreen mode Exit fullscreen mode

Step 3: Present Payment Info to User

Send the user your public TRON address:

python
async def buy_command(update, context):
user_id = update.effective_user.id
order = create_order(user_id)

msg = (
    f"💳 *Order Created ({order['order_id']})*\n\n"
    f"Please send exactly *{order['amount_usdt']} USDT (TRC-20)* to:\n"
    f"`{order['recipient_address']}`\n\n"
    f"Type /check after sending to unlock your membership!"
)
await update.message.reply_text(msg, parse_mode="Markdown")
Enter fullscreen mode Exit fullscreen mode

Step 4: Verify Payment On-Chain

When the user types /check (or when you receive an instant webhook callback):

python
def check_payment(order_id: str):
res = requests.post(
f"{TRONGATE_URL}/orders/poll-verify",
json={"order_id": order_id}
).json()

if res.get("status") == "PAID":
    # Payment is verified on TRON mainnet!
    unlock_vip_user(res["order_id"])
    return True
elif res.get("status") == "UNDERPAID":
    print(f"Customer sent insufficient USDT: {res.get('details')}")
    return False
else:
    print("Payment still pending on blockchain.")
    return False
Enter fullscreen mode Exit fullscreen mode

⚡ Clone the Full Starter Kit

We open-sourced a complete, ready-to-deploy Python Telegram bot with this exact flow: 👉 GitHub: trongate-telegram-bot-template

You can also test the live sandbox and inspect interactive Swagger docs for the TronGate API at: 👉 TronGate API Sandbox

Have you built a Telegram bot with crypto payments? What's been your biggest friction point? Drop a comment below!

Top comments (0)