self::$sessionKey, 'phone' => $cleanPhone ]); $ch = curl_init(self::$gatewayUrl . '/api/contacts/check'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'X-Webhook-Secret: ' . self::$secret ]); curl_setopt($ch, CURLOPT_TIMEOUT, 5); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode === 200 && $response) { $data = json_decode($response, true); if (isset($data['status']) && $data['status'] === 'success') { return isset($data['data']['exists']) && $data['data']['exists'] === true; } } return false; } /** * Send OTP message via WhatsApp Gateway. * * @param string $phone Destination phone number * @param string $message Message text * @param string|null $imageBase64 Optional base64 image data * @return bool True if successfully sent */ public static function sendMessage($phone, $message, $imageBase64 = null) { self::init(); $cleanPhone = preg_replace('/[^\d]/', '', $phone); $payloadData = [ 'session_key' => self::$sessionKey, 'phone' => $cleanPhone, 'message' => $message ]; if ($imageBase64) { $payloadData['image'] = $imageBase64; } $payload = json_encode($payloadData); $ch = curl_init(self::$gatewayUrl . '/api/messages/send'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'X-Webhook-Secret: ' . self::$secret ]); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode === 200 && $response) { $data = json_decode($response, true); return isset($data['status']) && $data['status'] === 'success'; } return false; } /** * Generate dynamic base64-encoded image containing OTP code using GD library. * * @param string $otp 4-digit OTP code * @return string Base64 encoded PNG image */ public static function generateOtpImageBase64($otp) { // Create a 300x100 image $im = imagecreatetruecolor(300, 100); if (!$im) { return ''; } // Colors $bgColor = imagecolorallocate($im, 240, 244, 248); // Soft grey-blue $textColor = imagecolorallocate($im, 33, 37, 41); // Dark charcoal $accentColor = imagecolorallocate($im, 13, 110, 253); // Premium blue $noiseColor = imagecolorallocate($im, 200, 210, 220); // Light noise // Fill background imagefill($im, 0, 0, $bgColor); // Draw some obfuscation lines / background noise for ($i = 0; $i < 6; $i++) { imageline($im, random_int(0, 300), random_int(0, 100), random_int(0, 300), random_int(0, 100), $noiseColor); } // Draw some random dots for ($i = 0; $i < 100; $i++) { imagesetpixel($im, random_int(0, 300), random_int(0, 100), $noiseColor); } // Header text (smaller) imagestring($im, 3, 20, 15, "Verification Code:", $textColor); // Large OTP text (using larger font index 5 or custom size if possible) // Split OTP and draw characters with varying Y positions and styling to make OCR harder $chars = str_split($otp); $x = 90; foreach ($chars as $char) { $y = random_int(35, 45); imagestring($im, 5, $x, $y, $char, $accentColor); $x += 30; } // Draw a bounding border imagerectangle($im, 0, 0, 299, 99, $noiseColor); // Capture output ob_start(); imagepng($im); $imageData = ob_get_clean(); imagedestroy($im); return base64_encode($imageData); } }