WHMCS Module
Setup & operation guide — provisions MetroPanel hosting accounts from WHMCS via REST API v1.
Module directory: modules/servers/metropanel/
Module name (in WHMCS): MetroPanel
Requires: PHP 8.1+, cURL extension, a MetroPanel API bearer token.
-
Copy the
metropanelfolder tomodules/servers/on your WHMCS install. -
The module's tables (
mod_metropanel_link,mod_metropanel_settings) are created automatically the first time a product is configured.
Sign in to MetroPanel as an admin (or reseller) and open Security → API Tokens. Create a token for WHMCS / billing automation.
- Open Security → API Tokens
- Choose the Provisioning preset (recommended for WHMCS)
- Optionally pin the token to your WHMCS server IP
- Create the token — the plain-text value is shown once; store it securely
Use Provisioning. This preset is intended for WHMCS / billing automation. It can create and manage accounts, packages, domains, apps, and databases.
Full access is the same as Provisioning, plus cron job management (cron:read / cron:write). Use Full access only if your integration manages cron jobs — a normal WHMCS hosting module does not.
| Preset | What it includes | Use for WHMCS? |
| Provisioning | Accounts, packages, domains, apps, databases (read + write) | Yes — use this |
When creating the token, MetroPanel can restrict which client IPs may use it. Empty allowlist = any IP (default). Whenever possible, pin the token to your WHMCS server egress IP.
- Include your WHMCS server IP (the IP MetroPanel sees when WHMCS calls the API).
-
Denied requests return HTTP
403with:This API token is not allowed from your IP address.
After setup, verify with Test Connection (calls GET /api/v1/auth/me). Do not use the public health URL to validate tokens.
Go to Configuration → System Settings → Servers → Add New Server:
| Field | Value |
| Hostname |
Your panel domain, e.g. panel.example.com — or leave blank and use IP.
|
| IP Address |
Server IP (used if Hostname is empty), e.g. 203.0.113.10.
|
| Port | 8443 — MetroPanel's fixed API port for every install. WHMCS pre-fills this when you select the module. |
| Secure (SSL) |
Leave unticked for most installs — the panel serves plain http on port 8443. Tick it only if your panel serves https on 8443 (a self-signed cert is fine — TLS verification is off by default).
|
| Module | Select MetroPanel. |
| Username / Password | Username: add your admin/reseller username. Password: add API Token. |
Click Test Connection. The module calls GET /api/v1/auth/me with the API token from the Password field. Success means the token is valid, the license is active, the user is active, and the token IP allowlist (if any) permits WHMCS's IP.
The module builds the base URL automatically: https://panel.example.com:8443/api/v1 or http://203.0.113.10:8443/api/v1. You can use a panel domain or server IP with port 8443; a public CA certificate is not required when TLS verification is disabled.
Optional ops monitoring (not used by this module): authenticated GET /ready checks database and queue.
- Open (or create) a hosting product: System Settings → Products/Services.
- On the Module Settings tab, choose MetroPanel and the server group, then Save.
-
The MetroPanel Package field is a live dropdown — WHMCS loads it from the server via
GET /packages, with a None — use custom resource limits option on top. Pick a package, or pick None to define limits yourself. - If you chose None, fill in the seven custom limit fields below the package (Disk / Bandwidth / CPU / RAM + Max Domains / Databases / Apps). These apply in custom mode and are ignored when a package is selected.
The dropdown is powered by a WHMCS loader function: it fetches packages from the assigned server using the API token. If the server or token isn't set yet (or the panel is unreachable), the list is empty and you can type the numeric package id manually — leave it blank or 0 for custom limits.
Package vs. custom limits (mirrors the panel create form):
-
Package selected: the module sends
package_idonly. The custom limit fields are ignored (so stale values left over from a previously-assigned module can never break provisioning). -
None: the module sends no
package_idand instead sends all seven limits —disk_limit_mb(min 100),bandwidth_limit_mb(min 100),cpu_limit_percent(1–10000),ram_limit_mb(min 128),max_domains(min 1),max_databases(min 0),max_apps(min 0). Terminal access is managed by MetroPanel (the panel's package default on create; preserved on later limit changes).
On Change Package, package mode calls PATCH /accounts/{{id}}/package; custom mode calls PATCH /accounts/{{id}}/resources (the account's current terminal_access is preserved automatically).
- Test Connection fails — no token: Password is empty. Paste the Sanctum bearer token from MetroPanel Security → API Tokens into the Password field (and set Username to your admin/reseller username).
- 401 / Unauthenticated: Token missing, revoked, or wrong value. Recreate the token and update the Password field.
- 403 — not allowed from your IP: Token has an IP allowlist that excludes WHMCS. Add WHMCS egress IP on the token in the panel, or clear the allowlist for testing.
-
403 / forbidden ability: Token lacks a required ability for provisioning (typically
accounts:read,accounts:write,packages:read). - 422 validation: The message contains the field error (e.g. username already taken, invalid package, weak password). Contact email is not rejected for reuse across services.
- No valid MetroPanel Package ID: Set the package on the product Module Settings tab or use custom limits (None).
- All actions are logged (with secrets redacted) under Utilities → Logs → Module Log.