# Webhook validation fails for php code

**URL:** <https://devforum.zoom.us/t/webhook-validation-fails-for-php-code/94509>\
**Category:** API and Webhooks\
**Tags:** webhooks\
**Created:** [September 6, 2023, 2:23am UTC](https://devforum.zoom.us/t/webhook-validation-fails-for-php-code/94509 "2023-09-06T02:23:50Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![rahuldolas123](https://avatars.discourse-cdn.com/v4/letter/r/ba9def/32.png) [@rahuldolas123](https://devforum.zoom.us/u/rahuldolas123)\
**Post date:** [September 6, 2023, 2:23am UTC](https://devforum.zoom.us/t/webhook-validation-fails-for-php-code/94509/1 "2023-09-06T02:23:50Z")

</div>

Hello Team,

I have gone through the Developer Forum and Developer documentation though I didn’t find any support for PHP sample code for implementing the webhook validation.

Can you direct me to any sample code in PHP for webhook validation?

I would appreciate any help you could give me with this.

I have gone through the node js sample code provided and tried to replicate that code in PHP - still getting the error ‘URL validation failed. Try again later.’

########

```auto
<?PHP

$varname = file_get_contents('php://input');
$zoomData = json_decode($varname, true);

$zoomSecret = ‘X......A’;

$hashForValidate = hash_hmac('sha256', $zoomData['payload']['plainToken'], $zoomSecret);

return ['plainToken' => $plainToken, 'encryptedToken' => $hashForValidate];

?>

```

---

<div class="post-metadata">

**Author:** ![elisa.zoom](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/elisa.zoom/32/47836_2.png) [@elisa.zoom](https://devforum.zoom.us/u/elisa.zoom)\
**Post date:** [September 8, 2023, 3:11pm UTC](https://devforum.zoom.us/t/webhook-validation-fails-for-php-code/94509/2 "2023-09-08T15:11:37Z")

</div>

Hi @rahuldolas123  
Thanks for reaching out!  
Have you taken a look at our sample app here:

> <https://github.com/zoom/webhook-sample/blob/master/index.js#L31>

---

<div class="post-metadata">

**Author:** ![seanevtech](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/seanevtech/32/57483_2.png) [@seanevtech](https://devforum.zoom.us/u/seanevtech)\
**Post date:** [September 19, 2023, 11:34pm UTC](https://devforum.zoom.us/t/webhook-validation-fails-for-php-code/94509/3 "2023-09-19T23:34:04Z")

</div>

I am having a similar issue, I reviewed the node.js example, but I can t get it work with my php file.

```auto
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
include_once('zoom_dbaccess.php');

$authResponse = getAuthToken(true);
$token = $authResponse->response->token;
define("TOKEN", $token);
$zoomSecret = "..." ;

//GET INPUT JSON ENCODED
date_default_timezone_set('US/Pacific');
$currenttime = date('h:i:s:u');
$_GET['currentTime'] = $currenttime;

$data = (!empty(file_get_contents('php://input')) ? file_get_contents('php://input') : json_encode($_REQUEST)) ;
// $data = '{"event":"endpoint.url_validation","event_ts":1695163211051,"payload":{"plainToken":"e7cSuLyCSUelSN0Qfmkr9Q"}}' ;
// Decode the JSON
$dataDecode = json_decode($data, true);
// Access the data
$event = $dataDecode['event'];

if ($event == 'endpoint.url_validation') {
   $payload = $dataDecode['payload'];
   $plainToken = $payload['plainToken'];
   $encryptedtoken = hash_hmac('sha256', $plainToken, $zoomSecret, false);
   // echo "<pre>".print_r($event,true)."</pre>";
   // echo "<pre>".print_r($plainToken,true)."</pre>";
   // echo "<pre>".print_r($encryptedtoken,true)."</pre>";
   $result = array("plainToken"=>$plainToken, "encryptedtoken"=>$encryptedtoken);
   $result = json_encode($result);
   echo $result;
} else {
   $url = BASEURL."/fmi/data/v1/databases/".DATABASE."/layouts/Web_Use__ZOOMLOG/records";

   $postData = json_encode(array("fieldData" => array( "json" => $data ), "script" => "ZoomLog | Incoming Log" ));

   $curl = curl_init();
   curl_setopt_array($curl, array(
      CURLOPT_URL => $url,
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_ENCODING => "",
      CURLOPT_MAXREDIRS => 10,
      CURLOPT_TIMEOUT => 30,
      CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
      CURLOPT_USERPWD => USER . ":" . PASSWORD,
      CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
      CURLOPT_SSL_VERIFYHOST => 0,
      CURLOPT_SSL_VERIFYPEER => 0,
      CURLOPT_CUSTOMREQUEST => "POST",
      CURLOPT_POSTFIELDS => $postData,
      CURLOPT_HTTPHEADER => array(
         "Content-Type: application/json",
         "Authorization: Bearer " . TOKEN
      ),
   ));

   $response = curl_exec($curl);
   $err = curl_error($curl);
   curl_close($curl);

   echo "<pre>".print_r($response,true)."</pre>";

// Log the call
   $log = 
   "Action:POST".PHP_EOL.
   "URL: ".$url.PHP_EOL.
   "token:".$token.PHP_EOL.
   "Post Fields: ".$postData.PHP_EOL.
   "Result: ".$response.PHP_EOL.
   "Error: ".$err.PHP_EOL.
   "-------------------------".PHP_EOL;

   file_put_contents('log_zoom_'.date("j.n.Y").'.txt', $log, FILE_APPEND);

//Disconnect the session
   $url = BASEURL."/fmi/data/v1/databases/".DATABASE."/sessions/". TOKEN;

   $curl = curl_init();
   curl_setopt_array($curl, array(
      CURLOPT_URL => $url,
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_ENCODING => "",
      CURLOPT_MAXREDIRS => 10,
      CURLOPT_TIMEOUT => 30,
      CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
      CURLOPT_USERPWD => USER . ":" . PASSWORD,
      CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
      CURLOPT_SSL_VERIFYHOST => 0,
      CURLOPT_SSL_VERIFYPEER => 0,
      CURLOPT_CUSTOMREQUEST => "DELETE",
      CURLOPT_HTTPHEADER => array(
         "Content-Type: application/json",
         "Authorization: Bearer " . TOKEN
      ),
   ));
   $response = curl_exec($curl);
   $err = curl_error($curl);
   curl_close($curl);

// Decode the JSON
   $data = json_decode($response, true);
// Access the data
// $scriptResult = $data['response'];

   echo "<pre>".print_r($data ,true)."</pre>";

// Log the call
   $log = 
   "Action:DELETE".PHP_EOL.
   "URL: ".$url.PHP_EOL.
   "token:".$token.PHP_EOL.
   // "Post Fields: ".$postData.PHP_EOL.
   "Result: ".$response.PHP_EOL.
   "Error: ".$err.PHP_EOL.
   "-------------------------".PHP_EOL;

   file_put_contents('log_zoom_'.date("j.n.Y").'.txt', $log, FILE_APPEND);
}

?>

```

---

<div class="post-metadata">

**Author:** ![chunsiong.zoom](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/chunsiong.zoom/32/35488_2.png) [@chunsiong.zoom](https://devforum.zoom.us/u/chunsiong.zoom)\
**Post date:** [September 20, 2023, 6:27am UTC](https://devforum.zoom.us/t/webhook-validation-fails-for-php-code/94509/4 "2023-09-20T06:27:41Z")

</div>

@rahuldolas123 @seanevtech

could you try something like this?

````auto
<?php

$config = include 'config.php';
$secretToken= $config['webhook_app_secret_token'];
// Get the raw POST data from the request
$input = file_get_contents("php://input");

    // Decode the JSON data
    $data = json_decode($input);

    // Check if the event type is "endpoint.url_validation"
    if ($data && isset($data->event) && $data->event === "endpoint.url_validation") {
        // Check if the payload contains the "plainToken" property
        if (isset($data->payload) && isset($data->payload->plainToken)) {
            // Get the plainToken from the payload
            $plainToken = $data->payload->plainToken;

           
            // Hash the plainToken using HMAC-SHA256
            $encryptedToken = hash_hmac("sha256", $plainToken, $secretToken);

            // Create the response JSON object
            $response = [
                "plainToken" => $plainToken,
                "encryptedToken" => $encryptedToken
            ];

            // Set the response HTTP status code to 200 OK
            http_response_code(200);

            // Set the response content type to JSON
            header("Content-Type: application/json");

            // Output the response JSON
            echo json_encode($response);
        } else {
            // Payload is missing the "plainToken" property
            http_response_code(400); // Bad Request
            echo "Payload is missing 'plainToken' property.";
        }
    } else {
        // Invalid event type
        http_response_code(400); // Bad Request
        echo "Invalid event type.";
    }

?>```
````

---

<div class="post-metadata">

**Author:** ![seanevtech](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/seanevtech/32/57483_2.png) [@seanevtech](https://devforum.zoom.us/u/seanevtech)\
**Post date:** [September 20, 2023, 3:40pm UTC](https://devforum.zoom.us/t/webhook-validation-fails-for-php-code/94509/5 "2023-09-20T15:40:17Z")

</div>

YES, thank you so much, this worked!!!

---

<div class="post-metadata">

**Author:** ![rahuldolas123](https://avatars.discourse-cdn.com/v4/letter/r/ba9def/32.png) [@rahuldolas123](https://devforum.zoom.us/u/rahuldolas123)\
**Post date:** [September 20, 2023, 9:08pm UTC](https://devforum.zoom.us/t/webhook-validation-fails-for-php-code/94509/6 "2023-09-20T21:08:51Z")

</div>

Thank you @elisa.zoom and @chunsiong.zoom

The PHP code you posted works fine, creating a $response JSON object, and setting the http\_response\_code as 200. But still, when I validate it, I get the same error message as ‘URL validation failed. Try again later.’

 ![image](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/0/4/042c46c30389564ee063d34fa6212a082d6344af.png)

Still trying to figure out and debug.

---

<div class="post-metadata">

**Author:** ![chunsiong.zoom](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/chunsiong.zoom/32/35488_2.png) [@chunsiong.zoom](https://devforum.zoom.us/u/chunsiong.zoom)\
**Post date:** [September 21, 2023, 3:24am UTC](https://devforum.zoom.us/t/webhook-validation-fails-for-php-code/94509/7 "2023-09-21T03:24:06Z")

</div>

@rahuldolas123 ,

I would double check the secret token.  
It is under the Feature menu

---

<div class="post-metadata">

**Author:** ![seanevtech](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/seanevtech/32/57483_2.png) [@seanevtech](https://devforum.zoom.us/u/seanevtech)\
**Post date:** [March 12, 2024, 4:48pm UTC](https://devforum.zoom.us/t/webhook-validation-fails-for-php-code/94509/8 "2024-03-12T16:48:20Z")

</div>

This has been working great for some time, now suddenly with no changes I am getting validation error.

 ![Screenshot 2024-03-12 at 10.34.01 AM](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/3/8/38b7b107e5a319d023cf2ccea7569b6a1a14ff11.png)

\<?php ini\_set('display\_errors', 1); ini\_set('display\_startup\_errors', 1); error\_reporting(E\_ALL); include\_once('zoom\_dbaccess.php'); $authResponse = getAuthToken(true); $token = $authResponse-\>response-\>token; define("TOKEN", $token); $secretToken = "REDACTED"; //GET INPUT JSON ENCODED date\_default\_timezone\_set('US/Pacific'); $currenttime = date('h:i:s:u'); $\_GET['currentTime'] = $currenttime; $data = (!empty(file\_get\_contents('php://input')) ? file\_get\_contents('php://input') : json\_encode($\_REQUEST)); // $data = '{"event":"endpoint.url\_validation","event\_ts":1695163211051,"payload":{"plainToken":"e7cSuLyCSUelSN0Qfmkr9Q"}}' ; // Decode the JSON $dataDecode = json\_decode($data, true); // Access the data $event = $dataDecode['event']; // Log the call $log = "Action:ALL" . PHP\_EOL . "Event: " . $event . PHP\_EOL . "data:" . json\_encode($dataDecode) . PHP\_EOL . "plainToken: " . $plainToken . PHP\_EOL . "Time: " . date('Y-m-d H:i:s') . PHP\_EOL . "-------------------------" . PHP\_EOL; file\_put\_contents('logs/zoom\_all\_log\_' . date("j.n.Y") . '.txt', $log, FILE\_APPEND); if ($event == 'endpoint.url\_validation') { // Get the plainToken from the payload $payload = $dataDecode['payload']; $plainToken = $payload['plainToken']; // Hash the plainToken using HMAC-SHA256 $encryptedToken = hash\_hmac("sha256", $plainToken, $secretToken); // Create the response JSON object $response = ["plainToken" =\> $plainToken, "encryptedToken" =\> $encryptedToken]; // Set the response HTTP status code to 200 OK http\_response\_code(200); // Set the response content type to JSON header("Content-Type: application/json"); // Output the response JSON echo json\_encode($response); } else { $url = BASEURL . "/fmi/data/v1/databases/" . DATABASE . "/layouts/Web\_Use\_\_ZOOMLOG/records"; $postData = json\_encode(array("fieldData" =\> array("json" =\> $data), "script" =\> "ZoomLog | Incoming Log")); $curl = curl\_init(); curl\_setopt\_array($curl, array( CURLOPT\_URL =\> $url, CURLOPT\_RETURNTRANSFER =\> true, CURLOPT\_ENCODING =\> "", CURLOPT\_MAXREDIRS =\> 10, CURLOPT\_TIMEOUT =\> 30, CURLOPT\_HTTPAUTH =\> CURLAUTH\_BASIC, CURLOPT\_USERPWD =\> USER . ":" . PASSWORD, CURLOPT\_HTTP\_VERSION =\> CURL\_HTTP\_VERSION\_1\_1, CURLOPT\_SSL\_VERIFYHOST =\> 0, CURLOPT\_SSL\_VERIFYPEER =\> 0, CURLOPT\_CUSTOMREQUEST =\> "POST", CURLOPT\_POSTFIELDS =\> $postData, CURLOPT\_HTTPHEADER =\> array( "Content-Type: application/json", "Authorization: Bearer " . TOKEN ), )); $response = curl\_exec($curl); $err = curl\_error($curl); curl\_close($curl); echo "
```
" . print_r($response, true) . "
```
"; // Log the call $log = "Action:POST" . PHP\_EOL . "URL: " . $url . PHP\_EOL . "token:" . $token . PHP\_EOL . "Post Fields: " . $postData . PHP\_EOL . "Result: " . $response . PHP\_EOL . "Error: " . $err . PHP\_EOL . "Time: " . date('Y-m-d H:i:s') . PHP\_EOL . "-------------------------" . PHP\_EOL; file\_put\_contents('logs/zoom\_log\_' . date("j.n.Y") . '.txt', $log, FILE\_APPEND); //Disconnect the session $url = BASEURL . "/fmi/data/v1/databases/" . DATABASE . "/sessions/" . TOKEN; $curl = curl\_init(); curl\_setopt\_array($curl, array( CURLOPT\_URL =\> $url, CURLOPT\_RETURNTRANSFER =\> true, CURLOPT\_ENCODING =\> "", CURLOPT\_MAXREDIRS =\> 10, CURLOPT\_TIMEOUT =\> 30, CURLOPT\_HTTPAUTH =\> CURLAUTH\_BASIC, CURLOPT\_USERPWD =\> USER . ":" . PASSWORD, CURLOPT\_HTTP\_VERSION =\> CURL\_HTTP\_VERSION\_1\_1, CURLOPT\_SSL\_VERIFYHOST =\> 0, CURLOPT\_SSL\_VERIFYPEER =\> 0, CURLOPT\_CUSTOMREQUEST =\> "DELETE", CURLOPT\_HTTPHEADER =\> array( "Content-Type: application/json", "Authorization: Bearer " . TOKEN ), )); $response = curl\_exec($curl); $err = curl\_error($curl); curl\_close($curl); // Decode the JSON $data = json\_decode($response, true); // Access the data // $scriptResult = $data['response']; echo "
```
" . print_r($data, true) . "
```
"; // Log the call $log = "Action:DELETE" . PHP\_EOL . "URL: " . $url . PHP\_EOL . "token:" . $token . PHP\_EOL . // "Post Fields: ".$postData.PHP\_EOL. "Result: " . $response . PHP\_EOL . "Error: " . $err . PHP\_EOL . "Time: " . date('Y-m-d H:i:s') . PHP\_EOL . "-------------------------" . PHP\_EOL; file\_put\_contents('logs/zoom\_log\_' . date("j.n.Y") . '.txt', $log, FILE\_APPEND); }

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/6/1/614bdd549b610bbaa46ff934617683a02bdaa03c.png) [@system](https://devforum.zoom.us/u/system)\
**Post date:** [March 16, 2025, 8:24am UTC](https://devforum.zoom.us/t/webhook-validation-fails-for-php-code/94509/9 "2025-03-16T08:24:37Z")

</div>

This topic was automatically closed 368 days after the last reply. New replies are no longer allowed.
