'image/jpeg', 'png' => 'image/png', default => 'application/octet-stream', }; $prompts = [ "id_front_sy" => << << << << << << [ ["role" => "user", "parts" => [["text" => $prompt]]], ["role" => "user", "parts" => [["inlineData" => ["mimeType" => $mimeType, "data" => $imageBase64]]]] ] ]; $ch = curl_init($apiURL); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); $response = curl_exec($ch); if (curl_errno($ch)) { $error_msg = curl_error($ch); error_log("CURL error: $error_msg"); jsonError("AI Error: $error_msg"); curl_close($ch); exit; } curl_close($ch); error_log("AI raw response: $response"); $data = json_decode($response, true); if (json_last_error() !== JSON_ERROR_NONE) { error_log("JSON decode error: " . json_last_error_msg()); jsonError("Failed to parse AI response"); exit; } $textRaw = $data['candidates'][0]['content']['parts'][0]['text'] ?? ''; $textRaw = trim(preg_replace('/```json|```/', '', $textRaw)); $json = json_decode($textRaw, true); $requiredKey = match ($type) { 'id_front_sy' => 'national_number', 'id_back_sy' => 'gender', 'driving_license_sy' => 'license_type', 'vehicle_license_sy' => 'chassis', default => null, }; if (!$json || ($requiredKey && !isset($json[$requiredKey]))) { error_log("AI response missing required key '$requiredKey': $textRaw"); jsonError("AI failed to extract required information"); exit; } printSuccess([ "image_url" => $imageUrl, "data" => $json ]);