"Which chain should I accept USDT on?" is the wrong question. The right one is: which chain did your customer already load their wallet on?
USDT is not one asset. It is the same dollar peg minted across a dozen chains, and the three that matter for acceptance are Tron (TRC-20), Ethereum (ERC-20), and Solana (SPL). They share a ticker and a price. They share almost nothing else that affects how a payment actually clears.
We support all three as first-class deposit rails, and we let the payer choose at checkout. This post is the reasoning behind that default, and the tradeoffs you inherit if you try to pick one for them.
The three USDT rails, side by side
The numbers below are habitual ranges, not promises. Networks move. But the shape of the difference is stable.
Each row is a different customer walking up to your checkout. The mistake is assuming they all want the rail you find convenient to reconcile.
Why TRC-20 dominates high-volume acceptance
If you watch where USDT actually moves in volume, Tron is the firehose. The reason is not technical superiority — it is liquidity and habit. The TRC-20 USDT pool is the deepest stablecoin pool in Southeast Asia, and the wallets people there use day to day, the major exchange apps and Tron-default consumer wallets, hand you a TRC-20 address the moment you ask to receive USDT.
For a merchant taking hundreds or thousands of small payments — top-ups, marketplace settlements, subscription renewals under a few thousand dollars — that combination is decisive:
- The fee is cents, so it does not eat the margin on a small ticket.
- Confirmation lands fast enough that you can credit the order while the customer is still on the page.
- The customer does not have to bridge or convert anything. Their balance is already TRC-20.
The fee gap is the part everyone quotes, but the habit is what actually wins. A payer who already holds TRC-20 USDT will pay on TRC-20. Offer them only ERC-20 and you have just asked them to bridge, eat gas twice, and wait — or abandon. Most abandon.
Where the other two earn their place
TRC-20 winning the volume does not make the other rails decoration.
ERC-20 is what institutional money speaks. If your counterparty custodies on Ethereum, is about to redeploy the funds into a DeFi position the same day, or is settling an amount large enough that a few dollars of gas is rounding noise, ERC-20 is correct and TRC-20 would be the friction. A six-figure settlement to a treasury does not care about gas. A $30 payment cares about everything.
SPL is the third quadrant: fast, effectively free, and increasingly the default for newer retail wallets in the US and EU. Confirmation is sub-second and fees round to zero, which makes it a strong fit for high-frequency, low-ticket flows where you would otherwise default to Tron but your audience skews toward Solana-native wallets.
The honest summary: TRC-20 is the high-volume default, ERC-20 is the institutional rail, SPL is the fast-retail rail. Few merchants live entirely in one quadrant.
So expose all three and let the payer pick
This is the part we feel strongly about. Do not hard-code a single USDT rail and call it a payments strategy.
When you create an invoice for USDT, you can anchor it in fiat — set amount_fiat and fiat_currency and let the rate lock at deposit — or fix it to a crypto amount directly. Either way, the invoice can present USDT on all three chains, and the customer selects the one their wallet already holds. The rate is locked, the expiry is enforced, and the underpaid / overpaid edges are handled the same way regardless of which chain the deposit lands on.
What the payer sees is a single choice: Tron, Ethereum, or Solana. What you get is the highest conversion, because nobody is being forced onto a rail they would have to bridge to reach. The settlement is the same dollar to you whichever chain it arrives on.
The trap is the opposite: you pick TRC-20 because it is cheapest, and six months in you discover that a meaningful slice of your customers hold USDT on Ethereum or Solana, hit your checkout, find no rail they can pay from, and leave. You did not save on fees. You lost the order.
What does not change across the three
The chain is a detail under the hood. The contract you build against stays the same:
- One invoice, one lifecycle. Whichever rail the deposit lands on, you receive the same events —
invoice.confirming, theninvoice.paid(orinvoice.underpaid/invoice.overpaidat the edges). Your code does not branch on the chain to know the order is settled. - Reorg-aware crediting. Each rail has its own confirmation depth before we mark an invoice paid. You do not tune that per chain; we do.
- Webhooks you verify the same way. Verify the HMAC signature over the raw bytes before you act, on every event, regardless of rail — the event envelope and signing scheme are documented at docs.thehalfin.com. (We wrote a whole post on why webhooks have to survive everything — the chain count does not change those rules.)
That uniformity is the point of accepting through infrastructure rather than wiring each chain yourself. The customer gets to pay the way they already pay. You get one integration and one event stream.
The operating rule
Accept USDT on Tron, Ethereum, and Solana. Make TRC-20 your mental default for high-volume, small-ticket acceptance — that is where the liquidity and the habit are — but never make it the only rail. Let the payer pick the chain their wallet is already on, and let the lifecycle look identical to your backend no matter what they choose.
If you want the deeper fee-and-settlement comparison between the two big rails, we broke it down in USDT on TRC-20 vs ERC-20. And the USDT asset page lists every chain we settle it on, with the confirmation behavior for each.
The rail is plumbing. We built the plumbing so your customer never has to think about it.