WHMCS is powerful out of the box, but its true potential lies in customization. Whether you need to integrate a new server type, connect a proprietary API, or add unique functionality, custom module development makes it possible. This comprehensive guide will teach you the fundamentals of WHMCS module development, from simple addon modules to complex provisioning integrations.
Understanding WHMCS Module Types
WHMCS supports several module types, each serving a specific purpose. Understanding which type you need is the first step in development.
Provisioning Modules (Server Modules)
Provisioning modules handle the automation of service delivery. When a customer orders hosting, a VPS, or any other automated service, the provisioning module creates the account, configures resources, and handles suspension, termination, and upgrades. Examples include the cPanel, Plesk, and SolusVM modules.
Addon Modules
Addon modules extend WHMCS with new functionality that doesn't directly relate to product provisioning. These might add new admin pages, implement custom reports, integrate with external services, or modify WHMCS behavior. Addon modules can also add pages to the client area.
Payment Gateway Modules
These handle payment processing. They communicate with payment providers, process transactions, handle callbacks, and manage refunds. If you need to accept payments via a method WHMCS doesn't support, you'll need a payment gateway module.
Registrar Modules
Registrar modules connect WHMCS to domain registrars. They handle domain registration, transfers, renewals, DNS management, and WHOIS privacy—everything related to domain name operations.
Building a Provisioning Module
Let's start with the most common custom development need: a provisioning module for a service that WHMCS doesn't support natively.
File Structure
Provisioning modules live in /modules/servers/yourmodule/. At minimum, you need:
/modules/servers/yourmodule/
yourmodule.php
logo.png (optional but recommended) Module Configuration
Every module needs a configuration function that defines settings and metadata:
function yourmodule_MetaData()
{
return [
'DisplayName' => 'Your Module Name',
'APIVersion' => '1.1',
'RequiresServer' => true,
];
}
function yourmodule_ConfigOptions()
{
return [
'Package' => [
'Type' => 'dropdown',
'Options' => 'basic,standard,premium',
'Description' => 'Hosting Package',
],
'Disk Space' => [
'Type' => 'text',
'Size' => '10',
'Default' => '5000',
'Description' => 'Disk space in MB',
],
];
} Core Functions
The heart of a provisioning module consists of these essential functions:
CreateAccount
Called when a new service is activated. This function should create the service on your target platform:
function yourmodule_CreateAccount(array $params)
{
try {
$api = new YourAPI($params['serverusername'], $params['serverpassword']);
$result = $api->createAccount([
'username' => $params['username'],
'password' => $params['password'],
'domain' => $params['domain'],
'package' => $params['configoption1'],
]);
return 'success';
} catch (Exception $e) {
return 'Error: ' . $e->getMessage();
}
} SuspendAccount and UnsuspendAccount
Handle service suspension for non-payment and reactivation after payment:
function yourmodule_SuspendAccount(array $params)
{
// Suspend the service
return 'success';
}
function yourmodule_UnsuspendAccount(array $params)
{
// Reactivate the service
return 'success';
} TerminateAccount
Called when a service is cancelled. This should remove the customer's account from your platform:
function yourmodule_TerminateAccount(array $params)
{
// Delete the account
return 'success';
} Building an Addon Module
Addon modules are often simpler but can be just as powerful. They're perfect for adding custom functionality, reports, or integrations.
Addon File Structure
/modules/addons/youraddon/
youraddon.php
hooks.php (optional)
lib/ (optional, for additional classes) Basic Addon Configuration
function youraddon_config()
{
return [
'name' => 'Your Addon Name',
'description' => 'Description of what your addon does',
'version' => '1.0',
'author' => 'Shahid Malla',
'fields' => [
'api_key' => [
'FriendlyName' => 'API Key',
'Type' => 'text',
'Size' => '50',
],
],
];
}
function youraddon_activate()
{
// Create database tables, set up initial config
return ['status' => 'success'];
}
function youraddon_deactivate()
{
// Clean up when addon is deactivated
return ['status' => 'success'];
} Admin Area Output
The output function renders your addon's admin interface:
function youraddon_output($vars)
{
$modulelink = $vars['modulelink'];
echo '<h1>Your Addon</h1>';
echo '<p>Welcome to your custom addon!</p>';
// Add your admin interface here
} Leveraging Hooks
Hooks allow you to execute code when specific events occur in WHMCS. They're essential for extending functionality without modifying core files.
Hook File Location
Place hooks in /includes/hooks/ or within your addon's hooks.php file. Using the addon hooks.php keeps your customizations organized.
Example Hooks
// Run code after invoice is paid
add_hook('InvoicePaid', 1, function($vars) {
$invoiceId = $vars['invoiceid'];
// Your custom logic here
});
// Modify client area pages
add_hook('ClientAreaPage', 1, function($vars) {
if ($vars['filename'] == 'clientarea') {
return ['customVariable' => 'value'];
}
}); Using the WHMCS API
WHMCS provides extensive internal APIs for interacting with system data. Use these instead of direct database queries for stability and compatibility.
use WHMCS\Database\Capsule;
// Use localAPI for internal calls
$result = localAPI('GetClients', [
'limitstart' => 0,
'limitnum' => 100,
]);
// Database queries using Capsule
$clients = Capsule::table('tblclients')
->where('status', 'Active')
->get(); Best Practices
Following best practices ensures your modules are reliable, maintainable, and compatible with WHMCS updates.
Error Handling
Always implement comprehensive error handling. Return clear error messages that help administrators diagnose issues:
try {
// Your code
} catch (Exception $e) {
logModuleCall('yourmodule', 'action', $params, $e->getMessage());
return 'Error: ' . $e->getMessage();
} Logging
Use WHMCS's built-in logging for API calls and errors. This creates valuable debugging information in the Module Log:
logModuleCall(
'yourmodule',
'CreateAccount',
$requestData,
$responseData,
$processedData
); Security
Never trust user input. Sanitize and validate all data, use prepared statements for database queries, and follow WHMCS security guidelines.
When to Hire a Developer
While this guide provides a foundation, complex module development requires experience with WHMCS internals, PHP best practices, and the specific APIs you're integrating. Consider hiring a professional when:
- The integration is business-critical and needs to be reliable
- You're working with complex external APIs
- You need ongoing maintenance and updates
- Time constraints don't allow for learning curve
As a top-rated WHMCS developer with 8+ years of experience, I've built hundreds of custom modules for hosting companies worldwide. My modules power businesses processing millions in transactions annually.
Conclusion
Custom WHMCS module development opens endless possibilities for automating your hosting business. Whether you need a simple addon or a complex multi-service provisioning system, understanding the fundamentals covered here will serve as a solid foundation.
If you need custom module development for your WHMCS installation, I'm here to help. From initial consultation to deployment and ongoing support, I provide end-to-end development services that transform your hosting operations.
Need a Custom WHMCS Module?
I develop custom WHMCS modules for any use case—provisioning, addons, payment gateways, and more. Professional code with full documentation.
About Shahid Malla
ExpertFull Stack Developer with 10+ years of experience in WHMCS development, WordPress, and server management. Trusted by 600+ clients worldwide for hosting automation and custom solutions.