initial commit

This commit is contained in:
TheOnlyMace
2026-05-17 13:26:14 +02:00
commit 75299b723d
176 changed files with 20327 additions and 0 deletions

View File

@@ -0,0 +1,148 @@
<?php
/**
* HexaHost Panel WHMCS 9.x Server Module
*
* Installation: Kopieren nach /modules/servers/hexahost/
* Konfiguration in WHMCS: Server Panel URL + API Secret
*/
if (! defined('WHMCS')) {
die('This file cannot be accessed directly');
}
function hexahost_MetaData(): array
{
return [
'DisplayName' => '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;
}