Square logo

Verify Square Webhook Signatures

Square signs each webhook with HMAC-SHA256 over your notification URL concatenated with the raw request body and sends the base64 result in the x-square-hmacsha256-signature header. The key is the signature key of that webhook subscription. Enter the notification URL exactly as configured, the raw body, the key and the header value.

Paste the x-square-hmacsha256-signature value above to compare

Everything runs in your browser — the payload and secret never leave this page. Want to verify a different provider? See the webhook signature verifier hub or the generic HMAC generator.

How Square signs webhooks

  1. Take the full notification URL exactly as configured in your subscription — scheme, host, path and any trailing slash must match.
  2. Concatenate that URL directly with the raw request body: URL first, body second, with no separator.
  3. Compute HMAC-SHA256 of the combined string using your subscription's signature key as the key.
  4. Base64-encode the digest and constant-time compare it to x-square-hmacsha256-signature.

Verify Square signatures in code

Node.js
const crypto = require('crypto');

// notificationUrl must match the subscription URL exactly (incl. trailing slash).
const expected = crypto
  .createHmac('sha256', process.env.SQUARE_SIGNATURE_KEY)
  .update(notificationUrl + rawBody)   // URL first, then the raw body
  .digest('base64');

const received = req.headers['x-square-hmacsha256-signature'];
const valid = crypto.timingSafeEqual(
  Buffer.from(expected), Buffer.from(received));
Python
import hmac, hashlib, base64

payload = notification_url.encode() + raw_body   # URL + raw body, no separator
expected = base64.b64encode(hmac.new(
    signature_key.encode(), payload, hashlib.sha256).digest()).decode()

received = request.headers['x-square-hmacsha256-signature']
valid = hmac.compare_digest(expected, received)

Frequently asked questions

Which key signs Square webhooks?

The signature key for that specific webhook subscription, shown in the Square Developer Dashboard under Webhooks → Subscriptions. Each subscription has its own key, and it is used as a raw string — not base64-decoded.

Why does my Square signature never match?

The most common cause is the notification URL not matching exactly: a missing or extra trailing slash, http vs https, or a proxy rewriting the host all change the result. Sign with the URL you configured in the subscription, and use the raw request body.

Does Square sign a timestamp?

No. The modern HMAC-SHA256 scheme signs only the URL plus body, so there is no built-in replay protection — rely on HTTPS and idempotent handling. The legacy x-square-signature header (HMAC-SHA1) is deprecated; verify x-square-hmacsha256-signature instead.

Verify other providers

Receiving Square webhooks on a server behind a firewall or on localhost? Webhook Relay can forward them to your internal service and even verify or transform them before delivery.