How to Accept USDC Payments on a Site or API
Receiving USDC is trivial. Building a payment system around it means solving attribution, matching an incoming transfer to a specific order, plus a confirmation policy, quote expiry, and handling for underpayment and overpayment. Use a unique address or an identifier per order rather than one shared address for everything.
The real problem is attribution
Accepting a transfer is a configuration detail. Knowing what that transfer was for is the system you are actually building.
With one shared receiving address, every incoming payment looks the same: an amount from an address, with nothing tying it to an order. If two customers pay the same amount within a minute, you cannot distinguish them. If someone pays the wrong amount, you cannot tell whether it is an underpayment for one order or a full payment for another.
Two approaches solve this properly.
A unique address per order. Generate a receiving address for each order, and any payment arriving there is unambiguously for that order. Clean, but you now manage address derivation and sweeping.
An identifier carried with the payment. The payment references an order identifier that your system issued, so matching is exact. This is the model that works naturally for API and agent payments, where the identifier comes from the payment terms you quoted.
What does not work is asking humans to include a reference and hoping. Some fraction will not, and each of those becomes a manual investigation that costs more than the sale.
Confirmation, quoting, and the edge cases
Confirmation policy. Decide how many confirmations you require before treating a payment as final, based on what is at risk rather than case by case. For small digital goods, a fast policy is usually right. For anything you cannot claw back, wait longer. What matters most is that the rule is written down, since ad hoc decisions during an incident are how goods get released against payments that later disappear.
Quote expiry. A price shown to a buyer is a commitment for as long as you honor it. Attach an expiry and enforce it, or someone will pay yesterday's price next month and be technically correct. For agent buyers this is not hypothetical, because software will absolutely retry against a stale quote.
Underpayment. Decide: credit partially, refund, or hold pending the difference. Pick one, publish it, implement it.
Overpayment. Same question, plus the operational reality that refunding requires knowing where to send it, which you may not have if payment came from an exchange or a contract.
Wrong network or wrong asset. Something adjacent to USDC arrives on a network you do not support. Recovery ranges from easy to impossible, so state clearly what you accept, in machine-readable form where possible.
Accounting from day one
Record the fiat-equivalent value at the time of receipt alongside the amount. Even with a stable settlement asset, your accounting is likely denominated in a fiat currency, and reconstructing values later is tedious and error prone. Doing it at write time costs nothing and saves a quarter-end.
Serving agent buyers as well as humans
If any of your buyers are software, the checkout page is not an interface. It is an obstacle.
An agent needs the same information a person gets from your pricing page, expressed in fields: what this costs, in what asset, on what network, where to send it, and how long the quote is valid. That is precisely the shape of a 402 payment challenge, and exposing it costs you very little if you already have the pieces above.
The practical benefit is that the sale requires no signup, no key issuance, and no invoicing, which is what makes very small purchases economically possible in the first place.
The practical requirement is that your error responses become part of the interface. An agent cannot ask support what went wrong, so "payment received but amount below quoted price, difference is X" is a usable response and "payment error" is not.
What buyers need on their side
Your integration only works if buyers can actually pay, and for agent buyers that means bounded spending authority rather than a person approving each purchase.
CryptoCadet is the counterpart to what this page describes: a non-custodial USDC rail on Base where an agent spends from a session-key bounded float with custody in the OS keychain, supporting x402-style pay-per-call and ERC-20 subscriptions. For you as a seller, payments arrive in USDC on Base with fast finality, from buyers whose limits are enforced by their credential rather than by a policy they promise to follow.
That matters commercially as well as technically. Buyers with bounded authority produce fewer abandoned payments and fewer disputes, because the failure mode of a bounded agent is a declined purchase rather than a chargeback conversation you cannot have on this rail anyway.
And if your product suits ongoing access rather than discrete purchases, support subscriptions alongside per-call pricing. Metering is right for bursty, unpredictable consumption. It is the wrong instrument for a customer who wants continuous access at a predictable cost.
Frequently asked questions
- How do I accept USDC payments on my website?
- Receiving a transfer is configuration. The system is attribution: use a unique receiving address per order or carry an order identifier with the payment, so every incoming transfer maps to exactly one order. Then define a confirmation policy, quote expiry, and behavior for underpayment and overpayment before launch.
- Can I use one receiving address for all payments?
- You can receive, but you cannot reliably reconcile. Two customers paying the same amount within a minute are indistinguishable, and a wrong amount could be an underpayment for one order or a full payment for another. Each ambiguity becomes a manual investigation that usually costs more than the sale.
- How many confirmations should I require before releasing goods?
- Set the policy by value at risk and write it down rather than deciding per transaction. Small digital goods justify a fast policy. Anything you cannot reclaim justifies waiting longer. The failure that hurts is releasing goods during an incident against a payment that does not ultimately settle.
- How do I let AI agents pay me directly?
- Expose machine-readable payment terms rather than only a checkout page: amount, asset, network, destination, quote expiry, and an order identifier. That is the shape of an HTTP 402 challenge. Also make error responses specific, since an agent cannot contact support and will act on whatever text you return.
