Documentation

Deposit address flow

When a customer opens your checkout link, Videpay creates a deposit session with a unique USDC address per network. They send the exact amount from any wallet or exchange withdrawal. If you omitted chain when creating the link, the hosted page lists every chain your business supports and the customer picks one before paying. Multichain, but make it user-friendly.

Need machine-readable request/response bodies for your AI or codebase? Download this page as plain Markdown.

When should I use this?

  • Customers pay from exchanges that only support send-to-address withdrawals.
  • You want zero wallet-connect UX: copy address or scan QR, send USDC, done.
  • Email, SMS, or QR invoice workflows.

Why use Videpay?

  • Works with every wallet and exchange, no browser extension required.
  • Partial payments are tracked; deposit.updated fires as funds arrive.
  • Overpayment and refund paths are handled by the platform.

Freelance invoice paid from Coinbase

You email a checkout link for 500 USDC. Your client withdraws from Coinbase to the deposit address shown on the page. deposit.updated shows progress; payment.settled fires when the full amount is confirmed, you unlock the deliverable. No 'did you get my transfer?' Slack thread required.

Before you start

  • Checkout link created
  • Webhook or Realtime listener registered

End-to-end flow

Listen for payment.settled, not deposit.settled

deposit.created and deposit.updated track funding progress. When the full amount arrives and Videpay sweeps to your merchant wallet, a deposit_sweep settlement payment is created and payment.settled fires: there is no deposit.settled webhook.

  1. Create checkout link (POST /checkout-links): omit chain for all supported networks, or set chain to lock to one.
  2. Customer opens checkoutUrl on the hosted page.
  3. Customer selects a network (multi-chain links): hosted page passes chain to POST .../deposit-sessions.
  4. Customer sends USDC to depositAddress for the exact expected amount.
  5. Listen for deposit.updated (progress) and payment.settled (done).

Multi-chain checkout links

Omit chain on create for all supported networks

When you do not pass chain on POST /checkout-links, Videpay sets chain.scope to all and returns supportedChains for every active merchant profile. The customer chooses a network on the hosted page; deposit session creation includes that chain. Pass chain at create time only when you want to restrict checkout to a single network.

Public deposit session (hosted page)

FieldTypeRequiredDescription
name / email / phoneNumberstringNoCustomer identity collected on the hosted page. Stored on the session and used to create or update customer records.
payerAddressaddressNoWallet the customer intends to pay from (optional hint for reconciliation).
refundAddressaddressNoAddress to return funds if the session expires or is refunded.
referencestringNoYour order reference for this payment attempt.
expiresInMinutes / expiresAtinteger / datetimeNoSession expiry: relative minutes (1–1440) or absolute ISO datetime.
metadataobjectNoArbitrary JSON attached to the deposit session.
chainstringNoLock 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.
POST/checkout-links/public/pub-k9m2x7/deposit-sessions

Called by the hosted checkout page when a customer starts paying. No API key: public endpoint.

Headers

headers
01Content-Type: application/json

Request body

request.json
01{02  "name": "Jane Doe",03  "email": "buyer@example.com",04  "phoneNumber": "+15551234567",05  "payerAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",06  "refundAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",07  "reference": "order-1001",08  "expiresInMinutes": 60,09  "metadata": {10    "cartId": "cart_abc"11  }12}

Merchant API deposit session

Create sessions from your backend when building a custom checkout UI that still uses deposit addresses. Same session shape as the public endpoint.

FieldTypeRequiredDescription
businessIduuidNoTarget business. Omit when your API key is scoped to one business.
chainstringNoLock 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.
assetstringYesAsset symbol from GET /finance/assets. When chain is omitted, routes are created on every active merchant chain that lists this symbol.
amountdecimal stringYesExpected deposit amount: fixed for the life of the session. Partial and overpayment handling is relative to this total.
refundAddressaddressNoAddress to return overpayment change and expiry refunds. Required for correct excess handling on sweep.
payerAddressaddressNoExpected sender wallet (optional enforcement hint).
customerIduuidNoAttach session to a CRM customer.
expiresAtdatetimeNoISO datetime when the session stops accepting deposits.
expiresInMinutesintegerNoRelative expiry (1–1440 minutes) instead of expiresAt.
reference / title / description / metadatastring / objectNoReconciliation and display fields.
POST/checkout-links/cl_7f3a9b2c-4d1e-4a8f-9c0b-1e2d3f4a5b6c/deposit-sessions

Create a session from your backend: useful for custom checkout UIs that still use deposit addresses.

Headers

headers
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json

Request body

request.json
01{02  "customerId": ":cus_3b7e9f1a-2c4d-5e6f-7a8b-9c0d1e2f3a4b",03  "payerAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",04  "refundAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",05  "reference": "order-1001",06  "expiresInMinutes": 60,07  "metadata": {08    "source": "api"09  }10}
GET/payments/deposit-sessions/ds_8e4f1a2b-3c5d-4e6f-7a8b-9c0d1e2f3a4b

Poll session state: amounts.received, amounts.remaining, status.

Headers

headers
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json
POST/payments/deposit-sessions/ds_8e4f1a2b-3c5d-4e6f-7a8b-9c0d1e2f3a4b/sync

Force on-chain balance check if webhook was delayed.

Headers

headers
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json

Deposit session object reference

FieldTypeRequiredDescription
depositAddressaddressNoUnique address the customer sends USDC to.
amounts.expected / amounts.received / amounts.remainingstringNoFunding progress in human units. remaining hits zero when fully funded.
amounts.progressPercentagestringNoPercentage funded: useful for progress UI.
statusenumNoPENDING, PARTIALLY_FUNDED, FULLY_FUNDED, SETTLED, REFUNDED, EXPIRED, CANCELLED (uppercase in merchant API).
settlementPaymentIduuidNoLinked settlement payment after sweep: present when status is SETTLED or REFUNDED.
routes[]arrayNoWhen chain was omitted at create, one entry per supported merchant chain with its own depositAddress.
customerobjectNoCRM customer when customerId was provided or identity collected on the page.

Checkout status (public poll)

GET/checkout-links/public/pub-k9m2x7/status?sessionId=ds_8e4f1a2b-3c5d-4e6f-7a8b-9c0d1e2f3a4b

Lightweight status for hosted pages. Prefer Realtime over polling in production: see Realtime events.

Webhooks you'll receive

Register a webhook endpoint and verify the X-Protocol-Signature header on every delivery before fulfilling orders or updating your database.

Webhookdeposit.created

Sent when a deposit session is created and a unique payment address is assigned.

Delivery headers

webhook-headers
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...
Webhookdeposit.updated

Sent when deposit progress changes (partial payment received, balance sync, etc.). Not sent for terminal statuses.

Delivery headers

webhook-headers
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...
Webhookpayment.settled

Sent when funds are confirmed on-chain and credited to your merchant balance.

Delivery headers

webhook-headers
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...