Guides · updated 2026-11-05

How to accept USDT (TRC-20) on your website without a payment processor

You don't need a gateway to take USDT. You need a TRON address you control, a way to tell which order a transfer belongs to, and a handful of rules for the cases that go wrong. Here is all of it.

Why people skip the processor

Hosted crypto gateways charge 0.5–1% per payment, hold your funds until payout, and usually want a merchant account with KYC. If your customers already pay in USDT, and many in markets without Stripe or PayPal do, the processor adds cost and an account that can be closed without adding anything you can't do yourself. A TRC-20 USDT transfer settles in about a minute and costs the sender a fixed amount of TRX, not a percentage.

The core problem: which order is this payment for?

On TRON, a USDT transfer carries a sender, a recipient and an amount. There is no memo field your customer will reliably fill in. With one receiving address, the only signal you control is the amount. So give every order a unique one: for a $12 product, ask for 12.0371 USDT on one order and 12.4410 on the next.

// 9,900 possible amounts per price point; never hand out one that is pending,
// or that expired in the last 24 hours (a late payer may still send it)
const base = Math.round(priceUsd * 1_000_000);          // USDT has 6 decimals
const candidate = base + randomInt(100, 10_000) * 100;   // 12.0100 … 12.9999

Then poll TronGrid for confirmed incoming transfers of the USDT contract (TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t) to your address and match by exact amount:

GET https://api.trongrid.io/v1/accounts/{address}/transactions/trc20
    ?only_to=true&only_confirmed=true
    &contract_address=TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t
    &min_timestamp={watermark}&order_by=block_timestamp,asc&limit=100

Two details that are easy to get wrong. First, TronGrid returns the newest transfers first by default; ask for block_timestamp,asc and keep a watermark of the last transfer you processed, or a burst of more than 100 transfers will silently skip the oldest. Second, keep polling even when no order is pending, or a payment that arrives after its order expired will never be seen.

The alternative, one fresh TRON address per order, removes the matching problem but means activating each address (about 1 TRX) and sweeping funds out of each one, which costs energy every time. For small shops the unique-amount approach is simpler and cheaper.

What a transfer actually costs your customer

A TRC-20 transfer burns about 65,000 energy when the recipient already holds USDT, and about 130,000 when it has never held any. Unless the sender has staked TRX for energy, it is paid in TRX at the network's current energy price, which puts it at roughly $2 and $4. Two practical consequences: receive into an address that already holds a little USDT, and don't sell anything under a few dollars in USDT. Our live fee comparer shows today's numbers next to Litecoin and Bitcoin, and the address checker tells you whether an address is in the cheap or the expensive case.

The cases that go wrong, and what to do

  • Exchange withdrawals that deduct the fee from the amount. The customer asks to send 12.0371 and you receive 11.0371. It won't match. Say on the checkout page that the amount must arrive exactly, and keep every unmatched transfer in a queue you can assign to an order by hand.
  • Late payments. Exchanges batch withdrawals; a payment can land an hour after your order expired. Record it as unmatched (don't ignore it), and don't reissue that amount to a new order for a day.
  • Paying twice. Mark each transaction id as processed. The second identical transfer should land in the unmatched queue, not be silently dropped and not deliver twice.
  • Freezes. Tether can blacklist addresses, and blacklisted USDT can't be moved. In 2025 it froze thousands of TRON addresses, mostly for receiving stolen funds. Keep your operating balance small and sweep to a separate address regularly.
  • Address poisoning. Scammers send dust from addresses that share the first and last characters of yours, hoping you copy the wrong one later. Never copy your own receiving address from transaction history.

Security checklist

  • The server needs only your public address. No private key belongs on it.
  • Rate-limit order creation, or someone can exhaust your 9,900 unique amounts with a script.
  • Generate license keys and download tokens with a cryptographic RNG, at least 80 bits.
  • If you notify your backend by webhook, sign the timestamp and body together and reject old timestamps.

Crypto Checkout does all of this for you: USDT TRC-20, Bitcoin and Litecoin straight to your wallet, MIT licensed, one Docker container. Try a $1 order or read the source.