WHMCS as an Automation Platform
WHMCS is the dominant billing and automation platform for web hosting providers, but its real power lies in its extensibility. The module system allows developers to integrate any provisioning system, payment gateway, or addon service into the WHMCS lifecycle. Custom modules transform WHMCS from a billing tool into a complete business automation layer. This guide covers the module architecture, the hooks system, and a step-by-step provisioning module implementation.
WHMCS Module Types
Understanding which module type to build determines your integration architecture:
- Provisioning Modules (Server Modules): Handle service lifecycle — Create, Suspend, Unsuspend, Terminate, ChangePackage. Called when customers purchase, cancel, or modify hosting services.
- Addon Modules: Add custom pages to the admin area and client area. Use for custom dashboards, reporting tools, or feature unlocks.
- Payment Gateway Modules: Integrate new payment processors. Handle invoice presentation, payment capture, and callback processing.
- Registrar Modules: Integrate domain registrars for automated domain registration, transfer, and DNS management.
The Hooks System
WHMCS hooks fire at every meaningful event in the system lifecycle — invoice creation, order acceptance, ticket submission, admin login, and hundreds more. Hooks enable you to add custom logic without modifying core files:
<?php
// /modules/hooks/my_custom_hook.php
add_hook('AfterModuleCreate', 1, function($vars) {
$serviceId = $vars['serviceid'];
$userId = $vars['userid'];
$domain = $vars['domain'];
// Send to external system
$response = file_get_contents('https://api.mypanel.com/provision', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => json_encode(['service_id' => $serviceId, 'domain' => $domain]),
]
]));
// Log for debugging
logModuleCall('my_custom_hook', 'AfterModuleCreate', compact('serviceId', 'domain'), $response, '', []);
});API Authentication
WHMCS exposes an internal API for all operations accessible from modules and hooks. Use the localAPI() function for internal calls (no authentication needed) and the external API with identifier/secret pairs for external integrations:
// Internal API call from within WHMCS
$result = localAPI('GetClientsDetails', ['clientid' => 1, 'stats' => true]);
// External API call
$postfields = [
'identifier' => 'YOUR_API_IDENTIFIER',
'secret' => 'YOUR_API_SECRET',
'action' => 'GetClients',
'responsetype' => 'json',
];Create API credentials in WHMCS Admin → Configuration → Manage API Credentials. Restrict API credentials by IP address for security-critical integrations.
Database Operations in Modules
WHMCS uses Illuminate Database (Laravel's ORM). Use the Capsule manager for database operations in modules:
use WHMCSDatabaseCapsule;
// Query
$services = Capsule::table('tblhosting')
->where('userid', $userId)
->where('domainstatus', 'Active')
->get();
// Insert custom data
Capsule::table('mod_myplugin_data')->insert([
'service_id' => $serviceId,
'external_id' => $externalId,
'created_at' => date('Y-m-d H:i:s'),
]);Always prefix custom tables with mod_yourmodulename_ to avoid collisions with WHMCS core tables.
Building a Custom Provisioning Module
Create the module file at /modules/servers/mypanel/mypanel.php. The minimum required functions are mypanel_ConfigOptions, mypanel_CreateAccount, mypanel_TerminateAccount, mypanel_SuspendAccount, and mypanel_UnsuspendAccount:
<?php
function mypanel_ConfigOptions() {
return [
'Package' => [
'Type' => 'dropdown',
'Options' => 'starter,pro,enterprise',
'Description' => 'Hosting package tier',
],
];
}
function mypanel_CreateAccount(array $params) {
try {
$api = new MyPanelAPI($params['configoption1'], $params['configoption2']);
$result = $api->createAccount([
'username' => $params['username'],
'password' => $params['password'],
'domain' => $params['domain'],
'package' => $params['configoption1'],
'email' => $params['clientsdetails']['email'],
]);
if ($result['success']) {
return 'success';
}
return $result['error'];
} catch (Exception $e) {
return $e->getMessage();
}
}
function mypanel_TerminateAccount(array $params) {
$api = new MyPanelAPI($params['configoption1'], $params['configoption2']);
$result = $api->deleteAccount($params['username']);
return $result['success'] ? 'success' : $result['error'];
}Testing with WHMCS Sandbox
WHMCS provides a module debug mode that logs all function calls, parameters, and return values to the WHMCS Module Log (Utilities → Logs → Module Log). Enable this during development. Use WHMCS's built-in test order system to simulate the full order-to-provision lifecycle without real payments. Test each lifecycle function — Create, Suspend, Unsuspend, Terminate — individually before attempting end-to-end testing.
Deployment Best Practices
- Version control your module code in a private Git repository
- Never modify WHMCS core files — all customization goes in
/modules/ - Test upgrades on a staging WHMCS instance before applying to production
- Log all external API calls using WHMCS's
logModuleCall()for debugging - Implement retry logic for external API calls — provisioning failures cascade to customer experience problems
- Handle WHMCS maintenance mode gracefully — queue provisioning requests if the external panel is unreachable
Well-built WHMCS modules automate the repetitive operational work of hosting provision, freeing support teams to handle exceptions rather than routine account management. The investment in proper module development pays returns with every new customer account created automatically.