0% found this document useful (0 votes)
750 views

Provisioning Module Developer Docs - WHMCS Documentation

This document provides information about developing provisioning modules for WHMCS. Provisioning modules enable provisioning and management of services and have functions for creating, suspending, terminating accounts and more. The document outlines the required and optional functions, parameters passed to functions, and other aspects of developing WHMCS provisioning modules.

Uploaded by

JayBeeDe
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
750 views

Provisioning Module Developer Docs - WHMCS Documentation

This document provides information about developing provisioning modules for WHMCS. Provisioning modules enable provisioning and management of services and have functions for creating, suspending, terminating accounts and more. The document outlines the required and optional functions, parameters passed to functions, and other aspects of developing WHMCS provisioning modules.

Uploaded by

JayBeeDe
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

Documentation

Search WHMCS Documentation

Search

Provisioning Module Developer Docs


Provisioning Modules, enable provisioning and management of services in WHMCS.
Provisioning Modules are also referred to as Product or Server Modules.
The core function of a module is creating, suspending, unsuspending, and terminating of products. This happens
as various events occur. These events include:
New order payment
Items becoming overdue
Overdue invoice payment
Cancellation requests.
A WHMCS module can do much more than just that including:
Automated password resets.
Upgrades/downgrades.
Renewals.
Admin based links.
Client area output.
And more via custom functions.
Developer Resources (/Developer_Resources)
Provisioning Module Docs | Gateway Module Docs (/Gateway_Module_Developer_Docs) | Registrar Module
Docs (/Registrar_Module_Developer_Docs) | Addon Module Docs (/Addon_Module_Developer_Docs)
Template Syntax (/Template_Syntax) | Database Interactions (/Interacting_With_The_Database) | Addon
Modules (/Addon_Modules) | Creating Pages (/Creating_Pages) | Action Hooks (/Hooks) | Internal API
(/API:Internal_API) | External API (/API)

Other types of modules that can be created in WHMCS are Payment Gateways
(/Gateway_Module_Developer_Docs), Domain Registrars (/Registrar_Module_Developer_Docs) and Addons
(/Addon_Module_Developer_Docs).
1 Getting Started
1.1 Naming Conventions
1.2 Product Conguration Options
2 Supported Functions
3 Module Parameters
3.1 Cong Options
3.2 Custom Fields & Congurable Options
4 Core Module Functions
4.1 Response Handling
4.2 Action Events

5 Single Sign-On
5.1 Service Single Sign-On
5.2 Server Single Sign-On
6 The UsageUpdate Function
7 Custom Functions
8 Client Area Output
8.1 Product Details Page Output
8.2 Custom Pages
9 Admin Services Tab
10 Module Logging
11 WHMCS Marketplace

Getting Started
Begin by downloading the Provisioning Module Template: https://github.com/WHMCS/sample-provisioningmodule (https://github.com/WHMCS/sample-provisioning-module)

Naming Conventions
Provisioning Modules are found in the /modules/servers/ directory. The module name chosen must be unique
and should be all lowercase. The name must only contain letters & numbers whilst always starting with a letter.
Inside the module, function naming will follow a certain format. Functions have a prex of the module lename,
underscore, then the function name. For example, a module "mymodule" would have the create function
"mymodule_CreateAccount".

Product Conguration Options


The required function of all provisioning modules is the CongOptions function. This denes the settings that are
congurable on a per product basis when a product uses the module. The name of this function must be
mymodule_CongOptions, matching the name of your module.
There is a limited number of supported eld types. These are: Text, Password, Yes/No Checkboxes, Dropdown
Menus, Radio Buttons & Text Areas.
Below are examples of the available parameters for each eld type. Provisioning modules support up to 24
options dened in this way.

$configarray=array(
"username"=>array(
"FriendlyName"=>"UserName",
"Type"=>"text",#TextBox
"Size"=>"25",#DefinestheFieldWidth
"Description"=>"Textbox",
"Default"=>"Example",
),
"password"=>array(
"FriendlyName"=>"Password",
"Type"=>"password",#PasswordField
"Size"=>"25",#DefinestheFieldWidth
"Description"=>"Password",
"Default"=>"Example",
),
"usessl"=>array(
"FriendlyName"=>"EnableSSL",
"Type"=>"yesno",#Yes/NoCheckbox
"Description"=>"Ticktousesecureconnections",
),
"package"=>array(
"FriendlyName"=>"PackageName",
"Type"=>"dropdown",#DropdownChoiceofOptions
"Options"=>"Starter,Advanced,Ultimate",
"Description"=>"SampleDropdown",
"Default"=>"Advanced",
),
"disk"=>array(
"FriendlyName"=>"DiskSpace",
"Type"=>"radio",#RadioSelectionofOptions
"Options"=>"100MB,200MB,300MB",
"Description"=>"RadioOptionsDemo",
"Default"=>"200MB",
),
"comments"=>array(
"FriendlyName"=>"Notes",
"Type"=>"textarea",#Textarea
"Rows"=>"3",#NumberofRows
"Cols"=>"50",#NumberofColumns
"Description"=>"Descriptiongoeshere",
"Default"=>"Enternoteshere",
),
);
return$configarray;

Supported Functions
Here is an overview of all functions that a WHMCS provisioning module can contain. Functions within a module
are optional and need not be in the module if they dont apply. Remember, all functions should have the prex
lename_ and then the function name. This is below in bold in the function descriptions.
CreateAccount - This function runs when a new product provisions. This can be by WHMCS
upon checkout or payment for a new order. Also, by an admin user from the Products/Services
tab in a clients prole of the admin area.
SuspendAccount - This function runs when a suspension is requested. Requested by the
WHMCS Cron when a product becomes overdue, or by admin user in the Client Prole.
UnsuspendAccount - This function runs when an unsuspension is requested. Requested upon
payment of an overdue invoice for a product.
TerminateAccount - This function runs when a termination is requested. Requested by the
WHMCS Cron for long overdue products when enabled
([Automation_Settings#Enable_Termination]). Also requested by an admin user in the Client
Prole.
Renew - This function runs each time a renewal invoice for a product becomes paid.
ChangePassword - This function runs as a client requests a password change. The option will
not show up if the function is not dened in the module. The status of the product must also be
active. Admins can also invoke this command from the admin area.
ChangePackage - This function runs for upgrading and downgrading of products. This function
runs when an upgrade or downgrade order placed by the client becomes paid. Admins can also
invoke this from the product management pages. The same function runs for upgrades and
downgrades of both products and congurable options.
ClientArea - This function can be used to dene module specic client area output. It accepts a
return of HTML for display on the product details page of the client area. Output via a template

le within the module folder named "clientarea.tpl" is also possible. Discussion of this function
in more detail later on in the docs.
AdminArea - Used to dene HTML code that displays on server conguration page (Setup >
Servers). Used to provide an automated shortcut/login link to the integrated server control
panel.
LoginLink - Used to dene HTML code to link to the customers account on a server control
panel. Displayed on the product management page of the admin area. The return must be
HTML output or link (no forms).
ClientAreaCustomButtonArray - Used to dene custom functions that your module supports.
Customers can invoke and run these from the client area. The functions can perform actions or
product page output in the client area. Example usages for this are to provide product
management pages, bandwidth reporting pages, etc
ClientAreaAllowedFunctions - Like the above, used to dene custom functions. Customers
can invoke, but are not shown as buttons by default (i.e. custom client area output will invoke
them).
AdminCustomButtonArray - Used to dene custom functions in your module for admin
users. This can contain more functions than the client area equivalent.
UsageUpdate - Used to perform a daily import of the disk and bandwidth usage from a server.
The data imported is then used to display the usage stats both within the client and admin
areas of WHMCS. The data is also used in disk and bandwidth overage billing calculations if
enabled for a product.
AdminServicesTabFields - Used to dene extra elds or output to display within admin
product pages.
AdminServicesTabFieldsSave - Used in conjunction with the above. This function handles the
values submitted in any custom elds when a save occurs.

Module Parameters
The module parameters are the data/values passed into each function when called. Every module function
receives the same parameters. These parameters provide information about the specic product/service the
module command runs for. The parameters also contains the settings from the product itself.
Var Name
serviceid
pid
serverid
domain
username
password
producttype
moduletype
congoptionX
clientsdetails
customelds
congoptions
server

Description
The unique ID of the service.
Database Field: tblhosting.id
The product ID for the service.
Database Field: tblproducts.id
The assigned server ID for the service.
Database Field: tblservers.id
The domain entered by the customer when ordering.
Database Field: tblhosting.domain
Username generated for the service. (defaults to rst 8 letters of the domain)
Database Field: tblhosting.username
Password generated for the service. (10 char generated on rst creation consisting of letters &
numbers, both upper & lowercase).
Database Field: tblhosting.password
The product type which can be one of sharedhosting, reselleraccount, server or other.
The module name (will match lename of module).
with X being from 1 to 24.
These elds contain the module settings for the product dened in the CongOptions function.
Contains an array of all client details service owner. This contains things like rstname,
lastname, email, address1, country, etc
Contains an array of all custom elds dened on the product.
The key is the custom eld name - $params[customelds][Field Name].
Contains an array of all the congurable options dened on the product.
Again the key being the option name in this case - $params[congoption][Option Name Here].
true/false - Is the product assigned to a server.

serverip
The IP Address of the selected server.
serverhostname The Hostname of the selected server.
serverusername The Username of the selected server.
serverpassword The Password of the selected server.
serveraccesshashThe Access Hash of the selected server.
serversecure
true/false - Is an SSL connection enabled in the Server Conguration.

Cong Options
Cong Options (do not confuse with Congurable Options) are the module's settings. These are dened in the
CongOptions function of the module. Cong Options are set on a per product basis. Supplied as a numbered list:
$params[congoption1], $params[congoption2], etc. Dened by the order specied in the CongOptions
function of the module.

Custom Fields & Congurable Options


Values from any custom elds & congurable options are passed into modules as parameters. Passed as an array
with the key being the name of the eld or option.
For example for a custom eld called Username, would become $params[customelds][Username]. Likewise, a
congurable option named Disk Space, would become $params[congoptions][Disk Space].

Core Module Functions


The core module functions are Create, Suspend, Unsuspend, Terminate, Renew, ChangePassword and
ChangePackage.
These 7 functions all operate in a similar manner. They can run both manually and automatically. Each expected
to return either a success or error response.

Response Handling
Each of these functions after running actions must either return a success or error.
For a successful result the code must actually return the word success to end the function. When WHMCS
receives "success" it knows the function completed and continues on that basis.
Should the function fail, the return should be a user understandable error message, as it will display to sta
users.

Action Events
When a function is successful, there are various actions that run as follows:
CreateAccount - Changes status to Active + Sends Product Welcome Email
SuspendAccount - Changes status to Suspended
UnsuspendAccount - UnsuspendAccount
TerminateAccount - Changes status to Terminated
ChangePassword - Updates password in database
Besides the above actions, admin users receive a conrmation of functions completing, or errors in the case of
failure. Functions invoked through automation, such as payment of a new order, that notication can be via email.
In the case of ChangePassword, any errors returned are also displayed to client users.

Single Sign-On
Single sign-on can occur for a service or server.
Whichever method being used, the return should be the same.
The return from either function should always be an array and contain two keys of a possible three.
success - This is a boolean (/Glossary#Boolean) value and should indicate success or failure
redirectTo - This should be a fully formatted URL return from your SSO request
errorMsg - Any appropriate error message to be displayed to whoever is making the request

Service Single Sign-On


Service single sign-on is to allow admin and client users to login to the control panel of the service automatically.
/**
*Performsinglesignonforagiveninstanceofaproduct/service.
*
*Calledwhensinglesignonisrequestedforaninstanceofaproduct/service.
*
*Whensuccessful,returnsaURLtowhichtheusershouldberedirected.
*
*@paramarray$paramscommonmoduleparameters
*
*@seehttp://docs.whmcs.com/Provisioning_Module_SDK_Parameters
*
*@returnarray
*/
functionmymodule_ServiceSingleSignOn(array$params)
{

$return=array(

'success'=false,

);

try{
/**
*alltheservice'ssinglesignontokenretrievalfunction,usingthe
*valuesprovidedbyWHMCSin`$params`.
*ThevariablesandresponseformatwoulddependonyourserverAPI
*/

$response=$formattedResponse=custom_call_to_server();

$return=array(
'success'=>true,
'redirectTo'=>$response['redirectUrl'],
);
}catch(Exception$e){
$return['errorMsg']=$e>getMessage();
$response=$e>getMessage();
$formattedResponse=$e>getTraceAsString();
}

/**
*Loganycalltotheserver
*/

logModuleCall(
'provisioningmodule',
__FUNCTION__,
$params,
$response,
$formattedResponse,
array('username','password')
);

Server Single Sign-On


Server single sign-on allows for Admin users to login to the associated server management panel (like WHM for
cPanel) automatically.

/**
*Performsinglesignonforaserver.
*
*Calledwhensinglesignonisrequestedforaserverassignedtothemodule.
*
*ThisdiffersfromServiceSingleSignOninthatitrelatestoaserver
*instancewithintheadminarea,asopposedtoasingleclientinstanceofa
*product/service.
*
*Whensuccessful,returnsaURLtowhichtheusershouldberedirectedto.
*
*@paramarray$paramscommonmoduleparameters
*
*@seehttp://docs.whmcs.com/Provisioning_Module_SDK_Parameters
*
*@returnarray
*/
functionmymodule_AdminSingleSignOn(array$params)
{

$return=array(

'success'=false,

);

try{
/**
*alltheservice'ssinglesignontokenretrievalfunction,usingthe
*valuesprovidedbyWHMCSin`$params`.
*ThevariablesandresponseformatwoulddependonyourserverAPI
*/

$response=$formattedResponse=custom_call_to_server();

$return=array(
'success'=>true,
'redirectTo'=>$response['redirectUrl'],
);
}catch(Exception$e){
$return['errorMsg']=$e>getMessage();
$response=$e>getMessage();
$formattedResponse=$e>getTraceAsString();
}

/**
*Loganycalltotheserver
*/

logModuleCall(
'provisioningmodule',
__FUNCTION__,
$params,
$response,
$formattedResponse,
array('username','password')
);

The UsageUpdate Function


The UsageUpdate function performs a daily import of the disk and bandwidth usage for accounts of a server. The
data imported is then used to display the usage stats both within the client and admin areas of WHMCS. The data
is also used in disk and bandwidth overage billing calculations if enabled for a product.
The UsageUpdate function runs via WHMCS Cron, for any active, enabled server. (important: Runs per server not
per product). So, this can only run if your module has a server created in WHMCS for it - products alone do not
invoke it.
The function receives the id, ip, hostname, username/hash, & password variables. The function will query the disk
and bandwidth usage for the server, and updates the database. The database update should be a single call for
speed and eciency. An example of how to do this is below.

functionmymodule_UsageUpdate($params){

$serverid=$params['serverid'];

$serverhostname=$params['serverhostname'];

$serverip=$params['serverip'];

$serverusername=$params['serverusername'];

$serverpassword=$params['serverpassword'];

$serveraccesshash=$params['serveraccesshash'];

$serversecure=$params['serversecure'];

#Runconnectiontoretrieveusageforalldomains/accountson$serverid

#NowloopthroughresultsandupdateDB

foreach($resultsAS$domain=>$values){
update_query("tblhosting",array(
"diskused"=>$values['diskusage'],
"disklimit"=>$values['disklimit'],
"bwusage"=>$values['bwusage'],
"bwlimit"=>$values['bwlimit'],
"lastupdate"=>"now()",
),array("server"=>$serverid,"domain"=>$values['domain']));
}

Custom Functions
Custom functions allow denition of extra operations that run using the module. The custom functions can
perform actions, or dene extra client area pages/output. Permissions can be granted for who can use each
custom function, be it just clients, just admins, or both.
The convention for custom function names follow the same as any other function of a module. It must begin with
the module lename_, and then the custom function name.
The easiest way to show this is with an example. So lets take an example of a reboot & shutdown function in a
VM/VPS system:
functiontemplate_reboot($params){

#Codetoperformrebootactiongoeshere...
if($successful){

$result="success";

}else{

$result="ErrorMessageGoesHere...";

return$result;

functiontemplate_shutdown($params){

#Codetoperformshutdownactiongoeshere...
if($successful){

$result="success";

}else{

$result="ErrorMessageGoesHere...";

return$result;

The above shows how to dene custom functions and to used the passed variables. The custom function returns
either success or an error message to show a failure. If we wanted to allow clients to perform reboots, but only
admins to be able to perform a shutdown. We would dene that like:

functiontemplate_ClientAreaCustomButtonArray(){
$buttonarray=array(

"RebootServer"=>"reboot",

);

return$buttonarray;
}

functiontemplate_AdminCustomButtonArray(){
$buttonarray=array(

"RebootServer"=>"reboot",

"ShutdownServer"=>"shutdown",

);

return$buttonarray;
}

The above allows a clients to run the reboot function, and admins reboot and shutdown.
The key value of the array is what displays to admins/clients on the button or menu options for the commands.
And the value is the custom function name excluding the modulename_ prex.
A description of how to provide a button or way to invoke a custom function is in the Client Area Output section:
<formmethod="post"action="clientarea.php?action=productdetails">
<inputtype="hidden"name="id"value="{$serviceid}"/>
<inputtype="hidden"name="modop"value="custom"/>
<inputtype="hidden"name="a"value="reboot"/>
<inputtype="submit"value="RebootVPSServer"/>
</form>

Client Area Output


Another key function of a module is to give clients access to extra options and output within the client area. Done
either on the product details page (using the ClientArea function of a module), or as a custom function/action as
above.

Product Details Page Output


Creating output to display on the same page as the product details in the client area is easy. Create a template le
named clientarea.tpl within the module folder. This template le will process as a Smarty template le. This
means it can make use of Smarty variables. The variables will be the same module vars as passed to every
module function. Also, other smarty functions such as logic functions are available.
More advanced actions, such as performing API Calls or dening variables for the output are possible. A
ClientArea function within the module that runs any code and returns an array with the template le to use, and
any variables desired besides the defaults. Returning dierent template le values based on data in the $_GET or
$_POST array data, allows for many pages which can have direct links.
functionmymodule_ClientArea($vars){
returnarray(
'templatefile'=>'clientarea',
'vars'=>array(
'test1'=>'hello',
'test2'=>'world',
),
);
}

Custom Pages
Situations that need a custom page, rather than output on the existing product details page, are possible. Done
using functions as described earlier in this article, with that function returning an array as follows:

functionmymodule_mycustomfunction($vars){
returnarray(
'templatefile'=>'customfunc',
'breadcrumb'=>array(
'stepurl.php?action=this&var=that'=>'CustomFunction',
),
'vars'=>array(
'test1'=>'hello',
'test2'=>'world',
),
);
}

Clients then need access to use this function, and a link in the product details page. Do this using the methods
described in the Custom Functions section above.

Admin Services Tab


Admin Services Tab functions allow denition of extra elds to appear on the product details in the admin area.
Used for informational output, or for settings and values stored in custom tables or outside WHMCS.
WHMCS uses this in the core system for our licensing addon module. The license specic elds of the allowed
system are set and viewed from the product details.
There are 2 functions relating to the services tab - AdminServicesTabFields and AdminServicesTab-FieldsSave. The
rst of these allows denition of the extra elds to output. The latter allows handling any input on
submission/save, if required.
So on to an example, below we show you how to dene 4 extra elds. This example shows an input, dropdown,
textarea and info only output. The examples continues to update them in a custom table of the database via the
save event.
functionmymodule_AdminServicesTabFields($params){

$result=select_query("mod_customtable","",array("serviceid"=>$params['serviceid']));
$data=mysql_fetch_array($result);
$var1=$data['var1'];
$var2=$data['var2'];
$var3=$data['var3'];
$var4=$data['var4'];

$fieldsarray=array(
'Field1'=>'<inputtype="text"name="modulefields[0]"size="30"value="'.$var1.'"/>',
'Field2'=>'<selectname="modulefields[1]"><option>Val1</option</select>',
'Field3'=>'<textareaname="modulefields[2]"rows="2"cols="80">'.$var3.'</textarea>',
'Field4'=>$var4,#InfoOutputOnly
);
return$fieldsarray;

functionmymodule_AdminServicesTabFieldsSave($params){
update_query("mod_customtable",array(
"var1"=>$_POST['modulefields'][0],
"var2"=>$_POST['modulefields'][1],
"var3"=>$_POST['modulefields'][2],
),array("serviceid"=>$params['serviceid']));
}

Module Logging
To make reviewing and debugging module calls easier, WHMCS has a built in logging function. This allows the
record of the request and response strings for every call the module makes. This becomes available in an
accessible way via the WHMCS admin interface. If you plan to release the module, this allows end users to
troubleshoot and debug issues experienced using the module. This also allows you to be able to debug issues
experienced while using it.
Logging is not something that is always enabled. This is to avoid logs growing too large, so it's something that
needs enabling for the logging to occur. To toggle logging, goto Utilities > Logs > Module Debug Log. This is the
same place to review the logs.
To utilise this functionality, the module needs to make a call as follows:
logModuleCall($module,$action,$requeststring,$responsedata,$processeddata,$replacevars);

$module - The name of the module, for example "cpanel", "plesk", "resellerclub", etc...
$action - This should be the action running, ie. create, suspend, register, etc...
$requeststring - This should be the variables passed to the remote API. This can be in either
string or array format.
$responsedata - The return of the raw API response. This can be in either string or array
format also.
$processeddata - Like the above, Used for a post processing API response. Such as after
conversion into a friendly format, an array for example.
$replacevars - This accepts an array of strings to replace. So, for example, the module might
want to pass the username and password for the API into this function. The function replaces
the data with *'s wherever they appear in the request or response strings for extra security.

WHMCS Marketplace
WHMCS oers a Marketplace which accepts submission of the completed module. Displayed listed are found
under the Addons tab within the administration area and online at http://marketplace.whmcs.com
(http://marketplace.whmcs.com) . This is a great way to make WHMCS users aware of the module.
For help using the Marketplace please refer to https://marketplace.whmcs.com/help
(https://marketplace.whmcs.com/help) . We aim to review submissions in 1-2 weeks.

Developer Resources (/Developer_Resources)


Provisioning Module Docs | Gateway Module Docs (/Gateway_Module_Developer_Docs) | Registrar Module
Docs (/Registrar_Module_Developer_Docs) | Addon Module Docs (/Addon_Module_Developer_Docs)
Template Syntax (/Template_Syntax) | Database Interactions (/Interacting_With_The_Database) | Addon
Modules (/Addon_Modules) | Creating Pages (/Creating_Pages) | Action Hooks (/Hooks) | Internal API
(/API:Internal_API) | External API (/API)
Retrieved from "http://docs.whmcs.com/index.php?title=Provisioning_Module_Developer_Docs&oldid=18322
(http://docs.whmcs.com/index.php?title=Provisioning_Module_Developer_Docs&oldid=18322)"
Documentation Home (/)
General Information (/Getting_Started)
System Requirements (/System_Requirements)
Installing WHMCS (/Installing_WHMCS)
Upgrading (/Upgrading)
Release Notes (/Release_Notes)
Further Security Steps (/Further_Security_Steps)
Importing Data (/Importing_Data)
Licensing (/Licensing)
Common Troubleshooting Tips (/Common_Troubleshooting_Tips)
Key Aspects (/Using_WHMCS_and_Howtos)
Clients (/Client_Management)
Orders (/Order_Management)
Products (/Products_Management)

Domains (/Domains_Management)
Invoicing (/Invoicing)
Transactions (/Transactions)
Support Tickets (/Support Tickets)
Messages & Emails (/Messages/Emails)
Setup/Conguration (/Setup/Conguration)
General Settings (/Conguration)
Automation Settings (/Automation_Settings)
Payment Gateways (/Payment_Gateways)
Admins/Permissions (/Administrators_and_Permissions)
Products/Services (/Products_and_Services)
Support Departments (/Support_Departments)
Developer Resources (/Developer_Resources)
Client Area Templates (/Client_Area_Template_Files)
Order Form Templates (/Order_Form_Templates)
Language Files (/Language_Files)
Action Hooks (/Hooks)
Widgets (/Widgets)
Creating Modules (/Creating_Modules)
API (/API)

WHMCS
The World's Leading Web
Hosting Automation Platform
2016 WHMCS Limited.
Terms of Service (//www.whmcs.com/about/terms-of-service/)

PRODUCT
Features (//www.whmcs.com/features/)
Addons (//www.whmcs.com/addons/)
Demo (//www.whmcs.com/demo/)
Pricing (//www.whmcs.com/order/)

Privacy (//www.whmcs.com/about/privacy-policy/)

RESOURCES
Download (//download.whmcs.com/)
Marketplace (https://marketplace.whmcs.com/)
Partners (//www.whmcs.com/partners/)
Security Program (//www.whmcs.com/security-bounty-program/)
License Verication (//www.whmcs.com/members/verifydomain.php)

SUPPORT
Documentation (//docs.whmcs.com/)
Technical Support (//www.whmcs.com/support/)
Community Forums (//forums.whmcs.com/)
Developer API (//www.whmcs.com/developers/)

COMPANY
About Us (//www.whmcs.com/about/)
Blog (//blog.whmcs.com/)
Jobs

We're hiring!

(//www.whmcs.com/about/jobs/)

Contact (//www.whmcs.com/about/contact/)

(//www.google.com/plus/+whmcs)
(//www.youtube.com/whmcs)

You might also like