While implementing a TOTP application, please note that hash_hmac() must receive data in binary, not in a hexadecimal string, to generate a valid OTP across platforms.
This problem can be easily fixed by converting a hexadecimal string to its binary form before passing it to hash_hmac().
<?php
$time = hex2bin('0000000003523f77'); // time must be in this "hexadecimal and padded" form
$key = hex2bin('bb57d1...'); // 160-bits = 40-digit hexadecimal (4 bits) = 32-digit base32 (5 bits)
hash_hmac('sha1', $time, $key);
?>