Fiat Onramp (Coinbase)
NEW
Buy crypto with credit card or bank transfer via Coinbase Onramp. USDC and ETH are deposited directly to your workspace wallet on Base.
Overview
How the fiat onramp flow works
- Your server calls
POST /api/v1/onramp/sessionwith a PayDirect API key - PayDirect generates a signed JWT, requests a one-time session token from Coinbase
- Returns a Coinbase Onramp URL the user can open to buy USDC or ETH
- Purchased crypto is deposited directly to the workspace's wallet on Base
Live only: Onramp requires a
pd_live_ API key. Sandbox (pd_test_) is not supported.POST
/api/v1/onramp/session
Create a one-time Coinbase Onramp session
Authentication
Bearer token required. pd_live_ key required — sandbox not supported.
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer pd_live_... |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
asset | string | No | "USDC" or "ETH" — default asset in the onramp UI |
fiatAmount | number | No | Preset fiat amount (1–10000) |
fiatCurrency | string | No | Fiat currency code (default: "USD") |
blockchains | string[] | No | Allowed blockchains (default: ["base"]) |
assets | string[] | No | Allowed assets (default: ["USDC", "ETH"]) |
Response (200 OK)
{
"onramp": {
"sessionToken": "...",
"channelId": "...",
"onrampUrl": "https://pay.coinbase.com/buy/select-asset?...",
"walletAddress": "0x...",
"expiresIn": 300
},
"timestamp": "2026-03-17T..."
}Error Responses
400 — Sandbox key
{
"error": "Coinbase Onramp is only available in live environment. Use a live API key to create onramp sessions."
}400 — Unsupported asset
{
"error": "Unsupported asset. Supported: USDC, ETH"
}400 — Invalid fiat amount
{
"error": "fiatAmount must be between 0 and 10000"
}400 — No wallet
{
"error": "No workspace wallet found. Provision a wallet first."
}500 — Coinbase API failure
{
"error": "Failed to create onramp session"
}cURL Example
curl -X POST https://www.paydirect.com/api/v1/onramp/session \
-H "Authorization: Bearer pd_live_..." \
-H "Content-Type: application/json" \
-d '{
"asset": "USDC",
"fiatAmount": 50,
"fiatCurrency": "USD"
}'SDK Usage
const { onramp } = await client.createOnrampSession({
asset: "USDC",
fiatAmount: 50,
});
window.open(onramp.onrampUrl, "_blank");Widget Usage
Use the OnrampWidget for a drop-in UI:
import { PayDirectProvider, OnrampWidget } from "@/components/widgets";
<PayDirectProvider apiKey={process.env.NEXT_PUBLIC_PAYDIRECT_API_KEY!}>
<OnrampWidget
defaultAsset="USDC"
defaultFiatAmount={50}
fiatCurrency="USD"
mode="popup"
onSuccess={({ onrampUrl, channelId }) => console.log("Session:", channelId)}
onError={(err) => console.error(err)}
/>
</PayDirectProvider>mode: "popup" opens Coinbase in a new window; "inline" embeds an iframe.
Webhook Event
Events fired when an onramp session is created
onramp.session.created
Delivered when a session is successfully created. Payload includes walletAddress, channelId, and expiresIn.
Security Notes
How we keep onramp sessions secure
- Session tokens are single-use and expire in 5 minutes. Each call to
POST /api/v1/onramp/sessiongenerates a new token. - CDP API keys never leave the server. PayDirect signs JWTs server-side; your frontend only receives the Coinbase Onramp URL.
- CORS restricted to approved origins. No wildcard — only domains you configure in the dashboard can call the API from the browser.
- JWT signed with ES256. Coinbase-compatible elliptic curve signing for token requests.
