2026-10-05
USDC Payments for Developers: A Guide to Every Step of the Integration

Accepting USDC in your own product takes about seven decisions, made roughly in this order. We've written a separate post on each, and this page puts them in sequence so you can read the one you need now and skip the rest.
If you only read one thing first, make it the custody section. Every later step works differently depending on who can move the money after the customer pays.
1. Decide who holds the money
The chain settles USDC in seconds for a fraction of a cent. What slows a team down is the tooling around it: custody, integration time, and primitives that don't exist yet.
Custody is the first question because it decides what a "paid" status even means. With a custodial processor, the customer pays the processor and you get a balance in its ledger. With direct on-chain settlement, the transfer goes to an address that pays out to your wallet, and the payment provider only detects and reports it. What a non-custodial payments API does covers how to evaluate a provider on this, and what self-custody payments actually require covers the part that becomes your job: keys, treasury, and recovery.
2. Model the payment as a charge
A wallet address on a page isn't a payment API. A USDC payment API starts with a charge your backend creates: a price, the token and network pairs you accept, an expiry of up to an hour, and your own order ID in externalRef.
Each charge gets its own deterministic address, so matching a transfer to an order never depends on the amount or a memo field. The charge also has a fixed lifecycle: pending, partially_paid, confirmed, expired, underpaid, with payout to your wallet tracked separately in settlementStatus. If you're working in Node.js, what to look for in a crypto payments SDK goes through how @klappay/node exposes all of this.
3. Choose who draws the checkout
You can send the customer to a hosted page, build the screen yourself, or use components in between. Hosted checkout vs payment API compares the three and explains why custody is a separate question from any of them.
For building your own, how to build a custom crypto checkout flow covers the architecture and @klappay/checkout-kit covers the code, wallet discovery included. If your customers don't have a wallet extension, checkout without a browser extension shows the OTP-plus-linked-wallet flow. And when there's no checkout page at all, only a URL to share, start with crypto payment links.
4. Let events drive the order
The browser never decides that an order is paid. Your backend does, from a verified event. How crypto payment webhooks work explains the payload, the signature, and the difference between charge.confirmed (the transfer landed) and charge.settled (the payout reached your wallet).
Webhooks are for the business action. For the screen the customer is watching, real-time payment notifications covers the live event stream and how your backend relays it. And before any of it, how to verify crypto payments lists what to check on-chain that a wallet's "success" message won't tell you.
5. Make the handler safe to run twice
Webhook delivery is at least once. Retries, a second endpoint, or two events about the same charge can all reach your handler with the same payment. Idempotent payment webhook handlers shows how to put that guarantee in database constraints instead of a lookup that races, and how to keep emails and fulfillment calls in an outbox.
6. Route the money: splits, escrow, recurring
Marketplaces and platforms rarely pay one wallet. How to split USDC payments between wallets defines up to five recipients on the charge itself, and how split distributions settle covers what happens between charge.confirmed and each recipient actually getting paid.
When money should wait for a condition, like a delivery confirmation or a dispute window, non-custodial escrow holds it in a per-charge Safe that Klappay can't release on its own. For subscriptions, designing a USDC recurring billing API works through the authorization model, since a connected wallet isn't a standing debit order.
7. Test the failures, not the 200
A charge endpoint returning 200 proves very little. How to test crypto payments without real funds uses the sandbox to push a test charge into underpaid, overpaid and expired states, with duplicate and out-of-order events on top, so you see how your handler behaves before a real customer finds out.
Not writing code?
If you're a freelancer who wants to send an invoice and get paid in USDC to your own wallet, skip all of the above and read how to get paid in USDC as a freelancer.
When you're ready to build, the developer docs have the API reference and SDK quickstart.