IVAN CAPPONI.NET/C# · Microsoft Azure

Webhook · Security · HMAC

Verifying incoming webhook signatures: Shopify, eBay and Stripe

Last updated: June 2026

Verifying incoming webhook signatures from Shopify, eBay and Stripe on the raw body
Verify the signature before acting: raw body, constant-time comparison, 200/401.

A webhook is an HTTP request from the internet: before trusting its content you must verify its signature, otherwise anyone can send fake events to your endpoint. Shopify, eBay and Stripe do this similarly in principle but differently in detail. This guide compares the three approaches with a .NET example on Azure.

The shared rule

  • compute the signature over the raw body (the received bytes), not the parsed JSON object;
  • compare with a constant-time comparison to avoid timing attacks;
  • if it doesn't match respond 401 and do nothing; if it matches respond 200 and process asynchronously;
  • keep the signing secret out of the code.

.NET example (HMAC-SHA256)

// rawBody = the EXACT request bytes (no re-serialisation)
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(signingSecret));
byte[] computed = hmac.ComputeHash(rawBody);
byte[] received = Convert.FromBase64String(headerValue);   // Shopify: base64
bool ok = CryptographicOperations.FixedTimeEquals(computed, received); // constant time
if (!ok) return Results.Unauthorized();
// ... queue the processing and respond 200

For Stripe the signature is hex and is computed over timestamp + "." + payload; the rest of the flow is identical.

Per-platform differences

PlatformHeaderMechanism
ShopifyX-Shopify-Hmac-Sha256Base64 HMAC-SHA256 with the client secret, over the raw body
StripeStripe-SignatureHex HMAC-SHA256 over timestamp+payload, with timestamp tolerance
eBay (account deletion)x-ebay-signatureSHA-256 hash for the challenge and signature validation with eBay's public key

So Shopify and Stripe use a shared secret (HMAC); eBay, for account deletion notifications, uses a signature verifiable with a public key. The eBay flow is detailed in the guide on the eBay account deletion webhook, while for Shopify webhooks see the guide on Shopify GDPR compliance webhooks.

Keep the secrets safe

Verification only works if the secret stays secret: keep it in a secret manager with a managed identity, as described in securing secrets and credentials with Azure Key Vault, and rotate it periodically.

Common mistakes

  • computing the signature over the parsed JSON instead of the raw body;
  • using a normal string comparison instead of a constant-time one;
  • ignoring the timestamp tolerance (Stripe) and accepting old requests (replay);
  • hardcoded signing secret in code or logs.

Conclusion

Verifying signatures is a few lines of code, but getting them wrong exposes the endpoint to fake events. The recipe is always the same: raw body, constant-time comparison, 200/401, protected secret. References: HTTPS webhooks (Shopify) and webhook signatures (Stripe).