WHMCS Module for HestiaCP

Is there an official WHMCS module for HestiaCP ?

If not available, can someone give me a guide on how to get it to work. I tried doing something to make it work but I’m not too familiar with how it’ll work.

I only got the auto login working. So users can automatically login to their HestiaCP account from their WHMCS account.

But I want to be able do the following from my WHMCS admin:

Create account
Suspend account
Terminate account
Modify account

Here’s my current HestiaCP server module for WHMCS

<?php

function hestia_MetaData()
{
    return array(
        'DisplayName' => 'HestiaCP',
        'APIVersion' => '1.0',
        'RequiresServer' => true,
        'DefaultNonSSLPort' => '8083',
        'DefaultSSLPort' => '8083',
        'ServiceSingleSignOnLabel' => 'Login as User',
        'AdminSingleSignOnLabel' => 'Login as Admin',
    );
}


function hestia_ConfigOptions() {

    $configarray = array(
     "Package Name" => array( "Type" => "text", "Default" => "default"),
     "SSH Access" => array( "Type" => "yesno", "Description" => "Tick to grant access", ),
     "IP Address (optional)" => array( "Type" => "text" ),
    );
    return $configarray;

}

function hestia_CreateAccount($params) {

    // Execute only if there is assigned server
    if ($params["server"] == 1) {

        // Prepare variables
        $postvars = array(
          'user' => $params["serverusername"],
          'password' => $params["serverpassword"],
          'hash' => $params["serveraccesshash"],
          'cmd' => 'v-add-user',
          'arg1' => $params["username"],
          'arg2' => $params["password"],
          'arg3' => $params["clientsdetails"]["email"],
          'arg4' => $params["configoption1"],
          'arg5' => $params["clientsdetails"]["firstname"],
          'arg6' => $params["clientsdetails"]["lastname"],
        );
        $postdata = http_build_query($postvars);

        // Create user account
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, 'https://' . $params["serverhostname"] . ':8083/api/');
        curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
        $answer = curl_exec($curl);

		logModuleCall('hestia','CreateAccount_UserAccount','https://'.$params["serverhostname"].':8083/api/'.$postdata,$answer);

        // Enable ssh access
        if(($answer == 'OK') && ($params["configoption2"] == 'on')) {
            $postvars = array(
              'user' => $params["serverusername"],
              'password' => $params["serverpassword"],
              'hash' => $params["serveraccesshash"],
              'cmd' => 'v-change-user-shell',
              'arg1' => $params["username"],
              'arg2' => 'bash'
            );
            $postdata = http_build_query($postvars);
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, 'https://' . $params["serverhostname"] . ':8083/api/');
            curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($curl, CURLOPT_POST, true);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
            $answer = curl_exec($curl);

            logModuleCall('hestia','CreateAccount_EnableSSH','https://'.$params["serverhostname"].':8083/api/'.$postdata,$answer);
        }

        // Add domain
        if(($answer == 'OK') && (!empty($params["domain"]))) {
            $postvars = array(
              'user' => $params["serverusername"],
              'password' => $params["serverpassword"],
              'hash' => $params["serveraccesshash"],
              'cmd' => 'v-add-domain',
              'arg1' => $params["username"],
              'arg2' => $params["domain"],
              'arg3' => $params["configoption3"],
            );
            $postdata = http_build_query($postvars);
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, 'https://' . $params["serverhostname"] . ':8083/api/');
            curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($curl, CURLOPT_POST, true);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
            $answer = curl_exec($curl);

            logModuleCall('hestia','CreateAccount_AddDomain','https://'.$params["serverhostname"].':8083/api/'.$postdata,$answer);
        }
    }

    if($answer == 'OK') {
        $result = "success";
    } else {
        $result = $answer;
    }

    return $result;
}

function hestia_TerminateAccount($params) {

    // Execute only if there is assigned server
    if ($params["server"] == 1) {

        // Prepare variables
        $postvars = array(
          'user' => $params["serverusername"],
          'password' => $params["serverpassword"],
          'hash' => $params["serveraccesshash"],
          'cmd' => 'v-delete-user',
          'arg1' => $params["username"]
        );
        $postdata = http_build_query($postvars);

        // Delete user account
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, 'https://' . $params["serverhostname"] . ':8083/api/');
        curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
        $answer = curl_exec($curl);
    }

	logModuleCall('hestia','TerminateAccount','https://'.$params["serverhostname"].':8083/api/'.$postdata,$answer);

    if($answer == 'OK') {
        $result = "success";
    } else {
        $result = $answer;
    }

    return $result;
}

function hestia_SuspendAccount($params) {

    // Execute only if there is assigned server
    if ($params["server"] == 1) {

        // Prepare variables
        $postvars = array(
          'user' => $params["serverusername"],
          'password' => $params["serverpassword"],
          'hash' => $params["serveraccesshash"],
          'cmd' => 'v-suspend-user',
          'arg1' => $params["username"]
        );
        $postdata = http_build_query($postvars);

        // Susupend user account
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, 'https://' . $params["serverhostname"] . ':8083/api/');
        curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
        $answer = curl_exec($curl);
    }

	logModuleCall('hestia','SuspendAccount','https://'.$params["serverhostname"].':8083/api/'.$postdata,$answer);

    if($answer == 'OK') {
        $result = "success";
    } else {
        $result = $answer;
    }

    return $result;
}

function hestia_UnsuspendAccount($params) {

    // Execute only if there is assigned server
    if ($params["server"] == 1) {

        // Prepare variables
        $postvars = array(
          'user' => $params["serverusername"],
          'password' => $params["serverpassword"],
          'hash' => $params["serveraccesshash"],
          'cmd' => 'v-unsuspend-user',
          'arg1' => $params["username"]
        );
        $postdata = http_build_query($postvars);

        // Unsusupend user account
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, 'https://' . $params["serverhostname"] . ':8083/api/');
        curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
        $answer = curl_exec($curl);
    }

    logModuleCall('hestia','UnsuspendAccount','https://'.$params["serverhostname"].':8083/api/'.$postdata,$answer);

    if($answer == 'OK') {
        $result = "success";
    } else {
        $result = $answer;
    }

    return $result;
}

function hestia_ChangePassword($params) {

    // Execute only if there is assigned server
    if ($params["server"] == 1) {

        // Prepare variables
        $postvars = array(
          'user' => $params["serverusername"],
          'password' => $params["serverpassword"],
          'hash' => $params["serveraccesshash"],
          'cmd' => 'v-change-user-password',
          'arg1' => $params["username"],
          'arg2' => $params["password"]
        );
        $postdata = http_build_query($postvars);

        // Change user package
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, 'https://' . $params["serverhostname"] . ':8083/api/');
        curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
        $answer = curl_exec($curl);
    }

	logModuleCall('hestia','ChangePassword','https://'.$params["serverhostname"].':8083/api/'.$postdata,$answer);

    if($answer == 'OK') {
        $result = "success";
    } else {
        $result = $answer;
    }
    
    return $result;
}

function hestia_ChangePackage($params) {

    // Execute only if there is assigned server
    if ($params["server"] == 1) {

        // Prepare variables
        $postvars = array(
          'user' => $params["hstadmin"],
          'password' => $params["hstadminpw"],
          'returncode' => 'no',
          'hash' => $params["serveraccesshash"],
          'cmd' => 'v-check-user-password',
          'arg1' => $params["username"],
          'arg2' => $params["password"]
        );
        $postdata = http_build_query($postvars);

        // Change user package
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_HEADER,false);
        curl_setopt($curl, CURLOPT_URL, 'https://' . $params["hostname"] . ':8083/api/');
        curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
        $answer = curl_exec($curl);
    }

	logModuleCall('hestia','ChangePackage','https://'.$params["hostname"].':8083/api/'.$postdata,$answer);

    if($answer == 'OK') {
        $result = "success";
    } else {
        $result = $answer;
    }

    return $result;
}

function hestia_ClientArea($params) {

$code = '
<form action="https://'.$params["serverhostname"].':8083/login/" method="post" target="_blank" class="cyberpanel">
<input type="hidden" name="user" value="'.$params["username"].'" />
<input type="hidden" name="password" value="'.$params["password"].'" />
<input type="hidden" name="api" value="1" />
<input type="submit" value="Login to Control Panel" />
</form>';
return $code;

}

/*<input type="button" value="Webmail" onClick="window.open(\'https://webmail.'.$params["domain"].'/\')" />
<input type="button" value="Phpmyadmin" onClick="window.open(\'https://'.$params["domain"].'/phpmyadmin\')" />*/

function hestia_AdminLink($params) {

$code = '<form action="https://'.$params["serverhostname"].':8083/login/" method="post" target=\"_blank\">
<input type="hidden" name="user" value="'.$params["serverusername"].'" />
<input type="hidden" name="password" value="'.$params["serverpassword"].'" />
<input type="hidden" name="api" value="1" />
<input type="submit" value="Login to Control Panel" />
</form>';


return $code;

}

function hestia_LoginLink($params) {
$code = '
<style>#btnLoginLinkTrigger { display: none }</style>
<form action="https://'.$params["serverhostname"].':8083/login/" method="post" target="_blank" class="cyberpanel">
<input type="hidden" name="user" value="'.$params["username"].'" />
<input type="hidden" name="password" value="'.$params["password"].'" />
<input type="hidden" name="api" value="1" />
<input type="submit" style="padding:2px 5px;margin-right:15px;margin-bottom:5px;background-color:green;color:#fff;border:none;border-radius:20px" value="Login to Control Panel" />
</form>';
echo $code;
}

function hestia_UsageUpdate($params) {

    // Prepare variables
    $postvars = array(
      'user' => $params["serverusername"],
      'password' => $params["serverpassword"],
      'hash' => $params["serveraccesshash"],
      'cmd' => 'v-list-users',
      'arg1' => 'json'
    );
    $postdata = http_build_query($postvars);

    // Get user stats
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'https://' . $params["serverhostname"] . ':8083/api/');
    curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
    $answer = curl_exec($curl);

    // Decode json data
    $results = json_decode($answer, true);

    // Loop through results and update DB
    foreach ($results AS $user=>$values) {
        update_query("tblhosting",array(
          "diskusage"=>$values['U_DISK'],
          "disklimit"=>$values['DISK_QUOTA'],
          "bwusage"=>$values['U_BANDWIDTH'],
          "bwlimit"=>$values['BANDWIDTH'],
          "lastupdate"=>"now()",
        ),array("server"=>$params['serverid'], "username"=>$user));
    }

}

?>

The http://c.vestacp.com/0.9.8/rhel/whmcs-module.php should still work

Autologin shouldn’t be possible as we regenerate the csrf token every refresh…

What should I add as hash: 'hash' => $params["serveraccesshash"], ?

v-generate-api-key generates an api key

However It doesn’t support the new access key yet …

Generated the API key and used it as hash in my WHMCS module settings, but I get this error when I try to create account:

image_2023-09-02_141052155

I have never used the module except for a few year ago and then it worked fine…

were you able to get it working? I get the same “Function Not Supported by Module” when I try to accept an order with the hestia module.