initial commit
This commit is contained in:
148
whmcs-module/hexahost/hexahost.php
Normal file
148
whmcs-module/hexahost/hexahost.php
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user