Topics covering webhook creation & management, event handling, Pub/Sub, and Eventbridge, in Shopify apps.
Hey all.
I've trying to get the webhook validation up and running for a while with no success.
I've seen the Ruby example, and was wondering if there's a Python example to validade the webhook sent to a Flask app.
Thanks a lot.
Solved! Go to the solution
This is an accepted solution.
Take a look at Verifying webhooks section of the Using webhooks article, and click the Python button.
This is an accepted solution.
Take a look at Verifying webhooks section of the Using webhooks article, and click the Python button.
digest = hmac.new(SECRET.encode('utf-8'), data, hashlib.sha256).digest()
works for me instead of what's there
Do you mind sharing the rest of your code? What I have so far is:
def verify_webhook(data, hmac_header):
digest = hmac.new(SECRET.encode('utf-8'), data, hashlib.sha256).digest()
genHmac = base64.b64encode(digest)
return hmac.compare_digest(genHmac, hmac_header.encode('utf-8'))
@app.route('/', methods=['POST'])
def main(request):
print('Received Webhook...')
data = request.get_data()
hmac_header = request.headers.get('X-Shopify-Hmac-SHA256')
verified = verify_webhook(data, hmac_header)
if not verified:
# do stuff...
return 'Integrity of request compromised...', 401
# do stuff...
print('Verified request...')
But it isn't working! I have no idea why and the docs don't help either.
import hmac
import hashlib
import base64
from flask import Flask
app = Flask(__name__)
SECRET = ''
def verify_webhook(data, hmac_header):
digest = hmac.new(SECRET.encode('utf-8'), data, hashlib.sha256).digest()
computed_hmac = base64.b64encode(digest)
return hmac.compare_digest(computed_hmac, hmac_header.encode('utf-8'))
@app.route('/productCreation', methods=['POST'])
def productCreation():
data = request.data
verified = verify_webhook(data, request.headers.get('X-Shopify-Hmac-SHA256'))
You can also checkout the guide in this post which also includes a link to a repo that has a fully functioning webhook handlers writter in Python + Flask
import hmac
import hashlib
import base64
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import Response
import os
load_dotenv()
app = FastAPI()
SHOPIFY_SECRET = os.getenv('SHOPIFY_SECRET')
def verify_webhook(raw_data, hmac_header, secret):
digest = hmac.new(secret.encode('utf-8'), raw_data, digestmod=hashlib.sha256).digest()
computed_hmac = base64.b64encode(digest).decode()
print(f"SECRET: {secret}")
print(f"RAW DATA: {raw_data}")
print(f"RAW DATA (decoded): {raw_data.decode('utf-8')}")
print(f"DIGEST (binary): {digest}")
print(f"DIGEST (hex): {digest.hex()}")
print(f"COMPUTED HMAC: {computed_hmac}")
print(f"RECEIVED HMAC: {hmac_header}")
return hmac.compare_digest(computed_hmac, hmac_header)
@app.post('/webhook/customer_data_request')
async def customer_data_request_webhook(request: Request):
try:
raw_data = await request.body()
headers = dict(request.headers)
print('HEADERS:', headers)
print('RAW DATA:', raw_data)
hmac_header = headers.get('X-Shopify-Hmac-SHA256')
if not hmac_header:
raise HTTPException(status_code=400, detail="Missing HMAC header")
verified = verify_webhook(raw_data, hmac_header, SHOPIFY_SECRET)
if not verified:
print("Computed HMAC does not match the provided HMAC.")
raise HTTPException(status_code=401, detail="HMAC verification failed")
print("HMAC verification successful.")
return Response(status_code=200)
except Exception as e:
print("Error processing customer data request webhook:")
print(e)
return Response(status_code=500, content=str(e))
I’m building a Shopify public app and I’m having trouble with the HMAC verification process. Despite using the Shopify Secret from the Dashboard of my app at partners.shopify.com, I can’t get the computed HMAC and the received HMAC to match. This always results in a failed verification.
I’ve tried various combinations, but nothing seems to work—they never match. There might be something I’m missing. I hope someone here has a solution.
Hey @KevinLopezBC , did you find a solution? I'm stuck with the same. I can't get them to match in my orders/create webhook.
In the post mentioned above, I've seen that the author is putting a "shpss" and underscore in front of the secret, but this also didn't fix it for me.
Hey there,
I didn’t find any solution, likely due to a conflict with middleware adding unwanted elements to the HTTP response.
Anyway, I had to set up a Flask server to handle this. It worked with the Shopify Flask code provided for the hmac verification, and my Flask server communicates back with my backend server. It worked on first try.
However, I didn’t find a direct solution, even after posting issues on FastAPI’s GitHub.