Create a charge via POST /charges with name, description, pricing_type (fixed_price), local_price (amount and currency), and metadata containing your internal order ID; this returns a hosted_url for the customer and a charge code.
Validate all incoming webhooks by computing HMAC-SHA256 of the raw request body using your webhook shared secret and comparing it to the X-CC-Webhook-Signature header before processing any event.
Listen for charge:confirmed (sufficient on-chain payment with required confirmations), charge:failed (expired without payment), and charge:delayed (payment detected but insufficient confirmations at expiry) events.
To handle underpayment: if the on-chain amount is less than the required amount, Coinbase Commerce emits a charge:pending followed by a charge:failed event (no charge:confirmed) — detect this by comparing payments[].value.local.amount against the original pricing; issue a partial refund or request a top-up from the customer.
For overpayment: Coinbase Commerce confirms the charge and flags overpaid amounts in the payment object's overpayment_detection field — it is your responsibility to return the excess to the sender's address; Coinbase does not auto-refund.
Implement idempotent webhook processing: acknowledge with HTTP 200 immediately, enqueue the event for async processing, and deduplicate on event.id before updating order status to avoid double-fulfillment from retried webhook deliveries.
Known gotchas
Coinbase Commerce charges expire after a fixed window (check current documentation for the expiry duration as it may vary by pricing type); once expired, no further payments are accepted, and the charge moves to EXPIRED — do not fulfill orders on late payments to expired charges.
Confirmation requirements vary by blockchain — on-chain finality for Bitcoin requires more block confirmations than Ethereum; Coinbase Commerce abstracts this but may take significantly longer to emit charge:confirmed for Bitcoin versus stablecoin-on-Ethereum payments.
Do not rely solely on charge:confirmed for fulfillment without also checking the charge's timeline for any subsequent charge:failed or charge:delayed event — rare edge cases can produce both events; treat the final state in the timeline array as authoritative.
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp