Settlement APIs let you accept payments (eg. USDC, DAI, BUSD, USDT, EURC, and cNGN) programmatically without a hosted checkout page. Deposit sessions assign a unique address per payment with a fixed expected amount, partial-payment tracking, and automatic excess refunds on sweep. Wallet direct and wallet intent flows cover in-app payers. Videpay detects on-chain activity, sweeps deposits, relays intents, and emits webhooks as payments move to settled.
Need machine-readable request/response bodies for your AI or codebase? Download this page as plain Markdown.
Your app creates a 25 USDC deposit session. The customer sends 10 USDC first, deposit.updated shows PARTIALLY_FUNDED with remaining 15. An hour later they send 15 more, status becomes FULLY_FUNDED, sweep runs, and payment.settled credits your balance. If they had sent 30 USDC in one go, we'd still settle 25 and the 5 USDC excess would refund to refundAddress automatically.
| Field | Type | Required | Description |
|---|---|---|---|
direct | flow | No | Payer sends an on-chain pay() transaction from their wallet. Returns unsigned transaction calldata. |
relayed_intent | flow | No | Payer signs an EIP-712 PaymentIntent; Videpay relays settlement gaslessly after token approval. |
relayed_batch | flow | No | Multiple relayed_intent payments settled in one on-chain batch transaction. |
deposit_sweep | flow | No | Funds received at a deposit address are swept into your merchant balance. Created when a deposit session settles. |
Dashboard maps to these APIs
Open Dashboard → Payments. The Payments tab lists settlement records (GET /payments/settlements) with filters, detail view (GET /payments/settlements/{id}), sync, and refund actions. The Deposits tab lists deposit sessions (GET /payments/deposit-sessions) with balance progress, manual settle, refund, and token recovery. Dashboard browser calls include authorization step-up (PIN/OTP/2FA) in the request body: API key integrations omit it.
Preview gross, fee, and net amounts from the on-chain TokenRegistry Payment fee bucket before creating a settlement or showing totals in your UI.
| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
asset | string | Yes | Asset symbol to quote (USDC). |
amount | decimal string | Yes | Gross payment amount in human units. |
/payments/quote-feeQuote protocol fee for a payment amount. Accepts public or secret API keys.
01x-api-key: pk_AbCdEfGhIj_XyZ1234567890abcdefghij02Content-Type: application/json01{02 "chain": "base",03 "asset": "USDC",04 "amount": "25"05}A deposit session is a fixed-amount payment contract, not an open tip jar. When you create a session, `amount` becomes the on-chain `expectedAmount` for that deposit address. Videpay continuously syncs the address balance, advances session status, emits webhooks, and, once fully funded, sweeps the expected portion to your merchant wallet. Surplus and expiry behavior are deterministic; your integration mostly listens and reacts.
Why deposit address ≠ donation address
Deposit sessions require a fixed expected amount: the customer is paying an invoice, not choosing a number. Donation campaigns accept any amount to a campaign `walletAddress` and aggregate toward an optional `goalUsd`. Deposit sessions also use a separate, higher protocol fee bucket than donations. Different rails for different economics.
Deposit addresses are designed for real-world payer behavior: wire delays, exchange minimums, and the occasional math typo.
| Field | Type | Required | Description |
|---|---|---|---|
amounts.expected / expectedRaw | decimal / raw | No | Fixed invoice total configured at session creation. This is the amount sweep settles toward. |
amounts.received / receivedRaw | decimal / raw | No | USDC observed at the deposit address so far. Increments as transfers arrive. |
amounts.remaining / remainingRaw | decimal / raw | No | Shortfall until fully funded. Zero once received ≥ expected. |
amounts.excess / excessRaw | decimal / raw | No | Surplus above expected before sweep. Refunded to refundAddress during sweep. |
amounts.refunded / refundedRaw | decimal / raw | No | After SETTLED or REFUNDED, cumulative amount returned to refundAddress (includes overpayment change). |
amounts.progressPercentage | string | No | Funding progress toward expected (e.g. "50.00" for half paid). Useful for checkout progress UI. |
refundAddress | address | No | Required for overpayment change and expiry refunds. Set at session creation; baked into the on-chain deposit route. |
Deposit sessions assign a unique `depositAddress` per payment (or one address per chain when `chain` is omitted). Customers send the expected asset from any wallet or exchange withdrawal. Videpay tracks partial receipts via deposit.updated, auto-sweeps when fully funded, and refunds excess atomically on sweep. Terminal success is always payment.settled with `flow: deposit_sweep`.
Omit chain for all supported networks
If you do not pass `chain` on POST /payments/deposit-sessions, Videpay creates deposit routes on every active merchant chain that supports the asset. The session includes `routes[]` with an address per network. When multiple routes receive funds, the first fully funded route wins; surplus on non-winning routes can be refunded after the winner settles. Pass `chain` only when you want a single-network session.
| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Lock the session to one chain. Omit to create deposit routes on every active merchant chain that supports the asset: session.routes[] lists an address per network. An unsupported asset and chain combination returns 400. See Supported chains. |
asset | string | Yes | Asset symbol from GET /finance/assets. When chain is omitted, routes are created on every active merchant chain that lists this symbol. |
amount | decimal string | Yes | Expected deposit amount: fixed for the life of the session. Partial and overpayment handling is relative to this total. |
refundAddress | address | No | Address to return overpayment change and expiry refunds. Required for correct excess handling on sweep. |
payerAddress | address | No | Expected sender wallet (optional enforcement hint). |
customerId | uuid | No | Attach session to a CRM customer. |
expiresAt | datetime | No | ISO datetime when the session stops accepting deposits. |
expiresInMinutes | integer | No | Relative expiry (1–1440 minutes) instead of expiresAt. |
reference / title / description / metadata | string / object | No | Reconciliation and display fields. |
/payments/deposit-sessionsCreate a standalone deposit session. Accepts public or secret API keys.
01x-api-key: pk_AbCdEfGhIj_XyZ1234567890abcdefghij02Content-Type: application/json01{02 "asset": "USDC",03 "chain": "base",04 "amount": "25",05 "reference": "tip-001",06 "refundAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",07 "payerAddress": "0xCustomerWallet12345678901234567890123456789012",08 "customerId": ":cus_3b7e9f1a-2c4d-5e6f-7a8b-9c0d1e2f3a4b",09 "checkoutLinkId": "cl_7f3a9b2c-4d1e-4a8f-9c0b-1e2d3f4a5b6c",10 "title": "Videpay Pro Plan",11 "expiresInMinutes": 60,12 "metadata": {13 "orderId": "ord-1001"14 }15}/payments/deposit-sessions/ds_8e4f1a2b-3c5d-4e6f-7a8b-9c0d1e2f3a4bRetrieve deposit session status, amounts, and settlementPaymentId when swept. Accepts public or secret API keys.
01x-api-key: pk_AbCdEfGhIj_XyZ1234567890abcdefghij02Content-Type: application/json/payments/deposit-sessionsList deposit sessions. Requires secret API key.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/jsonBackground workers continuously sync active deposit sessions; you rarely need to poll manually. Use sync to force a balance refresh after a slow exchange withdrawal, settle to nudge sweep when a session is already `FULLY_FUNDED`, and recovery endpoints when customers send the wrong asset. Refund and refund-all are documented on the Refunds page.
Deposit webhooks vs payment.settled
While a deposit is in progress, listen for deposit.created (session opened) and deposit.updated (partial receipts, balance syncs, status transitions). These events are not sent for terminal session statuses. When sweep completes, Videpay emits payment.settled with `flow: deposit_sweep`, not `deposit.settled`. Use `session.settlementPaymentId` to correlate the deposit session with its settlement record. For partial payments, deposit.updated is your progress signal; for fulfillment, wait for payment.settled.
| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
wrongToken | address | Yes | ERC-20 contract address of the token mistakenly sent to the deposit address. |
/payments/deposit-sessions/ds_8e4f1a2b-3c5d-4e6f-7a8b-9c0d1e2f3a4b/syncQueue an on-chain balance sync for the deposit address.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json/payments/deposit-sessions/ds_8e4f1a2b-3c5d-4e6f-7a8b-9c0d1e2f3a4b/settleQueue a sweep after the session is fully funded. Creates a settlement payment with flow deposit_sweep and emits payment.settled when complete.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json/payments/deposit-sessions/ds_8e4f1a2b-3c5d-4e6f-7a8b-9c0d1e2f3a4b/recover-tokenQueue recovery of a non-USDC ERC-20 token mistakenly sent to the deposit address.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "wrongToken": "0xWrongToken12345678901234567890123456789012"03}/payments/deposit-sessions/ds_8e4f1a2b-3c5d-4e6f-7a8b-9c0d1e2f3a4b/recover-nativeQueue recovery of native ETH accidentally sent to the deposit address.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/jsonThe payer broadcasts a pay() transaction from their wallet. The API returns calldata for your wallet SDK. No relay queue involved.
| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
asset | string | Yes | Asset symbol from GET /finance/assets (see Supported chains). Must be supported on the selected chain. |
amount | decimal string | Yes | Payment amount in human units (e.g. "25" for 25 USDC). |
customerAddress | address | Yes | Payer wallet address. |
customerId | uuid | No | Link payment to an existing CRM customer. |
title / description / reference | string | No | Display and reconciliation fields echoed in webhooks. |
metadata | object | No | Arbitrary JSON (max 16KB) stored on the payment. |
ttlSeconds | integer | No | Intent-only: signature validity window (30–86400 seconds). |
/payments/settlements/direct/preparePrepare a wallet-direct settlement. Requires secret API key.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "asset": "USDC",04 "amount": "25",05 "customerAddress": "0xCustomerWallet12345678901234567890123456789012",06 "customerId": ":cus_3b7e9f1a-2c4d-5e6f-7a8b-9c0d1e2f3a4b",07 "reference": "tip-002",08 "title": "In-app tip",09 "metadata": {10 "recipientId": "user_42"11 }12}The payer signs an EIP-712 PaymentIntent and approves USDC. Your backend relays the signature; Videpay submits the on-chain transaction gaslessly.
| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
asset | string | Yes | Asset symbol from GET /finance/assets (see Supported chains). Must be supported on the selected chain. |
amount | decimal string | Yes | Payment amount in human units (e.g. "25" for 25 USDC). |
customerAddress | address | Yes | Payer wallet address. |
customerId | uuid | No | Link payment to an existing CRM customer. |
title / description / reference | string | No | Display and reconciliation fields echoed in webhooks. |
metadata | object | No | Arbitrary JSON (max 16KB) stored on the payment. |
ttlSeconds | integer | No | Intent-only: signature validity window (30–86400 seconds). |
ttlSeconds | integer | No | Intent signature validity window (30–86400 seconds). Defaults to 3600. |
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
paymentId | uuid | Yes | Prepared relayed_intent payment ID. |
signature | hex string | Yes | EIP-712 signature from the payer wallet. |
/payments/settlements/intents/preparePrepare a relayed_intent payment and return typed data for signing.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "asset": "USDC",04 "amount": "25",05 "customerAddress": "0xCustomerWallet12345678901234567890123456789012",06 "customerId": ":cus_3b7e9f1a-2c4d-5e6f-7a8b-9c0d1e2f3a4b",07 "reference": "tip-003",08 "ttlSeconds": 360009}/payments/settlements/intents/relayRelay a signed payment intent. Queues on-chain submission and emits payment.updated while processing.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "paymentId": "pst_4a8f2c1d9e7b6a3f5c2d8e1b0a9f7c6d",03 "signature": "0x..."04}Poll or list settlement payments across all flows. Use sync when webhooks are delayed or to confirm relay progress.
| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
customerId | uuid | No | Filter by linked CRM customer. |
checkoutLinkId | uuid | No | Filter by originating checkout link. |
status | string | No | Settlement status filter (pending, queued, submitted, settled, refunded, failed, invalidated). |
q | string | No | Search reference, title, or customer wallet address. |
offset / limit | integer | No | Pagination. limit max 100. |
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
txHash | hex string | No | Optional on-chain transaction hash. Omit to nudge relay/sync workers when txHash is already known. |
/payments/settlements/pst_4a8f2c1d9e7b6a3f5c2d8e1b0a9f7c6dRetrieve payment status, amounts, and transaction hash. Accepts public or secret API keys.
01x-api-key: pk_AbCdEfGhIj_XyZ1234567890abcdefghij02Content-Type: application/json/payments/settlementsList settlement payments with filters. Requires secret API key.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json/payments/settlements/pst_4a8f2c1d9e7b6a3f5c2d8e1b0a9f7c6d/syncForce sync with on-chain state. Optionally pass txHash when relay metadata is missing.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "txHash": "0xabc123..."03}Settlement integrations typically subscribe to deposit.created, deposit.updated, payment.created, payment.updated, payment.settled, and payment.refunded. Every deposit and payment payload includes a customer field: pass customerId at creation or collect buyer identity at checkout so fulfillment webhooks carry your CRM record. When nothing is linked yet, customer is null (the key is still present).
| Field | Type | Required | Description |
|---|---|---|---|
customer | object | null | No | Linked CRM customer when customerId was set at creation or checkout collected buyer identity. Always present on deposit sessions, settlement payments, and subscriptions: null when unlinked. Shape: { id, name, email, phoneNumber, reference }. |
id | uuid | No | Videpay customer record ID. |
name | string | No | Display name. |
email / phoneNumber | string | null | No | Contact fields when collected. |
reference | string | null | No | Your CRM or user ID: unique per business. |
deposit.created | event | No | Deposit session created with depositAddress assigned. Customer at data.deposit.customer. |
deposit.updated | event | No | Balance or status change while session is non-terminal (partial payment, sync). Customer at data.deposit.customer. Not sent after SETTLED, REFUNDED, or CANCELLED. |
payment.created | event | No | Settlement record created for direct or relayed_intent prepare. Customer at data.payment.customer. |
payment.updated | event | No | Relay queue progress, submission, or non-terminal status change. Customer at data.payment.customer. |
payment.settled | event | No | On-chain settlement confirmed, including deposit_sweep after deposit address sweep. Customer at data.payment.customer. |
payment.refunded | event | No | Settlement refund completed. Customer at data.payment.customer. |
Register a webhook endpoint and verify the X-Protocol-Signature header on every delivery before fulfilling orders or updating your database.
deposit.createdSent when a deposit session is created and a unique payment address is assigned.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: deposit.created04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...deposit.updatedSent when deposit progress changes (partial payment received, balance sync, etc.). Not sent for terminal statuses.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: deposit.updated04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...payment.createdSent when a settlement payment record is created (wallet direct/intent flows).
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: payment.created04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...payment.settledSent when funds are confirmed on-chain and credited to your merchant balance.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: payment.settled04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...