Asset

Accept USDC on Ethereum (ERC-20)

Ethereum is where USDC started and where most institutional and EVM-native treasuries still keep their dollars. If a payer holds USDC on mainnet — in a MetaMask wallet, a hardware wallet, or alongside the rest of an on-chain treasury — accepting it as an ERC-20 token lets them pay you straight from where their funds sit, without bridging to a cheaper chain first. halfin accepts USDC on Ethereum, anchors the invoice to a fiat amount, and credits the dollar figure you billed to the same balance as every other rail. This page is specifically about the Ethereum (ERC-20) network; for the cross-network view, the USDC hub covers Base and Solana alongside it.

01

Who actually pays USDC on Ethereum

Ethereum was the first home for USDC, and a large share of the supply still lives there as an ERC-20 token. The customer who reaches for ERC-20 at checkout is usually EVM-native: they already operate on Ethereum, hold other ERC-20 assets in the same wallet, and would rather send from where their dollars sit than move money to another chain just to pay an invoice. For that payer, asking them to bridge to an L2 first is friction you do not want to introduce at the moment of payment.

There is a second, quieter reason ERC-20 shows up. Ethereum is the most broadly integrated network in the ecosystem, so a payer's existing tooling — custody, accounting, internal approvals — is often wired for Ethereum first. When a stablecoin transfer has to clear an internal process before it is sent, the chain that process already understands tends to win. Accepting USDC on Ethereum meets that payer where their operations already are, which is why it skews toward institutional and larger-ticket payments.

halfin treats this USDC exactly as it treats USDC on any other supported network: as a settlement asset, never a speculative position. USDC is a dollar-denominated stablecoin — one unit is intended to track one US dollar — and your invoice is anchored to the fiat amount, so any small live drift between the token and its peg is halfin's problem to map, not yours to absorb at reconciliation.

02

What ERC-20 means for the payment

ERC-20 is the token standard that USDC on Ethereum follows. In practice it means the payment is a standard token transfer on Ethereum mainnet, settled the way any ERC-20 movement settles, and confirmed on Ethereum's timescale. Crediting is reorg-aware: halfin waits for Ethereum's confirmation threshold before the invoice is marked paid, and reflects reorganizations rather than ignoring them, so a credit you see is a credit that survived.

The trade-off to name plainly is the network fee. Ethereum's gas cost is variable and, when the network is busy, can be meaningfully higher than the fee for the same transfer on Base or Solana. That fee is paid by the sender to the network, not to halfin, and it is a characteristic of the chain — not something the invoice changes. It is why ERC-20 tends to suit larger payments and EVM-native payers, while smaller everyday transfers often gravitate to a cheaper rail like Base. Surfacing more than one USDC network on an invoice lets the customer make that call themselves.

Because the amount is pinned to a fiat figure, none of this network detail leaks into your books. You reconcile against the dollar amount you billed; whether the customer paid USDC on Ethereum, Base, or Solana is a routing detail recorded on the invoice, not a separate ledger you have to keep.

03

USDC on Ethereum at a glance

The table sets the Ethereum (ERC-20) rail next to the other two networks halfin accepts USDC on, so you can see where it fits rather than reading it in isolation. The point is not that one rail is better — it is that the customer picks the one that matches where they hold the dollars and how much they are sending. The dollar value is identical across all three; only the rail differs.

NetworkToken standardBest fitNetwork fee character
EthereumERC-20EVM-native and institutional payers; larger transfers.Variable gas; higher when the network is busy.
BaseERC-20 (Base L2)Everyday and smaller-ticket dollar payments from EVM wallets.Low-cost settlement on an Ethereum L2.
SolanaSPLPayers already in the Solana ecosystem.Fast and low-fee settlement.
04

Fiat-anchored: bill in dollars, get paid in ERC-20 USDC

USDC is dollar-denominated, so the number on the invoice and the number on-chain are the same kind of number — but the two are not guaranteed to be exactly equal at every instant, which is precisely why halfin still anchors the invoice to fiat. You create an invoice with a fiat amount and currency; halfin maps that figure to the payable USDC amount and locks it when the invoice activates. The customer is shown one concrete USDC amount to send to their Ethereum deposit address, and your ledger records the dollar amount you billed.

Because the quote is pinned at activation rather than at draft time, the figure does not drift while the customer opens a wallet and confirms. This matters a little more on Ethereum than elsewhere: a busy network can slow a confirmation, and the locked amount holds for the invoice's window regardless. Each invoice carries an expiry — if the payment window elapses, the invoice expires instead of silently re-pricing, and you decide whether to re-issue. An underpayment is recorded against the invoice rather than stranded, and an overpayment is recorded the same way, so any difference between what was billed and what arrived stays visible and accountable.

05

Take an Ethereum USDC payment with one API call

Accepting USDC on Ethereum is not a network-specific integration — it is the same invoicing flow as every asset halfin supports. You post a fiat amount and currency to the public REST API with a scoped API key, and halfin returns a payable invoice you present through hosted checkout or render yourself. You do not pin the network when you create the invoice; the customer chooses USDC on Ethereum at the point of payment, and the EVM-native payer simply sends from the wallet they already use.

Below is a minimal create call. The amount is a string — monetary values are strings end to end, never floats — and the currency is your fiat anchor. The only request headers are X-API-Key and Content-Type. The idempotency_key field in the request body makes a retried request safe: the same key never creates a second invoice. Track the invoice through signed webhook events such as invoice.confirming and invoice.paid, and verify the HMAC signature before acting on any of them. The exact response fields live in the docs and the @halfin/sdk-merchant types.

curl -X POST https://api.thehalfin.com/api/v1/invoices \
  -H "X-API-Key: $HALFIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount_fiat": "250.00",
    "fiat_currency": "USD",
    "deferred": true,
    "description": "Invoice — USDC on Ethereum accepted",
    "idempotency_key": "00000000-0000-4000-8000-000000000002"
  }'

# halfin locks the rate at activation, pins the payable USDC amount, and
# returns an invoice the customer can settle as ERC-20 USDC on Ethereum
# mainnet. Watch invoice.confirming then invoice.paid via signed webhooks;
# verify the HMAC signature before acting. Full schema at docs.thehalfin.com.
06

After the payment clears

A paid ERC-20 USDC invoice accrues to the same dollar-anchored balance as the rest of your activity. From there the balance is not stuck on Ethereum: balance conversion lets you rebalance into another asset or onto another network as your treasury needs, so receiving on mainnet does not commit you to disbursing on mainnet. If you owe a stablecoin out — to a supplier, an affiliate, or a partner — single and mass payouts send USDC back out, and refunds handle the path back to a customer who is owed money.

Because the whole flow is fiat-anchored, USDC on Ethereum sits in the same ledger as USDC on Base and Solana, the USDT rails, and the native chain assets, all settled to the same dollar figures. Many merchants pair USDC for US and EVM-native payers with USDT for the regions and exchanges where it dominates — one fiat invoice covers both stablecoin audiences without a second integration. You get the broad reach and EVM-native familiarity of accepting USDC on Ethereum without inheriting a separate reconciliation pile for the rail.