Subject: Webhook Signature Mismatch for oauth.authorization.revoked Event
Message:
Hi Square Team,
I’m experiencing an issue with verifying the webhook signature for the oauth.authorization.revoked event. Despite following the documentation and ensuring all steps are correct, the computed HMAC-SHA256 signature does not match the x-square-signature header sent by Square.
Details
Webhook Endpoint:
Example: https://my-webhook-endpoint.com/square-webhook (using HTTPS, with no known modifications to the payload).
Payload (logged in raw format):
Here is the exact raw payload received from Square:
I’m Square Dev AI, here to help answer your question!
Based on the information you’ve provided, the following documentation will help answer your question:
If this documentation helped you find a solution, please check the box indicating that this reply solves the problem.
Otherwise one of our Developer Advocates will provide additional assistance shortly.
Never mind - I figured out the solution. Just followed the python code example from the following page and it worked!
Here is the code example:
from http.server import BaseHTTPRequestHandler, HTTPServer
from square.utilities.webhooks_helper import is_valid_webhook_event_signature
# The URL where event notifications are sent.
NOTIFICATION_URL = 'https://example.com/webhook'
# The signature key defined for the subscription.
SIGNATURE_KEY = 'asdf1234'
class MainHandler(BaseHTTPRequestHandler):
def do_POST(self):
length = int(self.headers.get('content-length', 0))
body = self.rfile.read(length).decode('utf-8')
square_signature = self.headers.get('x-square-hmacsha256-signature')
is_from_square = is_valid_webhook_event_signature(body,
square_signature,
SIGNATURE_KEY,
NOTIFICATION_URL)
if is_from_square:
# Signature is valid. Return 200 OK.
self.send_response(200)
print("Request body: {}".format(body))
else:
# Signature is invalid. Return 403 Forbidden.
self.send_response(403)
self.end_headers()
# Start a simple server for local testing.
# Different frameworks may provide the raw request body in other ways.
# INSTRUCTIONS
# 1. Run the server:
# python server.py
# 2. Send the following request from a separate terminal:
# curl -vX POST localhost:8000 -d '{"hello":"world"}' -H "X-Square-HmacSha256-Signature: 2kRE5qRU2tR+tBGlDwMEw2avJ7QM4ikPYD/PJ3bd9Og="
server = HTTPServer(("0.0.0.0", 8000), MainHandler)
server.serve_forever()
The issue you’re experiencing might be due to the encoding of the webhook signature key. The key provided by Square is base64-encoded, so you need to decode it before using it to compute the HMAC.
Here’s how you can modify your Python code:
import hmac
import hashlib
import base64
# Signature Key
webhook_signature_key = "[REDACTED FOR SECURITY]"
# Decode the Signature Key
decoded_key = base64.b64decode(webhook_signature_key)
# Compute HMAC-SHA256
computed_hash = hmac.new(
decoded_key,
raw_payload, # Received raw payload (as bytes)
hashlib.sha256
).digest()
# Base64 encode the result
expected_signature = base64.b64encode(computed_hash).decode("utf-8")
print(f"Computed Signature: {expected_signature}")
This should give you the correct computed signature that matches the x-square-signature header sent by Square. If you’re still experiencing issues, please let us know.