Webhook signature

A webhook signature is a cryptographic value, usually an HMAC calculated with a shared secret over the request body and a timestamp, that a payment provider sends with each webhook so the receiving server can confirm the message is genuine and unaltered.

Also called: webhook signing, signed webhook, HMAC signature, webhook verification, webhook signing secret

Updated

On this page4 sections

How does a webhook signature work?

The provider and the merchant share a secret for each webhook endpoint. When the provider sends a webhook, it calculates a hash-based message authentication code over the payload, often together with a timestamp, and puts the result in a header. The merchant’s server repeats the calculation with its copy of the secret and compares. Stripe’s documentation describes its scheme: a header with a timestamp and a signature, generated with HMAC and SHA-256 over the timestamp and the JSON payload. If the values match and the timestamp is recent, the message came from the provider and was not changed on the way.

Why does it matter?

Webhooks often trigger money movements: marking an order paid, crediting a balance, releasing goods. Stripe notes that without verification an attacker could send fake events to fulfil orders or change records. As an illustrative example: an endpoint that accepts any well-formed POST can be sent a fake success message for an unpaid order. With signature checks, that request fails verification and is rejected before any business logic runs.

What else is needed?

A signature proves the sender, not the outcome. Handlers should still process events idempotently, because the same event can arrive more than once, and should never downgrade a final status. Secrets should be rotated and kept out of code, and a status that matters can be confirmed by calling the provider’s API before acting on it.

Where does Omno use it?

When creating a webhook in Omno’s dashboard, merchants can choose an authorisation method for deliveries. Omno’s webhooks guide also asks merchants to process webhooks idempotently, never overwrite a final status with an earlier one, and confirm with Get Transaction Info when in doubt, rather than trusting redirects or browser events.

Frequently asked questions

Why must signature verification use the raw request body?

Because the signature was calculated over the exact bytes sent. Stripe's documentation warns that if a web framework parses or reformats the body before verification, the check fails. Verify the raw body first, then parse the JSON.

How does a signature stop replay attacks?

By signing a timestamp along with the body. An attacker cannot change the timestamp without breaking the signature, so the receiver can reject messages that are too old. Stripe's libraries use a default tolerance of 5 minutes, and Stripe recommends comparing signatures in constant time to avoid timing attacks.

esc
↑↓ to move ↵ to open All results