Skip to main content

Webhook Integration Guide

Webhooks allow your application to receive real-time notifications when transaction events occur, instead of polling for status changes.

Overview

Step 1: Register a webhook

Subscribe to all events

Use * to receive every event type:

Available events

Step 2: Verify webhook signatures

Every webhook request includes an x-zet-signature header containing an HMAC-SHA256 signature of the request body, computed using your webhook secret. Always verify signatures to ensure the webhook came from Zet and wasn’t tampered with.
Use the raw request body for signature verification, not a parsed/re-serialized JSON. JSON serialization can change key order or whitespace, invalidating the signature.

Step 3: Handle events

Webhook payload structure

Example handler

Retry policy

If your endpoint doesn’t respond with a 2xx status within 30 seconds, Zet retries with exponential backoff: After 5 failed retries, the webhook is marked as failed. You can check missed events via the Transactions API.

Managing webhooks

List all webhooks

Delete a webhook

Per-transaction callbacks

In addition to global webhooks, you can specify a callbackUrl when initiating a transaction. This URL receives events for that specific transaction only:
Per-transaction callbacks use the same signature verification as global webhooks.

Best practices

  1. Always verify signatures — never process unsigned or incorrectly signed webhooks
  2. Implement idempotency — webhooks may be delivered more than once; deduplicate by transactionId + event
  3. Respond quickly — return 200 immediately, then process asynchronously
  4. Use a queue — push webhook payloads to a queue (SQS, Redis, etc.) for reliable processing
  5. Log raw payloads — store the raw request body for debugging and auditing
  6. Use raw body for verification — don’t parse and re-serialize JSON before verifying the signature
  7. Monitor webhook health — alert if your endpoint starts returning errors
  8. Use HTTPS only — webhook URLs must use HTTPS with a valid TLS certificate
  9. Set up a fallback — periodically poll the Transactions API to catch any missed events
  10. Limit to 10 webhooks — you can register up to 10 webhook URLs per API key