Skip to main content

Webhook Security

Verifying webhooks

When you receive a webhook, verify it came from Wava before processing it. We recommend:
  1. Verify the signature — API integrations with signing enabled receive an X-Wava-Signature header. See Signature Verification below.
  2. 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.
  3. 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.

Request headers

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.
  • The signature is computed over the exact JSON body Wava sends, using HMAC-SHA256 by default.
  • Use the signing key as a plain UTF-8 string. It is 64 hexadecimal characters, but it is not hex-decoded before use — pass it to your HMAC function exactly as shown in your dashboard. Decoding it to 32 raw bytes first produces a valid-looking signature that will never match ours.
  • The webhook secret is the signing key (64 characters), not the API secret key (128 characters). Partner accounts receive both in the same response at account creation; only the 64-character signing_key signs webhooks.
  • Partner accounts are created with signing enabled and their own signing key, issued once at account creation. For direct API integrations signing is optional — contact soporte@wava.co to enable it.

Checking which key signed a delivery

If your signatures do not match, confirm you and Wava are using the same key before debugging the algorithm. GET /v1/partners/webhook returns signing_key_fingerprint: the first 12 characters of the SHA-256 of the key Wava signs with. Compute the same digest over the key you have configured:
If the two fingerprints differ, you are holding a different key — regenerate it from the dashboard and reconfigure. If they match, the key is correct and the mismatch is in how the signature is computed: check the two notes above about key encoding and which secret to use.

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.