Skip to content

Signature Verification

Most webhook providers sign their payloads so you can verify authenticity. HookNexus includes a built-in Signature Verification tool and a public API endpoint for this purpose.

Why Verify Signatures?

Without verification, anyone who knows your webhook URL can send fake events. Signature verification ensures:

  • The request genuinely came from the provider
  • The payload hasn’t been tampered with in transit

Using the Dashboard Tool

  1. Select a request in the Dashboard.
  2. Click the Verify Signature tab in the detail panel.
  3. Choose the provider (Stripe, GitHub, Shopify, or Slack).
  4. Enter your webhook secret.
  5. The tool shows whether the signature is valid or invalid, along with the computed hash.

Using the API

Send a POST request to the public verification endpoint:

Terminal window
curl -X POST https://api.hooknexus.com/api/verify-signature \
-H "Content-Type: application/json" \
-d '{
"provider": "stripe",
"payload": "raw request body here",
"signature": "t=1704278400,v1=abc123...",
"secret": "whsec_your_stripe_secret"
}'

Response:

{
"valid": true,
"provider": "stripe",
"algorithm": "sha256"
}

Provider Details

Header: Stripe-Signature Format: t=timestamp,v1=signature Algorithm: HMAC-SHA256

Stripe includes a timestamp to prevent replay attacks. The signed payload is {timestamp}.{body}.

const signedPayload = `${timestamp}.${rawBody}`;
const expectedSig = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');

Troubleshooting

IssueCauseFix
Signature always invalidWrong secret keyDouble-check your webhook secret from the provider’s dashboard
Stripe signature failsUsing parsed body instead of rawAlways use the raw request body string, not parsed JSON
Timestamp mismatchClock skewStripe allows 5-minute tolerance by default
Base64 vs hex confusionShopify uses Base64, others use hexThe HookNexus tool handles this automatically