Documentation

Webhooks

Webhooks push real-time events to your server when payments settle, transfers complete, subscriptions charge, and more. Treat them like cash-register receipts: verify every one before fulfilling orders. Trust, but verify signatures.

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

When should I use this?

  • You need your server to react instantly when a payment settles.
  • You want to decouple checkout UI from order fulfillment logic.
  • You are building idempotent handlers for payment, transfer, or subscription events.

Why use Videpay?

  • No polling: Videpay POSTs to your URL within seconds of on-chain confirmation.
  • Signed payloads prevent spoofed payment notifications.
  • Automatic retries with exponential backoff if your server is temporarily down.

E-commerce order unlock

A customer pays 49 USDC for a digital product. Your webhook handler receives payment.settled, verifies X-Protocol-Signature, checks the amount matches the order, and marks the order paid in your database even if the customer closed the browser after paying. The tab closure is not your problem. The signature check is.

Before you start

  • Public HTTPS endpoint (use ngrok for local development)
  • Sandbox or live API key

Register an endpoint

POST/webhooks/endpoints

Create a webhook endpoint. Save credential.signingSecret from the response.

Headers

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

Request body

request.json
01{02  "name": "Primary webhook",03  "url": "https://yourapp.com/webhooks/videpay"04}
GET/webhooks/endpoints

List registered webhook endpoints.

Headers

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

Verify signatures

Every delivery includes X-Protocol-Signature (HMAC-SHA256 over the raw JSON body using your signing secret). Reject requests with invalid signatures before processing.

  1. Read the raw request body as a string (before JSON parsing).
  2. Compute HMAC-SHA256 with your whsec_ signing secret.
  3. Compare to the X-Protocol-Signature header value.
  4. Check X-Protocol-Event matches the event type you handle.

Payload envelope

All webhook bodies share the same top-level shape. The event-specific details live in data.

POST(your webhook URL)

Example payment.settled delivery: full body as Videpay sends it.

Headers

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

Request body

request.json
01{02  "event": "payment.settled",03  "emittedAt": "2026-07-07T10:12:00.000Z",04  "businessId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",05  "data": {06    "type": "payment",07    "payment": {08      "id": "pst_4a8f2c1d9e7b6a3f5c2d8e1b0a9f7c6d",09      "title": "Videpay Pro Plan",10      "description": null,11      "reference": "order-1001",12      "referenceHash": "0xabc123...",13      "flow": "deposit",14      "status": "settled",15      "environment": "test",16      "chain": {17        "id": 84532,18        "name": "base-sepolia"19      },20      "merchant": {21        "profileId": "prof_8e4f1a2b-3c5d-4e6f-7a8b-9c0d1e2f3a4b",22        "merchantAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",23        "settlementContractAddress": "0xPaymentSettlementAddress",24        "tokenRegistryAddress": "0xTokenRegistryAddress"25      },26      "checkoutLinkId": "cl_7f3a9b2c-4d1e-4a8f-9c0b-1e2d3f4a5b6c",27      "customerAddress": "0xCustomerWallet12345678901234567890123456789012",28      "customer": {29        "id": ":cus_3b7e9f1a-2c4d-5e6f-7a8b-9c0d1e2f3a4b",30        "name": "Jane Doe",31        "email": "buyer@example.com",32        "phoneNumber": null,33        "reference": null34      },35      "asset": {36        "name": "USD Coin",37        "symbol": "USDC",38        "logo": "",39        "address": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",40        "decimals": 6,41        "isNative": false42      },43      "amounts": {44        "grossRaw": "25000000",45        "gross": "25",46        "feeRaw": "125000",47        "fee": "0.125",48        "netRaw": "24875000",49        "net": "24.875",50        "refundedRaw": "0",51        "refunded": "0"52      },53      "batch": null,54      "intent": null,55      "relay": {56        "queuedAt": null,57        "startedAt": null,58        "attemptCount": 059      },60      "transaction": {61        "hash": "0xabc123def4567890abcdef1234567890abcdef1234567890abcdef1234567890",62        "blockNumber": 12345678,63        "logIndex": 464      },65      "refundTransaction": {66        "hash": null,67        "blockNumber": null,68        "logIndex": null69      },70      "metadata": {},71      "preparedAt": "2026-07-07T10:10:00.000Z",72      "submittedAt": "2026-07-07T10:11:00.000Z",73      "settledAt": "2026-07-07T10:12:00.000Z",74      "refundedAt": null,75      "failedAt": null,76      "lastSyncedAt": "2026-07-07T10:12:00.000Z",77      "failureReason": null,78      "createdAt": "2026-07-07T10:10:00.000Z",79      "updatedAt": "2026-07-07T10:12:00.000Z"80    }81  }82}

Customer object in webhooks

Any payment or subscription action tied to a CRM customer includes a customer field in the webhook payload. Use it to sync orders, receipts, and billing without a second API lookup. When no customer is linked, the field is null: but the key is always present on deposits, payments, and subscriptions.

  1. Embedded payment/subscription customer: { id, name, email, phoneNumber, reference }.
  2. Pass customerId when creating checkout links, deposit sessions, subscriptions, or settlement payments.
  3. Hosted checkout can auto-create customers, deposit.updated and payment.settled then include the new record.
  4. customerAddress on payments is the payer wallet; customer is your CRM profile: both can appear on the same object.
FieldTypeRequiredDescription
data.deposit.customerobject | nullNodeposit.created and deposit.updated: same shape as settlement payments.
data.payment.customerobject | nullNopayment.created, payment.updated, payment.settled, and payment.refunded.
data.subscription.customerobject | nullNosubscription.created, subscription.charged, subscription.past_due, subscription.cancelled, and subscription.reactivated.
data.customerobjectNocustomer.created, customer.updated, and customer.archive: full customer record with notes, metadata, and status.
data.customer (virtual wallets)objectNocustomer.dedicated-virtual-wallet.* events: customer plus dedicatedVirtualWallet and/or transfer objects.
data.recoveryHoldingobjectNorecovery-holding.created, recovery-holding.release-queued, recovery-holding.released, recovery-holding.release-failed: unsupported tokens moved to platform custody and released to merchantAddress.

Manage endpoints and retries

GET/webhooks

List recent webhook events and delivery status.

Headers

headers
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json
GET/webhooks/wev_1a2b3c4d-5e6f-7890-abcd-ef1234567890

Get a single webhook event with delivery attempt history.

Headers

headers
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json
POST/webhooks/wev_1a2b3c4d-5e6f-7890-abcd-ef1234567890/retry

Manually retry a failed delivery.

Headers

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

Also available over Realtime

Every event listed below is also broadcast over WebSocket with the same envelope and data payload. Use webhooks for durable server-side fulfillment; add Realtime when you need instant UI updates on checkout pages or live dashboards. See Realtime events for connection examples (API key or checkout token).

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.

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...
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.created

Sent when a settlement payment record is created (wallet direct/intent flows).

Delivery headers

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

Sent when a settled payment is refunded to the payer.

Delivery headers

webhook-headers
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: payment.refunded04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...
Webhookcheckout.created

Sent when you create a new checkout link.

Delivery headers

webhook-headers
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: checkout.created04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...