apiKey = getenv('OTPIQ_API_KEY') ?: ''; $this->senderId = getenv('OTPIQ_SENDER_ID') ?: 'URUK-PRIZE'; $this->endpoint = getenv('OTPIQ_ENDPOINT') ?: 'https://api.otpiq.com/api/sms'; } /** * Sends OTP via OTPIQ with Smart Fallback (WhatsApp first, then SMS). */ public function sendOtp(string $phoneNumber, string $otpCode): array { // If API key is not configured, run in Mock / Dev mode if (empty($this->apiKey)) { error_log("[MOCK OTPIQ] Sent OTP {$otpCode} to {$phoneNumber} via WhatsApp/SMS Smart Fallback."); return [ 'success' => true, 'mode' => 'mock', 'phone' => $phoneNumber, 'otp' => $otpCode, 'provider' => 'mock-smart-fallback', ]; } $payload = [ 'recipient' => $phoneNumber, 'sender_id' => $this->senderId, 'type' => 'otp', 'code' => $otpCode, 'message' => "رمز التحقق الخاص بك لجائزة أوروك الدولية هو: {$otpCode}. لا تشاركه مع أحد.", 'channels' => ['whatsapp', 'sms'], // Smart fallback pipeline ]; $ch = curl_init($this->endpoint); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Authorization: Bearer ' . $this->apiKey, ], CURLOPT_TIMEOUT => 10, ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $error = curl_error($ch); curl_close($ch); if ($error || $httpCode >= 400) { return [ 'success' => false, 'error' => $error ?: "HTTP {$httpCode}: " . substr((string)$response, 0, 100), ]; } $data = json_decode((string)$response, true); return [ 'success' => true, 'data' => $data, ]; } }