Skip to main content
This guide walks through the core payment lifecycle in Sandbox: create a session, authorize it, capture the funds, and check status. The Sandbox environment uses mock data and does not move real funds. Base URL: https://sandbox.cdp.coinbase.com/platform

Prerequisites

Before you begin, you’ll need:
Install the CDP CLI (requires Node.js 22+):
Configure a Sandbox environment using your CDP Secret API Key JSON file from the CDP Portal:
Keep the API key secret. Never commit it to source control.
Payment Acceptance requires onboarding before you can use the APIs. Contact our team to get started. Once onboarded, you’ll receive Sandbox credentials and an account ID for testing.Set your account ID:
Sandbox does not move real funds. Testing real payments or bank settlement requires CDP Live Mode, your own CDP Portal, and a funded account.

1. Create a payment session

Create a payment session with an amount, asset, and target. The target is the account where captured funds will settle.
Save the payment session ID:
Key fields in the response:
  • url — A hosted payment page URL you can redirect buyers to
  • expiries — Deadlines for authorization (1 day), capture (7 days), and refund (30 days)
  • balances — Running totals that update as funds move through the lifecycle
  • status — Starts as created, waiting for buyer authorization

2. Authorize the payment

Authorization places a hold on the buyer’s funds. Payment Acceptance supports wallet, Coinbase, and x402 authorization — see Authorization for all three flows in full. Wallet authorization is the flow to use in Sandbox. It runs against real signature verification and real EVM RPC nodes — only the onchain settlement step is mocked, so no real funds move. Coinbase (OAuth) authorization is not available in Sandbox; test that flow against production once you’ve completed onboarding. Start by fetching the available wallet authorization options for the buyer’s address — this is a stateless read, no signing required yet:
Signing the returned payloads requires a wallet SDK or library — see Authorization for the full sign-and-submit flow, including payload types and the request to submit the signed payloads. The authorization starts in pending and transitions asynchronously to succeeded or failed. In production, subscribe to webhooks to get notified.

3. Check the session status

Poll the session to confirm authorization succeeded:
Once the status shows authorization_succeeded, the session’s balances.capturable will equal the authorized amount.

4. Capture the funds

After fulfillment, capture the authorized funds. You can capture the full amount or a partial amount. Full capture:
Partial capture (e.g., ship part of an order):
Setting finalCapture: true releases any remaining capturable balance back to the buyer after the capture settles. If omitted or false, the remaining hold stays open for subsequent partial captures.

Other lifecycle paths

The full capture in step 4 above moves the session to a terminal state — the steps below are alternative paths, not steps that follow it on the same session. Each applies to a session in a different state.

Void uncaptured funds

If you need to release authorized funds without capturing (e.g., order canceled before shipment):
Voids release all remaining capturable funds in a single operation. After voiding, no further captures can be made.

Refund captured funds

To return funds to the buyer after capture:
If amount is omitted, the full refundable balance is refunded. Multiple partial refunds are supported up to the total captured amount.

Cancel an unused session

If a session was never authorized, cancel it to move it to a terminal state:
Cancel only works on sessions in created status — before any authorization.

5. List payment sessions

View all payment sessions for your entity:

6. Handle webhooks

In production, subscribe to acceptance.payment_session.* events to receive real-time status updates rather than polling. See Webhooks for setup. Events fired for a successful payment:
  1. acceptance.payment_session.authorization_pending — buyer is authorizing
  2. acceptance.payment_session.authorization_succeeded — funds held
  3. acceptance.payment_session.capture_pending — capture initiated
  4. acceptance.payment_session.capture_succeeded — funds settled

Move to production

To run this flow with real funds:
  1. Complete onboarding with our team (get in touch)
  2. Set up your CDP account and Prime account for settlement
  3. Switch from the Sandbox base URL to the production base URL
  4. Use a production API key
Production payments settle real USDC from buyer wallets, with automated conversion and bank sweeps based on your settlement configuration.

Payment Sessions

Expiries, balances, auto-capture, and target types

Authorization

Wallet, Coinbase, and x402 authorization flows

Webhooks

Subscribe to real-time payment lifecycle events

API Reference

Full Payment Acceptance API