Webhook Security
Verifying webhooks
When you receive a webhook, verify it came from Wava before processing it. We recommend:
- Verify the signature — API integrations with signing enabled receive an
X-Wava-Signature header. See Signature Verification below.
- Verify the order — After receiving a webhook, call
GET /v1/orders/{orderId} with your merchant key to confirm the order status matches what the webhook reported.
- Use HTTPS — Always use an HTTPS endpoint for your webhook URL in production.
Signature verification
API integrations with HMAC signing enabled receive a signature in the X-Wava-Signature header on every webhook request. Use it to confirm the payload has not been tampered with.
How it works
Wava generates the signature by creating an HMAC-SHA256 hash of the JSON payload using your shared secret, then sends the hexadecimal result in the X-Wava-Signature header.
Verification examples
Always use a constant-time comparison function (timingSafeEqual, compare_digest, hash_equals) to prevent timing attacks. Never use === or == to compare signatures.
Important notes
- The
X-Wava-Signature is a plain hexadecimal string — no prefix like sha256=.
- Serialize the payload using
JSON.stringify() with default options. Property order matters.
- Store your secret in an environment variable — never commit it to source control.
- Signature signing is optional and must be enabled in your integration configuration. Contact support if you need it enabled.
Idempotency
Your webhook handler should be idempotent — processing the same webhook multiple times should produce the same result. Wava may send the same webhook more than once in rare cases (retries, network issues).
Use the id_order or id_external field to deduplicate incoming webhooks.
Never trust webhook data alone for critical business logic (e.g., shipping an order). Always verify the order status via the API before taking action.