Reminding readers to verify the HMAC against the raw body, before any JSON parsing, saves people a common hour of debugging. There is one trap in the snippet itself. crypto.timingSafeEqual throws a RangeError when the two buffers have different lengths, so a request with a missing or malformed header never reaches the 401 branch. In Express 4 a rejection from an async handler is not caught for you, so that request can hang instead of being refused. Checking the lengths first and returning 401 on a mismatch fixes it. I would also move processOrderEvent after the response. Shopify expects a reply within a few seconds and retries otherwise, and waiting on a WhatsApp API call inside the handler is the easiest way to cause the duplicate deliveries your section 7 then has to clean up.