Webhook validation fails for php code

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.’

########

<?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];


?>
1 Like

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

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

<?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);
}

?>

@rahuldolas123 @seanevtech

could you try something like this?

<?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.";
    }

?>```
1 Like

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

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.’

Still trying to figure out and debug.

@rahuldolas123 ,

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

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

<?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); }