Where the cost actually comes from
Before optimizing anything, separate the two charges that ride on a crypto payment, because they behave nothing alike. The first is the on-chain network fee — gas on an EVM chain, a transaction fee on Bitcoin, a tiny lamport charge on Solana. It is paid to the validators or miners that include your transaction, it is set by the chain and by how congested it is right now, and no payment provider controls it. The second is whatever commercial arrangement you have with halfin, which this guide deliberately does not put numbers on. The lever this guide pulls is the first one: the network charge.
The network fee is a property of the chain, not of the asset. "USDT is expensive" is the wrong mental model — USDT on Ethereum carries Ethereum's gas cost, the very same USDT on Tron carries Tron's much smaller transaction cost, and on Solana it carries Solana's near-trivial cost. The dollar moving is identical; the rail it rides on is what you are paying for. That single insight is most of the savings in this guide: you are not changing what you send, you are changing where you send it.
Fees also move with congestion. Ethereum gas spikes when the network is busy and falls when it is quiet; Bitcoin's fee market does the same. Lower-fee chains like Tron, Solana, and Base stay cheap precisely because they have headroom, so they are not just cheaper on average — they are far more predictable, which matters as much as the absolute number when you are budgeting a payout run.
- The on-chain network fee is set by the chain, not by halfin — it is the charge you can actually influence.
- The fee is a property of the network, not the asset: the same USDT costs very differently on Tron, Ethereum, and Solana.
- Busy chains (Ethereum, Bitcoin) have volatile fees; lower-fee chains (Tron, Solana, Base) are both cheaper and steadier.
- Routing onto the right network and sending fewer transactions are the two levers you control.
Lever 1 — Route each payment onto the network that fits
The single biggest win is choosing the right network for the asset, and the strongest case is stablecoins, because the very same token exists on several chains. USDT runs on Tron (TRC-20), Ethereum (ERC-20), and Solana; USDC runs on Ethereum (ERC-20), Base, and Solana. A dollar of USDT is a dollar on any of them — so when on-chain cost matters, prefer the lower-fee rail your counterparty can actually receive on. Tron TRC-20 and Solana are the low-cost defaults for stablecoins; Base is the low-cost EVM option for USDC.
Route by what the recipient holds, not by a blanket rule. A network is only cheap if the destination address can receive on it — sending USDT on a chain a wallet cannot accept does not save a fee, it strands the payment. Many traders and exchanges favor TRC-20 USDT for exactly the cost reason in this guide; an EVM-native or US-facing counterparty may prefer USDC on Base; a recipient already on Solana settles fastest and cheapest there. Let the addressable network drive the choice per payment.
Native-asset payments do not get a network swap — BTC settles on Bitcoin, ETH on Ethereum — but you still get a choice on where you accept value in the first place. If a customer can pay in USDC on Base instead of ETH on mainnet, or in SOL instead of an ERC-20, you have moved the cost onto a cheaper rail without changing the dollar amount. With halfin invoicing, the fiat-anchored amount is identical no matter which supported asset and network the payer chooses, so steering toward a cheaper rail costs you nothing on the booked figure.
| Asset | Lower-cost networks | Higher-cost network | When the cheaper rail fits |
|---|---|---|---|
| USDT | Tron (TRC-20), Solana | Ethereum (ERC-20) | Counterparty can receive TRC-20 or SPL — common for traders, exchanges, and payout recipients. |
| USDC | Base, Solana | Ethereum (ERC-20) | EVM-native payers who hold or can bridge to Base; recipients already on Solana. |
| ETH / ERC-20 tokens | Base, Arbitrum, Polygon (L2s) | Ethereum mainnet | Accept value on an L2 when the payer can pay there instead of mainnet. |
| Native assets | Solana (SOL), XRP | Bitcoin (BTC) | Steer optional payments toward fast, low-fee native rails where the customer is flexible. |
Lever 2 — Send fewer transactions
Every on-chain transaction carries its own network fee, so the second lever is simply making fewer of them. The clearest case is payouts. A mass payout in halfin is a fan-out: there is no /payouts/batches endpoint, so you loop POST /api/v1/payouts once per recipient, and every line that executes is its own on-chain transaction with its own network charge. That means the way you structure the run has a direct cost.
Consolidate where the logic allows. If the same recipient is owed several amounts in one cycle — a commission and a bonus, two invoices, three line items — paying them as one payout of the summed amount is one transaction and one network fee, instead of three. You still keep a per-line idempotency_key so a re-run never double-pays, but you reduce the count of payments that actually hit the chain. Do not over-consolidate across recipients, though: each distinct destination address is necessarily its own transaction, because a single transaction pays a single address.
Timing helps on the volatile chains. Where a payout is not time-critical and rides a chain with a real fee market — Ethereum mainnet or Bitcoin — running the batch during a quieter period costs less than firing it into peak congestion. On Tron, Solana, and Base this matters far less because the fee is already low and stable, which is itself a reason to prefer those rails for high-volume runs. The cheapest transaction is still the one you do not send: net out internal transfers in your own ledger and only settle the on-chain difference.
- Each payout line is its own on-chain transaction with its own network fee — fewer lines, lower total cost.
- Sum multiple amounts owed to one recipient into a single payout instead of several.
- You cannot merge payments to different addresses — one transaction pays one destination.
- On fee-volatile chains (Ethereum, Bitcoin), run non-urgent batches during quieter periods.
Worked example — a payout run that costs less
Put both levers together on a real shape: you owe 200 affiliates this cycle, you currently send everyone USDT on Ethereum, and your costs are uncomfortable. Two changes, neither of which touches the dollar amounts, cut the on-chain charge sharply: move recipients who can receive TRC-20 or SPL onto Tron or Solana, and collapse any recipient owed multiple amounts into one payout each.
The migration is per recipient, not all-or-nothing. Capture which network each address can accept, default everyone who can to a low-fee rail, and leave the few who genuinely need ERC-20 on Ethereum. The currency field on each payout line names the asset and network, so the same loop sends one line on Tron, the next on Solana, the next on Ethereum — the rail is data, not a code branch. Keep amounts as strings and give every line a deterministic idempotency_key so re-running the file after a failure never pays anyone twice.
The example below fans out one such run. Two of the three lines settle on low-fee rails; the third stays on Ethereum because that recipient can only receive ERC-20. The booked amounts are unchanged — you have moved cost off the expensive chain without renegotiating a single payment.
# One payout run, mixed networks. The cheaper rails (TRC-20, Solana) carry
# the same dollars at a fraction of Ethereum's on-chain fee. There is no
# batch endpoint — you loop POST /api/v1/payouts once per recipient.
# Recipient on Tron — low-fee USDT (TRC-20)
curl -sS -X POST https://api.thehalfin.com/api/v1/payouts \
-H "Content-Type: application/json" \
-H "X-API-Key: $HALFIN_PAYOUTS_API_KEY" \
-d '{
"currency": "USDT_TRC20",
"amount": "250.00",
"destination": "TR0nDe5t1nat10nAddre55xxxxxxxxxxxxx",
"idempotency_key": "acct_4821:payout-2026-06"
}'
# Recipient on Solana — low-fee USDT (SPL)
curl -sS -X POST https://api.thehalfin.com/api/v1/payouts \
-H "Content-Type: application/json" \
-H "X-API-Key: $HALFIN_PAYOUTS_API_KEY" \
-d '{
"currency": "USDT_SOL",
"amount": "180.00",
"destination": "So1anaDe5t1nat10nAddre55xxxxxxxxxxxx",
"idempotency_key": "acct_5530:payout-2026-06"
}'
# Recipient who can only receive ERC-20 — stays on Ethereum
curl -sS -X POST https://api.thehalfin.com/api/v1/payouts \
-H "Content-Type: application/json" \
-H "X-API-Key: $HALFIN_PAYOUTS_API_KEY" \
-d '{
"currency": "USDT_ERC20",
"amount": "420.00",
"destination": "0xErc20Destinati0nAddre55xxxxxxxxxxxxxxxxxx",
"idempotency_key": "acct_6107:payout-2026-06"
}'
# Re-running the whole file after a failure is free: keys collide,
# already-created payouts come back unchanged. See docs.thehalfin.com for
# the exact currency identifiers and the full request schema.What not to do to chase a lower fee
Cost optimization goes wrong the moment it overrides what the recipient can actually receive or what the payment needs to be. The failure that costs the most is sending an asset on a network the destination cannot accept — a TRC-20 transfer to an address that only handles ERC-20 does not arrive cheaper, it does not arrive at all, and now you are reconciling a stranded payment instead of saving a fee. Always validate the network against the destination before you let cost steer the choice.
Do not let a cheaper rail erode the guarantees you actually rely on. halfin credits payments reorg-aware and waits for each chain's confirmation threshold before marking them settled, so a low-fee chain is not a low-assurance one — but that also means you should not invent your own shortcut, like acting on a first-seen transaction to feel faster. The confirmation behavior is part of why the credit is one you can trust; let it run.
Finally, keep the optimization where it belongs. Picking a network and batching transactions is a sound, durable way to manage on-chain cost. Chasing a marginally cheaper rail by pushing a customer onto a chain they do not use, or by holding a time-sensitive payout for a quieter fee window it cannot wait for, trades a small saving for a support ticket. Optimize the cost you control without compromising delivery, finality, or the recipient's experience.
- Never send an asset on a network the destination can't receive — a stranded payment is the most expensive outcome.
- Don't shortcut confirmations to feel faster; reorg-aware crediting and per-chain thresholds are what make the credit trustworthy.
- Don't force a customer onto a chain they don't use just to save a fee.
- Don't hold a time-critical payout for a cheaper fee window it can't wait for.