Might I suggest using the Guzzle HTTP library. It is relatively simple to understand and implement. I use it for subscriptions (and various other things in my app) and Symfony/Illuminate (Laravel back end) handles everything inbound.
But here’s the call I make using Guzzle:
(NOTE: these are synchronous calls. I use them as a personal preference in this situation, but Guzzle also supports asynchronous requests, so make sure you know how to handle Promises properly in PHP before going that route!)
try {
$response = $this->client->request('POST', Constants::TWITCH_HELIX_WEBHOOKS, [
'headers' => [
'Content-Type' => 'application/json',
'Client-ID' => '<your client id>',
'Authorization' => 'Bearer ' . '<your app token>',
],
'query' => [
'hub.callback' => '<callback url>',
'hub.mode' => 'subscribe',
'hub.topic' => '<the topic you are subscribing to>',
'hub.lease_seconds' => 864000
]
]);
if ($response->getStatusCode() === 202) {
<Subscription accepted; do stuff>
} else if ($response->getStatusCode() === 200) {
<Subscription denied; do stuff>
} else {
<handle anything not covered by 202 or 200>
}
} catch (ServerException $e) {
<handle any exceptions you get in>
}
There won’t be a payload returned. Everything you need is in the query string and headers and shuld be parsed as Barry mentioned above.
To receive the payload from Twitch, use the method Barry mentioned above (note that the payload from php://input will contain both headers and the body in one string so you’ll need to properly handle that before parsing to JSON) then parse it to a JSON object and use standard PHP stuff to access the variables in the object. It comes in as POST. Make sure to send back a HTTP 200 (or any 20X code you deem appropriate) when you’ve accepted the payload! (otherwise Twitch may just assume that your application failed to receive it and attempt to resend it!!!)
As for sending an HTTP status code back to Twitch, I use built in stuff in Laravel, but i would definitely start looking here for your answer. As for responding with the challenge, I believe that echoing it should be sufficient.
Hope this helps you out some.