encryptData($raw); $enc_norm = $encryptionHelper->encryptData($norm); $sql = "SELECT 1 FROM passenger_blacklist WHERE phone IN (:enc_raw, :enc_norm) AND (expires_at IS NULL OR expires_at > NOW()) LIMIT 1"; $q = $con->prepare($sql); $q->execute([ 'enc_raw' => $enc_raw, 'enc_norm' => $enc_norm, ]); return (bool)$q->fetchColumn(); } /* 0) Get phone number */ $receiver = filterRequest("receiver"); if (!$receiver) { jsonError('Phone number is required.'); exit(); } if (is_blacklisted($con, $encryptionHelper, $receiver)) { jsonError('This phone is blacklisted and cannot receive OTP.'); error_log("[send_otp] BLOCKED (blacklisted): $receiver"); exit(); } /* 1) Generate OTP (3 digits) */ $otp = (string)rand(100, 999); /* 2) Send via Flash Call / WhatsApp Gateway */ $nabehUrl = 'https://otp.intaleqapp.com/api/request-otp.php'; $appKey = getenv('NABEH_OTP_APP_KEY'); $payload = [ 'phone' => $receiver, 'device_type' => 'android', 'method' => 'whatsapp', 'code' => $otp ]; $ch = curl_init($nabehUrl); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', "X-App-Key: $appKey" ], CURLOPT_TIMEOUT => 15, CURLOPT_CONNECTTIMEOUT => 5 ]); $res = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $error = curl_error($ch); curl_close($ch); if ($error) { error_log("⚠️ [Flash Call OTP Passenger] Curl Error: $error"); jsonError('Failed to connect to OTP service'); exit; } $decoded = json_decode((string)$res, true); if ($httpCode !== 200 || !($decoded['success'] ?? false)) { error_log("❌ [Flash Call OTP Passenger] Failed response: Code $httpCode | Body: " . (string)$res); jsonError($decoded['message'] ?? 'Failed to request verification code'); exit; } /* 3) Save OTP (encrypted) */ $receiver_enc = $encryptionHelper->encryptData($receiver); $otp_enc = $encryptionHelper->encryptData($otp); $exp = date('Y-m-d H:i:s', strtotime('+5 minutes')); $now = date('Y-m-d H:i:s'); try { $con->prepare("DELETE FROM phone_verification_passenger WHERE phone_number = ?") ->execute([$receiver_enc]); $stmt = $con->prepare(" INSERT INTO phone_verification_passenger (phone_number, token, expiration_time, verified, created_at) VALUES (?, ?, ?, 0, ?) "); $stmt->execute([$receiver_enc, $otp_enc, $exp, $now]); jsonSuccess(null, 'OTP sent and saved successfully'); error_log("[send_otp] OTP saved successfully for $receiver"); } catch (PDOException $e) { error_log("[send_otp] DB error: ".$e->getMessage()); jsonError('OTP generated but failed to save to database'); }