'HexaHost Proxmox Panel', 'APIVersion' => '1.1', 'RequiresServer' => true, 'DefaultNonSSLPort' => '443', 'DefaultSSLPort' => '443', ]; } function hexahost_ConfigOptions(): array { return [ 'plan_slug' => [ 'FriendlyName' => 'Hosting Plan (Slug)', 'Type' => 'text', 'Size' => '32', 'Description' => 'z.B. small, medium, large', ], 'behind_traefik' => [ 'FriendlyName' => 'Hinter Traefik', 'Type' => 'yesno', 'Description' => 'Subdomain + DNS via Traefik', ], 'provision_mode' => [ 'FriendlyName' => 'Provisionierungsmodus', 'Type' => 'dropdown', 'Options' => 'template,iso,empty', 'Description' => 'template | iso | empty', ], ]; } function hexahost_CreateAccount(array $params): string { $payload = [ 'whmcs_service_id' => (int) $params['serviceid'], 'whmcs_client_id' => (int) $params['clientsdetails']['userid'], 'whmcs_order_id' => (int) ($params['model']['orderid'] ?? 0), 'client_email' => $params['clientsdetails']['email'], 'client_name' => trim($params['clientsdetails']['firstname'].' '.$params['clientsdetails']['lastname']), 'plan_slug' => $params['configoption1'] ?: 'small', 'hostname' => $params['domain'] ?: 'vm-'.$params['serviceid'], 'subdomain' => $params['customfields']['subdomain'] ?? explode('.', $params['domain'])[0] ?? 'vm'.$params['serviceid'], 'behind_traefik' => ($params['configoption2'] ?? '') === 'on', 'provision_mode' => $params['configoption3'] ?: 'template', 'template_slug' => $params['customfields']['template_slug'] ?? null, 'iso_volid' => $params['customfields']['iso_volid'] ?? null, ]; $response = hexahost_apiRequest($params, 'POST', '/api/whmcs/services', $payload); if (! empty($response['error'])) { return $response['error']; } return 'success'; } function hexahost_SuspendAccount(array $params): string { $response = hexahost_apiRequest($params, 'POST', '/api/whmcs/services/'.$params['serviceid'].'/suspend', []); return ! empty($response['error']) ? $response['error'] : 'success'; } function hexahost_UnsuspendAccount(array $params): string { $response = hexahost_apiRequest($params, 'POST', '/api/whmcs/services/'.$params['serviceid'].'/unsuspend', []); return ! empty($response['error']) ? $response['error'] : 'success'; } function hexahost_TerminateAccount(array $params): string { $response = hexahost_apiRequest($params, 'DELETE', '/api/whmcs/services/'.$params['serviceid'], []); return ! empty($response['error']) ? $response['error'] : 'success'; } function hexahost_AdminServicesTabFields(array $params): array { $response = hexahost_apiRequest($params, 'GET', '/api/whmcs/services/'.$params['serviceid'], []); if (! empty($response['customer'])) { return [ 'Panel VMID' => $response['customer']['vmid'] ?? '—', 'Status' => $response['customer']['status'] ?? '—', 'IP' => $response['customer']['ip_address'] ?? '—', ]; } return ['Status' => $response['error'] ?? 'Keine Daten']; } function hexahost_apiRequest(array $params, string $method, string $path, array $body): array { $baseUrl = rtrim($params['serverhostname'] ?: $params['serverip'], '/'); if (! str_starts_with($baseUrl, 'http')) { $baseUrl = 'https://'.$baseUrl; } $secret = $params['serverpassword'] ?: $params['serveraccesshash']; $json = json_encode($body); $timestamp = time(); $signature = hash_hmac('sha256', $timestamp.'.'.$json, $secret); $ch = curl_init($baseUrl.$path); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_POSTFIELDS => $method === 'GET' || $method === 'DELETE' ? null : $json, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Accept: application/json', 'X-Whmcs-Timestamp: '.$timestamp, 'X-Whmcs-Signature: '.$signature, ], CURLOPT_TIMEOUT => 120, CURLOPT_SSL_VERIFYPEER => true, ]); $raw = curl_exec($ch); $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $data = json_decode($raw ?: '{}', true) ?: []; if ($code >= 400) { return ['error' => $data['message'] ?? $data['error'] ?? 'HTTP '.$code]; } return $data; }