Author Topic: CWP module for WHMCS - rewritten for PHP 8 / WHMCS 9 (drop-in, MIT)  (Read 5809 times)

0 Members and 1 Guest are viewing this topic.

Offline
*
The official cwp7 module hasn't changed since 30 March 2020. WHMCS has shipped 15 releases since then and now requires PHP 8.2, so I rewrote it.

It's a drop-in replacement: same module name, same directory, same config option order. Existing server entries, products and services keep working with no reconfiguration.

https://github.com/bradleygb/whmcs-cwp-module



Why you'd switch

Running the 2020 module today, these are live faults, not style complaints:

  • Disk and bandwidth reporting has never worked. It matches tblhosting.dedicatedip against CWP's ip_address, but dedicatedip is empty for every shared-IP account, so the query matches no rows. It also writes lastupdate with date('Y-m-d H:i:S') - capital S is PHP's ordinal suffix, producing "14:30:th", which MySQL rejects.
  • Package changes don't work against current CWP. CWP has a dedicated /v1/changepack endpoint. The module posts to /v1/account with action=udp and the package suffixed "12@", where that endpoint documents a "@12" prefix. Nothing changes and WHMCS reports success.
  • Resource limits aren't applied. CWP's add endpoint wants limit_nofile and limit_nproc; account/udp wants openfiles and processes. The module sends nofile and nproc, which neither accepts, so every account gets its package defaults.
  • ChangePassword sends 'acction' instead of 'action'. The field never reaches CWP.
  • A fatal TypeError in your daily cron. count() is called on the API payload without checking it's an array - on PHP 8 that aborts the cron run.
  • The API key is written to the WHMCS Module Log in plaintext, and sent with CURLOPT_SSL_VERIFYPEER and VERIFYHOST both disabled.
  • A live autologin URL is minted on every product-details page load and printed into the page HTML, where it persists in page source, browser history and referrer headers.



What's in the rewrite

All of the above fixed. TLS verification on by default with optional certificate pinning. The API key masked in logs and stripped from CWP's own error text - CWP echoes it back inside "Unauthorized action". Autologin sessions minted on click through WHMCS single sign-on. Account creation given its own 180-second budget, and a creation that times out is reconciled rather than left as an orphaned account.

Added: MetaData, TestConnection, ServiceSingleSignOn, ListAccounts for Server Sync, live account detail on the admin service page, and a client area block that makes no API call while rendering - so an unreachable panel can't stall a customer's page.

Optionally, changing a service's Product/Service applies the package to CWP directly, with no second click.

Errors name the exact API Manager function and action when a permission is missing, which matters because CWP's internal permission names don't match its own labels - account/udp is checked as "accout_upd".



Requirements

WHMCS 8.5-9.0, PHP 7.4-8.3, curl and json. Tested on 7.4, 8.0, 8.1, 8.2 and 8.3. MIT licensed. Community module, not affiliated with the CWP project.

Install

Extract into modules/servers/ and press Test Connection. PERMISSIONS.md lists the exact API Manager grants - note the grid is per function and per action, and an action left off produces "Unauthorized action" even when the function looks enabled.

Upgrading: replace the directory contents, nothing else. One thing can stop a previously "working" install - TLS verification is now on. If CWP serves a certificate from a public CA on 2304 you're fine; if it's self-signed, the README covers pinning it.

Issues and pull requests welcome.

Offline
*
Re: CWP module for WHMCS - rewritten for PHP 8 / WHMCS 9 (drop-in, MIT)
« Reply #1 on: September 02, 2026, 10:10:05 PM »
Update — a few versions have gone by since I posted this, so here's the lot.

https://github.com/bradleygb/whmcs-cwp-module/releases

The theme since the first post has been giving non-technical clients what they need without sending them into CWP at all. Most of mine only use their hosting for email — they don't want a control panel, they want to add a mailbox and change a password. That happens in the WHMCS client area now, and the ones who do want the panel still have the login button.







Packages (2.1.0)

  • Products can create their CWP packages. Ten product options describe the package — disk, bandwidth, FTP, email, email lists, databases, subdomains, parked and addon domains, hourly emails. Save the product and the package is created on every CWP server in that product's server group, or updated if one of that name already exists. No more building the same package by hand on each server.
  • Off by default (push_packages_on_product_save). Turning it on decides ownership — WHMCS becomes the source of truth, and a package edited in CWP gets overwritten next time the product is saved.
  • The CWP Package field can be left blank and it uses the product's own name.
  • Fixed: a package change failed whenever the package was set by name. changepack takes an id and nothing else — given a name it answers a bare Error with no explanation. Whatever the product holds is resolved to an id first now.
  • apply_resource_limits (2.1.1) — some servers refuse account/udp even with Account/UPD granted, which put a failed call in the log on every package change. Set it false on those and the call isn't made.

Client area (2.2.0 – 2.5.1)

  • Account dashboard — package and state, disk and bandwidth against their limits, the email/FTP/database/subdomain allowances, and the domain, subdomain and database lists. One accountdetail call made after the page renders, so an unreachable panel leaves a short message instead of a stalled page.
  • Mailbox management — add, change password, change size, delete. Off by default, needs ADD/UPD/DEL on Emails.
  • The mailbox list filters and pages at 10 (2.5.0); the domain, subdomain and database panels do the same at 5 (2.5.1). Neither appears until there's more than a page, so a small account looks as it always did. email/list and accountdetail/list both return everything in one response with no pagination of their own, so it's done browser-side.
  • The sixteen shortcut tiles from 2.2.0 came out again in 2.3.0 — every one of them opened CWP's dashboard rather than its own section, so they weren't doing what they looked like they did.

Fixed

  • Terminate was reporting a failure when it had actually worked. account/del answers {"status":"OK"} and then dumps its HTML confirmation after it, so json_decode threw the whole body out. WHMCS left the service Suspended while the account was already deleted off the server. It reads the JSON off the front now.
  • Suspend, unsuspend and terminate check the server before reporting a failure. Already gone, already suspended, already active — that's a success, whatever CWP said on the way.
  • Mailbox passwords were ending up in the WHMCS module log. Masked by shape now instead of by field name.

A few API things I worked out the hard way, in case it saves anyone else the time:

  • email/add takes the local part only, not the whole address. Send test@domain.co.za and you get testdomain.co.za@domain.co.za.
  • email/udp and email/del want mailbox (full address) and password — not email and pass. Wrong names give you an HTTP 500 with Undefined offset: 1.
  • quota is ignored on email/add but applied on email/udp, in bytes.
  • changepack only takes the package ID. A name comes back as a bare Error.



Extract over modules/servers/cwp7/ and run Test Connection.