A dedicated virtual wallet gives each customer their own on-chain deposit address per chain. When they send a supported stablecoin or token (USDC, USDT, DAI, EURC, and other assets registered on your chain's TokenRegistry), Videpay detects it, sweeps to your merchant balance, and notifies you, ideal for billing portals, memberships, and repeat invoicing. 'Send to this address every month', finally a sentence finance and engineering agree on.
Need machine-readable request/response bodies for your AI or codebase? Download this page as plain Markdown.
Each household gets a virtual wallet address in their billing portal. They send USDC or DAI monthly to the same address. Your system receives customer.dedicated-virtual-wallet.deposit-detected, then customer.dedicated-virtual-wallet.swept when funds reach your balance.
Virtual wallets use the same on-chain TokenRegistry as deposit sessions and checkout, not a USDC-only path. When a transfer arrives, Videpay calls `getTokenInfo(tokenAddress)` on the wallet's registry. If `supported` is true, the token is swept to your merchant balance. If false, you receive customer.dedicated-virtual-wallet.unsupported-token-detected and recovery is queued automatically when `autoSweep` is true (default).
Supported vs unsupported
Supported, USDC, USDT, DAI, EURC, BUSD, cNGN, and any other asset your chain's TokenRegistry marks as supported (including native ETH/MATIC when enabled). Swept via `deposit-detected` → `swept` webhooks. Unsupported, random ERC-20s, scam tokens, or assets not in the registry. Moved to Videpay platform custody, not credited to your merchant balance. After `unsupported-token-recovered`, a recovery holding is created; release it to your registered `merchantAddress` via POST `/recovery-holdings/{id}/release`. Listen for `recovery-holding.created` and `recovery-holding.released`.
Dashboard → Customers → Virtual wallets
From a customer detail page, deploy wallets per chain, toggle autoSweep, and view transfer history. Supported assets sweep like settlement deposits; unsupported assets route to platform custody for release. Every action maps to the API endpoints below.
| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Deploy on a specific chain (e.g. base). Omit to deploy on all active merchant chains. |
autoSweep | boolean | No | Automatically sweep supported-token deposits to merchant balance. Defaults to true. Unsupported tokens are moved to Videpay platform custody (not your merchant wallet). |
/customers/:cus_3b7e9f1a-2c4d-5e6f-7a8b-9c0d1e2f3a4b/dedicated-virtual-walletsDeploy a persistent deposit address. Omit chain to deploy on all active merchant chains. Emits customer.dedicated-virtual-wallet.created when deployment completes.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "autoSweep": true04}/customers/:cus_3b7e9f1a-2c4d-5e6f-7a8b-9c0d1e2f3a4b/dedicated-virtual-walletsList all virtual wallets for a customer.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json/customers/:cus_3b7e9f1a-2c4d-5e6f-7a8b-9c0d1e2f3a4b/dedicated-virtual-wallets/dvw_5c8d2e1f-9a3b-4c7d-8e6f-1a2b3c4d5e6fUpdate wallet settings (e.g. toggle autoSweep).
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "autoSweep": false03}| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
offset / limit | integer | No | Transfer list pagination. limit 1–100, default 20. |
/customers/:cus_3b7e9f1a-2c4d-5e6f-7a8b-9c0d1e2f3a4b/dedicated-virtual-wallets/dvw_5c8d2e1f-9a3b-4c7d-8e6f-1a2b3c4d5e6f/transfers?limit=20List deposits detected on a virtual wallet with pagination.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json| Field | Type | Required | Description |
|---|---|---|---|
id / walletId | uuid / bytes32 | No | Videpay record ID and on-chain wallet identifier. |
address | address | No | Deposit address customers send supported tokens to. |
chain | object | No | Chain id and name (e.g. base-sepolia). |
status | enum | No | deploying, deployed, or failed. |
autoSweep | boolean | No | Whether supported-token deposits are automatically swept to the merchant settlement wallet. Unsupported tokens are automatically recovered when true. |
deployTxHash / deployedAt | string / datetime | No | On-chain deployment transaction details. |
When an unsupported token is recovered from a virtual wallet or deposit session, Videpay creates a recovery holding ledger entry. Release sends the exact recorded amount from platform custody to your registered `merchantAddress` on that chain: destination is fixed; you cannot redirect to an arbitrary wallet. Dashboard sessions require step-up auth (PIN, OTP, or 2FA) on live; secret API key calls skip step-up.
| Field | Type | Required | Description |
|---|---|---|---|
source | enum | No | virtual_wallet_transfer or deposit_session: links back to the originating transfer or session via sourceId. |
status | enum | No | in_custody → release_queued → released (or failed). |
amount.raw | string | No | Exact token amount released: must match custody record. |
recoveryTxHash / releaseTxHash | string | No | On-chain custody move and merchant release transactions. |
authorization | object | No | Dashboard only. Step-up confirmation (PIN, OTP, or 2FA) when a logged-in owner acts in the browser. Omit entirely for secret API key integrations: the server skips this check when you authenticate with x-api-key. On sandbox, any emailed OTP code is `000000` (six zeroes). It's giving dev mode. Live sends a real code. |
authorization.pin | string | No | Transaction PIN when enabled. |
authorization.otpChallengeId | uuid | No | OTP challenge from a prior dashboard auth step. On sandbox, enter `000000` when verifying the emailed code. |
authorization.twoFactorCode | string | No | TOTP code when 2FA is enabled. |
/recovery-holdings?source=VIRTUAL_WALLET_TRANSFER&sourceId=dvwt_1a2b3c4d&status=in_custodyList recovery holdings for your business. Filter by source, sourceId, status, or chain.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json/recovery-holdings/rh_6d9e2f3a-4b5c-4d7e-8f9a-0b1c2d3e4f5aRetrieve a single recovery holding.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json/recovery-holdings/rh_6d9e2f3a-4b5c-4d7e-8f9a-0b1c2d3e4f5a/releaseQueue release to your merchantAddress. Emits recovery-holding.release-queued, then recovery-holding.released on success.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base"03}| Field | Type | Required | Description |
|---|---|---|---|
status | enum | No | detected, held, sweep_queued, swept, recovery_queued, recovered, or failed. |
token.isSupported | boolean | No | true when the token is supported by your chain's TokenRegistry (swept to merchant). false triggers unsupported-token-detected and recovery. |
amount.raw / amount.formatted | string | No | Transfer amount in raw and human units. |
sweepRef / settlementTxHash | string | No | Present after sweep completes. |
Register a webhook endpoint and verify the X-Protocol-Signature header on every delivery before fulfilling orders or updating your database.
customer.dedicated-virtual-wallet.createdSent when a dedicated virtual wallet is deployed for a customer.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: customer.dedicated-virtual-wallet.created04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...customer.dedicated-virtual-wallet.deposit-detectedSent when a TokenRegistry-supported token arrives at a customer virtual wallet.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: customer.dedicated-virtual-wallet.deposit-detected04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...customer.dedicated-virtual-wallet.sweptSent when a detected deposit is swept to your merchant balance.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: customer.dedicated-virtual-wallet.swept04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...customer.dedicated-virtual-wallet.unsupported-token-detectedSent when a token outside the chain TokenRegistry arrives at a virtual wallet address. Recovery to Videpay platform custody is queued automatically when autoSweep is true.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: customer.dedicated-virtual-wallet.unsupported-token-detected04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...customer.dedicated-virtual-wallet.unsupported-token-recoveredSent when an unsupported token is moved from a virtual wallet into Videpay platform custody (not the merchant settlement wallet).
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: customer.dedicated-virtual-wallet.unsupported-token-recovered04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...recovery-holding.createdSent when an unsupported token is moved into platform custody and a releaseable holding is recorded.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: recovery-holding.created04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...recovery-holding.releasedSent when a recovery holding is released to the merchant registered address.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: recovery-holding.released04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...