You’re doing the verification step wrong.
When Twitch sends a GET request to your callback URL, containing a hub.challenge, your server needs to respond to that request from Twitch by returning the hub.challenge in the body.
You don’t send it as a querystring on anything, you don’t need to make any more requests yourself, you simply respond to Twitch’s GET request to you with the challenge in the body. If Twitch doesn’t get back JUST the hub.challenge and a 200 response when it sends a GET request to your callback URL, it assumes either the callback url isn’t accessible, or isn’t set up to handle webhooks, and so the subscription process fails.