How to accept USDT (TRC20) payments on your website or bot
USDT on TRON is the most common way to pay in crypto in many regions: transfers are fast and cheap for the payer. This guide shows the minimal integration with ChainPay.
The model
- Your backend asks ChainPay for a deposit address for each order (or each user).
- The payer sends USDT to that address.
- After the network confirms the transfer, ChainPay sweeps it to your own wallet and calls your webhook.
You keep custody: the destination is your forwardAddress, and ChainPay does not hold a merchant balance.
One address per order or per user
- Per order: use a new
externalReferencefor every order. Easy reconciliation, one payment per address. - Per user: reuse the same
externalReferencefor a user. The address is permanent and can receive many deposits; this fits top-ups and balances.
Create the address
curl -X POST https://api.chainpay.site/deposit-address \
-H 'content-type: application/json' \
-d '{
"ticker": "trc20/usdt",
"callbackUrl": "https://shop.example.com/crypto-webhook?token=SECRET",
"forwardAddress": "TYourOwnTronWallet...",
"externalReference": "order-123"
}'
Handle the webhook
- Verify your
tokenquery value. - Match the payment by
externalReference. - Credit the order only on
status: "confirmed". - Make the handler idempotent: the same event may arrive more than once.
What the payer pays
Because every TRC20 transfer needs TRON Energy, the fee has a percentage part (1%) and a flat part priced at the live network cost. On TRON this flat part is roughly 4 USDT at current rates, so very small payments are not economical. Set a sensible minimum order amount. See Pricing for the current numbers.
Test it
Start with a small amount in the cabinet-attributed mode if you want to see the address in your account: register in the cabinet, create an API key and send the same request with x-api-key.