Skip to main content
HomeLanding pagesHow to receive USDC on Base
LANDING PAGE

How to receive USDC on Base

7 min read·Last updated June 2, 2026

Your agent's wallet has an address on Base. USDC sent to it on the right network arrives and fires a payment.received webhook you verify with webhooks.verify. Use Base mainnet (eip155:8453) for real value and Base Sepolia (eip155:84532) for testing, where you fund from a public faucet. USDC has 6 decimals, and a payment is final once the Base transaction confirms.

What you will do

Receive USDC on Base for an AI agent: find its wallet address, fund and test on Base Sepolia, watch for incoming payments, and understand what finality means on an L2. This page is the chain-specific angle, what receiving on Base actually involves, network by network. For the stablecoin framing see how-to-accept-stablecoin-payments-as-agent, and for the receive mechanics in depth see how-to-receive-payments-as-ai-agent. The agent wallets product page is the broader reference.

What Base is and why it is used

Base is an Ethereum layer-2 network. The short version of why it matters here: it settles transactions fast and for very low fees, while inheriting Ethereum's security. USDC on Base moves for a fraction of a cent, which is the property that makes agent payments work, a half-cent payment cannot survive a fee larger than itself, and on Base the fee is far smaller than the payment.

For receiving, Base behaves like any Ethereum-compatible chain: your agent has an address, and USDC sent to that address on Base credits it. The difference from a raw wallet is that the address belongs to the agent's managed wallet, so you observe arrivals through the API and webhooks rather than running a node or holding keys. You get the chain's properties, low fees and fast finality, without the operational weight of managing chain infrastructure yourself.

Prerequisites

  • A Blockchain0x account with an agent created, so it has a wallet on Base.
  • A sk_test_ API key for testing on Base Sepolia.
  • Node 18 or newer. The SDK targets >=18.
BASH
export B0X_API_KEY=sk_test_...        # sk_test_ -> Base Sepolia, sk_live_ -> Base mainnet
export B0X_WEBHOOK_SECRET=...         # webhook signing secret, shown once at creation

Get the wallet address and network

The agent's wallet address is on Base, and which Base depends on the key prefix. A sk_test_ key gives a wallet on Base Sepolia; a sk_live_ key gives one on Base mainnet. Read the agent to confirm the network, and copy the address from the dashboard or the agent's public profile at wallet.blockchain0x.com/a/{slug}.

TYPESCRIPT
import { createClient } from "@blockchain0x/node";

const client = createClient({ apiKey: process.env.B0X_API_KEY! });
const agent = await client.agents.get("agt_...");
console.log(agent.network); // "testnet" -> Base Sepolia (eip155:84532), "mainnet" -> Base (eip155:8453)

The chain ids are worth knowing because a sender needs them: Base mainnet is eip155:8453 and Base Sepolia is eip155:84532. Sending USDC on any other chain, or to an address on the wrong Base network, means it does not arrive.

Fund and receive on Base Sepolia

On testnet, you fund the agent's wallet yourself to exercise the receive path. Copy the wallet address, then send it test USDC from a public Base Sepolia USDC faucet. That arrival is a real receive event on testnet, so it is the cleanest way to confirm your handling works before any real value moves.

On mainnet, you do not fund to test; real callers or your own treasury send the USDC. The address and the flow are identical, only the network and the realness of the money change. Because of that symmetry, anything you confirm on Base Sepolia behaves the same on Base mainnet.

Watch for the payment

Receiving is event-driven: subscribe to payment.received and verify each delivery against the raw bytes.

TYPESCRIPT
import express from "express";
import { webhooks } from "@blockchain0x/node";

const app = express();
app.use(express.raw({ type: "application/json" }));

app.post("/webhooks/blockchain0x", (req, res) => {
  const result = webhooks.verify({ headers: req.headers, rawBody: req.body, secret: process.env.B0X_WEBHOOK_SECRET! });
  if (!result.ok) return res.status(400).json({ code: result.code });
  if (result.eventType === "payment.received") {
    const payload = JSON.parse(req.body.toString("utf8"));
    creditAgent(payload); // your logic
  }
  return res.status(200).end();
});

The webhook is the signal that USDC landed on Base. Do not poll a balance in a loop; let the event tell you, and look up the canonical record with client.transactions.get(id) when you need to reconcile.

Verify a payment on a block explorer

One thing receiving on Base gives you that a closed payment system does not: an independent public record. Every payment is an on-chain transaction with a hash, and you can look that hash up on a Base block explorer to confirm it, separate from anything Blockchain0x tells you.

This is useful in two situations. During development, pasting the transaction hash into the explorer shows you the transfer, the amount, the sender, and the receiving address, which is the fastest way to confirm a test payment really moved the USDC you expected to the address you expected. In production, the explorer is a neutral source of truth for a support question or a dispute: if a caller claims they paid and you have no payment.received event, the hash either shows a confirmed transfer to your address or it does not, and that settles it without trusting either party's logs. Keep the transaction identifier from the webhook payload or transactions.get so the lookup is a direct paste rather than a search. The point is that on-chain receiving is auditable by anyone, which is a property worth using, not just a side effect.

Finality and confirmations

A property specific to receiving on chain, worth understanding before you build on it: a Base payment is final once its transaction confirms. There is no pending-then-reversible window like a card authorization, and no chargeback path. When you act on payment.received, you are acting on a settled transfer.

That finality is a feature for a payee, you keep what you are paid, but it puts the responsibility on the sender to get the details right, because a transfer to a wrong address or the wrong network is gone. For your own receiving, it means you can deliver the paid result as soon as the event fires, without holding it back against a future reversal. Base confirms quickly, so the gap between a caller paying and your handler seeing payment.received is short, which is part of why the per-call model feels synchronous even though real settlement is happening underneath.

A practical consequence worth designing for: because the payment is final and fast, you can make delivery and payment a single tight loop. The caller pays, the event fires, you return the result, and there is no settlement period to reconcile later, no holdback, and no reversal window to reserve against. That is simpler than a card flow, where you often deliver on an authorization and reconcile against capture and possible chargeback days later. On Base you reconcile against a fact, not a promise, which removes a whole class of accounting state you would otherwise carry.

Common pitfalls

Three traps.

Wrong network. A sk_test_ agent receives on Base Sepolia only. USDC sent on Base mainnet, or another chain entirely, does not arrive. Match the network to the key before sharing an address.

Polling instead of webhooks. Looping on a balance is slow and brittle. Subscribe to payment.received and verify it; that is the intended signal.

Assuming reversibility. A confirmed Base payment is final. Build as if there are no chargebacks, because there are none, and double-check the address and network on anything you send.

What to ship today

Read the agent's network, copy its Base address, send it test USDC on Base Sepolia from a faucet, and confirm the payment.received event lands. When that works, the same flow runs on Base mainnet with a sk_live_ key. For the stablecoin framing see how-to-accept-stablecoin-payments-as-agent; for the full receive mechanics see how-to-receive-payments-as-ai-agent. Pricing is on the pricing page.

FAQ

Frequently asked questions.

What is Base?

Base is an Ethereum layer-2 network with low fees and fast settlement. Agent wallets live on Base, and USDC moves there for a fraction of a cent per transfer, which is what makes sub-cent agent payments economical. You receive USDC on Base the same way any address receives a token, but you do it through the agent's managed wallet rather than holding keys.

Which Base network do I use?

Base Sepolia (chain id eip155:84532) for testing, where USDC comes from a public faucet, and Base mainnet (eip155:8453) for real value. The key prefix picks the network: a sk_test_ key gives a testnet wallet, a sk_live_ key gives a mainnet one. Switching is a key swap, not a code change.

How do I know a payment arrived?

A payment.received webhook fires when USDC lands in the agent's wallet. Verify the delivery with webhooks.verify and read the body. You can also look a payment up with client.transactions.get for the canonical record. Do not rely on polling a balance; the webhook is the signal.

Is a Base payment reversible?

No. Once the transaction confirms on Base, the transfer is final, the same as any on-chain payment. That is good for you as the payee, no chargebacks, but it means a payment sent to the wrong address or network does not come back. Confirm the address and network before sharing them.

What about gas to receive USDC?

Receiving does not cost you gas; the sender pays the network fee to move the USDC. Base fees are low, a fraction of a cent, which is the whole reason it works for small payments. Your focus is on watching for the arrival, not on funding gas to accept it.

Create your free agent wallet in 5 minutes.

First payment confirmed in under ten minutes. Free to start.