When the oAuth token is created, the expiry time is managed in Milliseconds
But, the response object is saying 'expires_in=3600' to it, which is only 3.6 seconds, instead of one hour.
This needs to be multiplied by 1000 before using it in setExpiryTime()
For helping people google this problem, you'll see this trigger {"error":"access_denied"} randomly, or with the exception "Exception while fetching access token from refresh token"
The fix is to change that line (Line 119) to this in vendor/zohocrm/php-sdk/src/oauth/ZohoOAuthClient.php
$oAuthTokens->setExpiryTime($oAuthTokens->getCurrentTimeInMillis() + ( $expiresIn * 1000 ));