Webhooks

Receive real-time notifications when resources in your Mercury account change by configuring webhook endpoints to listen for specific events.

🚧

Webhooks are currently not available in the sandbox environment.

The Webhooks API allows you to receive real-time HTTP notifications when changes occur to your Mercury resources, like Transactions. Instead of polling the Events API, webhooks push updates directly to your server as they happen.

How Webhooks Work

When a resource changes in your Mercury account, we'll send an HTTP POST request to your configured webhook endpoint containing the event data. Webhooks use the same event structure as the Events API, following the JSON Merge Patch standard (RFC 7396). Each webhook delivery contains the same event structure as the Events API:

{
  "id": "bfa85eaa-afab-11f0-8fea-17d650f2306e",
  "resourceType": "transaction",
  "resourceId": "1d3042b6-af63-11f0-89d2-3503f2fcfef7",
  "operationType": "update",
  "resourceVersion": 2,
  "occurredAt": "2025-01-01T00:00:00.000000Z",
  "changedPaths": [
    "status",
    "postedAt"
  ],
  "mergePatch": {
    "postedAt": "2025-01-01T00:00:00.000000+00:00",
    "status": "sent"
  },
  "previousValues": {
    "postedAt": null,
    "status": "pending"
  }
}

See the Events API documentation for complete details on event field descriptions and supported resources.

Webhook Endpoint Configuration

Each webhook endpoint can be configured with:

  • url: The HTTPS URL where webhook events will be delivered.

  • eventTypes: Optional array of event types to subscribe to (e.g., ["transaction.created", "transaction.updated"]). If omitted, you'll receive all event types.

  • filterPaths: Optional array of resource field paths to filter by (e.g., ["status", "amount"]). When specified, webhooks are only sent when one of these fields changes. If omitted, all changes trigger webhooks.

  • status: The current state of the webhook endpoint:

    • "active" - Receiving events normally
    • "paused" - Temporarily stopped, no events will be sent

Webhook Event Types

Currently supported event types:

  • transaction.created: Fired when a new transaction is created in your account
  • transaction.updated: Fired when an existing transaction is modified in your account

Verifying Webhook Signatures

Every webhook request includes a signature in the Mercury-Signature header. You should always verify this signature to ensure the request is legitimately from Mercury and hasn't been tampered with.

The signature is computed as an HMAC-SHA256 hash using:

  • Key: Your webhook endpoint's secretKey (base64 portion only)
  • Message: <timestamp>.<request_body> where timestamp is a Unix timestamp (seconds since epoch)

The Mercury-Signature header format is: t=<timestamp>,v1=<signature>

  • t = Unix timestamp (seconds since epoch) when the webhook was sent
  • v1 = Hex-encoded HMAC-SHA256 signature

To verify:

  1. Extract the timestamp and signature from the header
  2. Construct the signed payload: timestamp.request_body
  3. Compute HMAC-SHA256 using your secret key
  4. Compare the computed signature with the received signature using constant-time comparison

Best Practices

Responding to Webhooks

Your endpoint should respond with a 2xx status code as soon as possible upon receiving an event. If we receive no response within 5 seconds or we receive a Non-2xx status code, Mercury will mark the event delivery as failed and retry up to 10 times using exponential backoff over the course of ~1 day. If we receive a 4xx status code, we will not retry with the exception of a 429 status code in which we will retry.

Handling Duplicate Events

Webhooks are delivered at-least-once, meaning you may occasionally receive the same event multiple times. Use the event's id field to track which events you've already processed and implement idempotency.

Filtering Events

Use eventTypes and filterPaths to reduce noise and only receive events you care about

Verifying Your Endpoints

After creating a webhook endpoint, verify your endpoint using VerifyWebhook to test your webhook configuration before going live. This sends a test event to your endpoint and confirms it's reachable and properly configured: