Skip to Content

Overview

Real-time notifications for transaction, token, and merchant lifecycle events, delivered by legacy webhooks or, by invitation, by Svix.

Webhooks provide real-time notifications for completed transaction and token events. You can configure webhooks to receive notifications for specific events, such as when a sale transaction is completed or a token is created.

Each event type is separate, so you can choose to subscribe to only the events you want to receive notifications for.

Each event is sent as a POST request to the endpoint URLs you configure, and each endpoint chooses which event types it subscribes to. The request body contains a JSON payload with the details of the event.

Configured transaction webhooks report outcomes across payment channels without depending on the customer's browser. A session or local validation error might not produce a transaction webhook. Use verified webhooks and authenticated transaction retrieval to maintain your payment records.

Two delivery methods

Webhooks reach you by one of two delivery methods. The event payload is identical on both. Only the transport, the way you configure endpoints, and the signature differ.

if Svix is enabled for youraccount

Transaction or token event

Legacy delivery
x-fsk-wh-chksm

Svix delivery
svix-id, svix-timestamp, svix-signature

Merchant lifecycle event

Your endpoint
same JSON payload either way

Verify, then deduplicate on event.id

Legacy webhooksThe delivery method every merchant has today. Support configures your endpoints, and each delivery is signed with the x-fsk-wh-chksm checksum.Legacy webhooks
Svix webhooks (invite only)Self-service endpoints in the partner portal, signed deliveries with replay protection, and a portal to inspect and replay failed deliveries. Available by invitation.Svix webhooks (invite only)

Svix webhooks are invite only. Unless Svix is enabled for your account, you are on legacy webhooks, and that is the delivery method to build against. To ask for Svix, see Requesting access.

Side by side

Legacy webhooks Svix webhooks
Availability Every merchant, today Invite only
Who sets it up Support, on your behalf You, self-service, in the partner portal
Signature headers x-fsk-wh-chksm svix-id, svix-timestamp, svix-signature
Signature algorithm HMAC-SHA256 over the raw body, lowercase hex HMAC-SHA256 over {svix-id}.{svix-timestamp}.{body}, base64
Secret Shared secret provided out-of-band by support Per-endpoint signing secret (whsec_...), shown in the portal, rotatable
Replay protection None - the signature has no time component Yes - timestamp tolerance enforced by the Svix libraries
Retries Retried on failure, but not on a published schedule Automatic, exponential backoff over roughly a day
Inspect and replay failed deliveries No - contact support Yes, from the portal
Events Transaction and token events Transaction, token, and merchant lifecycle events
Event payload Identical Identical

The payload is the same on both. Only the transport and the signature differ. Whichever you are on, the JSON body you parse and the event catalog you handle are the same - you do not need two parsers.

Tell from the headers

If you are not sure which delivery method your endpoint is on, capture one delivery and look at its request headers:

POST /webhooks HTTP/1.1
Content-Type: application/json
x-fsk-wh-chksm: 862c6f2473c97472be4262b04670e777b2ed145d12d8a1c79ffc52ea9cfe7f0f

You are on legacy webhooks. Follow Verifying the checksum, and contact support to change your endpoints.

POST /webhooks HTTP/1.1
Content-Type: application/json
svix-id: msg_2yZK3ZV4Tk3E8FQ0YB55X1N0Tq
svix-timestamp: 1783002600
svix-signature: v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=

You are on Svix webhooks. Follow Verifying signatures, and manage your endpoints yourself in the partner portal.

If the same URL receives some deliveries with x-fsk-wh-chksm and others with svix-* headers, your endpoint is registered on both delivery methods. Each event is then delivered twice - once by each.

This is expected while you move from legacy to Svix, not a fault. Handle it by deduplicating on event.id (see below), and ask support to remove the legacy registration once your Svix handling is verified. See Moving from legacy to Svix.

Delivery and retries

Deliveries are retried on both delivery methods when your endpoint does not answer with a 2xx. On legacy webhooks, failed deliveries are retried, but there is no published schedule and no portal to inspect or replay them - contact support. On Svix, retries follow an exponential backoff schedule over roughly the following day, endpoints that keep failing may be disabled automatically, and failed deliveries can be inspected and replayed from the portal.

Verify the delivery and save it to a durable queue before returning 2xx, then process asynchronously. If saving fails, return a non-2xx response so delivery can be retried. A handler that does slow work inline risks timing out, which is treated as a failed delivery and retried - so slow processing turns into duplicate processing.

Deduplicate on event ID

Because deliveries are retried, and because an endpoint can be registered on both delivery methods while you move from one to the other, your handler must be idempotent - the same event can arrive more than once.

Every payload, on either delivery method, carries an event envelope with a unique id. This excerpt shows only the envelope:

{
  "event": {
    "id": "evt_01JS21X856RR8R69GV5F17XK9C",
    "type": "sale.completed",
    "timestamp": "2025-04-16T14:30:00Z",
    "merchantId": "mer_01JQZC2Y6W3F8XKT5H9DPNBMVR"
  }
}

Store the event.id of every delivery you have processed, and ignore any delivery whose event.id you have already seen. This one check protects you against:

  • a legacy retry, or a replayed legacy delivery - the legacy checksum carries no timestamp, so this check is also its replay protection,
  • Svix's automatic retries after a slow or failed acknowledgement, and a manual replay from the portal, and
  • the same event arriving on both delivery methods while your endpoint is registered on both.

event.id is the same value on both delivery methods for the same event, because both send the same payload. The Svix svix-id header identifies the Svix message - it is constant across retries of one Svix message, but it is not present on legacy deliveries and does not match event.id. Deduplicate on event.id.

Where ACH depends on this

For ACH bank transfers, acceptance for processing is separate from settlement. The hosted ACH response reports Processing with result code 0; final webhooks report status: Completed with the approval or decline in transactionResponses[].responseCode. Use transaction retrieval to reconcile a missed delivery.

Event categories

Transaction eventsSales, authorizations, captures, refunds, and voids. Both delivery methods.Event catalog
Token eventsStored payment methods created and removed. Both delivery methods.Event catalog
Merchant lifecycle eventsMerchant application progress, approval, and pricing decisions. Svix webhooks only.Event catalog

Next steps

Know which delivery method you are on

You are on legacy webhooks unless Svix is enabled for your account. The headers of one delivery confirm it - see Tell from the headers.

Configure an endpoint

Through support on legacy webhooks, self-service in the partner portal on Svix. See Configuring endpoints for legacy, or Configuring endpoints for Svix.

Verify every delivery

Reject any request whose signature does not validate. See Verifying the checksum for legacy, or Verifying signatures for Svix.

Handle the events you subscribed to

See the event catalog for payloads and the full list.

Questions about your integration? Contact support@doura.ca.