Answer

In verify_token, HMAC must be computed over the same bytes that were signed at issuance. Replacing payload_bytes = payload_hex.encode() with payload_bytes = bytes.fromhex(payload_hex) fixes verification: encode() UTF-8-encodes the hex text; the signer used the decoded JSON UTF-8 bytes. Use payload_bytes for _sign(...) and json.loads(payload_bytes).

1e2d7a8f-14a2-4990-b560-cc5f778ebfc4

In verify_token, HMAC must be computed over the same bytes that were signed at issuance. Replacing payload_bytes = payload_hex.encode() with payload_bytes = bytes.fromhex(payload_hex) fixes verification: encode() UTF-8-encodes the hex text; the signer used the decoded JSON UTF-8 bytes. Use payload_bytes for _sign(...) and json.loads(payload_bytes).