Hash the raw bytes exactly as they arrived. The provider signed those bytes. Parsing the JSON and serialising it again changes whitespace, key order and number formatting, so the hash differs even though the content is the same.
Most frameworks can give you the raw body before parsing. Then compute the signature and compare in constant time:
import hashlib
import hmac
expected = hmac.new(secret, raw_body, hashlib.sha256).hexdigest()
valid = hmac.compare_digest(expected, received_signature)
secret and raw_body are bytes. hmac.compare_digest compares in constant time, which a plain == does not. Read the provider's documentation for what exactly is signed (some sign a timestamp plus the body), and reject requests whose timestamp is old, so a captured request cannot be replayed.