Topics covering webhook creation & management, event handling, Pub/Sub, and Eventbridge, in Shopify apps.
Hi,
I am trying to integrate webhook validation flow found here :
but the hmac that i calculate is not matching with the hamc sent in header, i have few questions regarding that, our app is PUBLIC app. Please help us with these questions:
1 - The secret key that I am using is the API secret key that we got prom out public apps dashboard, it looks something like this `cf188XXXXXXXXXXXXXXXXXXX7`, should i use this key or some other key.
2- As i can see from the documentation that the secret is not encoded(python example), but we need to encode the secret otherwise it throws a error that `a byte or bytearray objcet is expected`.
3- The data that we need to send is the whole body including the headers and all, or only some part of the body should be sent.
4 - Below is our code implementation (This is always returning 401 unauthorized):
import base64
import hashlib
import hmac
def verify_webhook_1(data, hmac_header, SECRET):
digest = hmac.new(SECRET.encode('utf-8'), data.encode('utf-8'), hashlib.sha256).digest()
computed_hmac = base64.b64encode(digest)
return hmac.compare_digest(computed_hmac, hmac_header.encode('utf-8'))
try:
if not verify_webhook_1(msg.body, shopify_headers['x-shopify-hmac-sha256'],
env('SHOPIFY_HMAC_SECRET')):
raise AuthenticationFailed()
except Exception as ex:
pass
#!/usr/bin/env python
import os
import hmac
import hashlib
import base64
import json
import flask
SECRET: str = os.environ.get("YOUR_APP_SECRET") # or the hash from the admin webhooks panel
app = flask.Flask(__name__)
def verify_wh(data: bytes, hmac_header: str) -> bool:
if not hmac_header:
return False
digest = hmac.new(SECRET.encode(), data, hashlib.sha256).digest()
computed_hmac = base64.b64encode(digest)
return hmac.compare_digest(computed_hmac, hmac_header.encode())
@app.route("/webhook", methods=["POST"])
def recieve_webhook():
data: dict = flask.request.get_json(force=True)
headers: dict = flask.request.headers
verified = verify_wh(flask.request.get_data(), headers.get("X-Shopify-Hmac-Sha256"))
if not verified:
return flask.make_response(flask.jsonify(message="NOT VERIFIED"), 401)
return flask.make_response(flask.jsonify(message="SUCCESSFUL"), 200)
Maybe this helps:)
Best regards,
LucidMoment