CWP Billing imports a ClientExec 6.x or 7.x database. Clients keep their passwords and sign in on a login form with the same field names as before, so saved browser logins keep working. Client, service, invoice and ticket numbers stay the same. ClientExec is only read, never changed. You can import as often as you like: do a test import, check everything, then do the final import on the day you switch.
What is imported
Imported:
- clients with their address, company, VAT number, notes and status;
- client logins, with the passwords they have in ClientExec (see Passwords);
- staff, disabled and without a password: enable the ones you need under Staff and give them a password (2FA is set up again at the first login);
- currencies, product groups and products with prices for each billing cycle, setup, renewal and transfer prices;
- servers (disabled, see step 2);
- packages: hosting packages become services, packages of a domain product group become domains, with domain name, user name, server, IP address, registrar and expiry date;
- invoices with items, payments (PayPal transaction IDs are recognised, payments from account credit become credit), cancellation requests;
- ticket departments, tickets with replies, staff notes and attachments.
IDs and numbers stay the same. Rows created later in the billing start at ID 1,000,000.
How ClientExec data is mapped:
- An invoice that is a draft in ClientExec stays a draft (clients don’t see it). A draft that has a payment date is imported as paid.
- A package whose fee is not recurring is never invoiced by ClientExec, so it is imported without a next due date, with a note on the service. The billing doesn’t invoice it either until you set a date.
- The next due date of a recurring package is the first unpaid invoiced period, otherwise ClientExec’s next bill date.
Not imported:
- Server and account passwords and saved cards. ClientExec encrypts them with its own key.
- E-mail templates. The billing has its own, in 9 languages.
- ClientExec plugins and their settings. Payment gateways and registrars are set up again in the billing.
Step 1: database import
- Install CWP Billing on a fresh installation and leave Automation enabled (Billing settings) off until you switch.
- Give a database user SELECT on the ClientExec database and enter it in
config/config.php:
'clientexec' => ['host' => 'localhost', 'name' => 'clientexec_db', 'user' => 'billing', 'pass' => '…',
'charset' => 'utf8mb4', 'uploads_dir' => '/home/user/public_html/uploads'],
uploads_dir is the ClientExec uploads folder. It is only needed for ticket attachments.
- Run the import:
php bin/console import:clientexec
The import stops if the installation already has its own clients, services or invoices, because ClientExec rows with the same IDs would replace them. Import into a fresh installation, or use --force if you are sure.
Import single parts again with --only:
php bin/console import:clientexec --only=clients,users
php bin/console import:clientexec --only=tickets,replies,attachments
Parts: currencies, admins, departments, clients, users, servers, products, services, domains, invoices, items, transactions, cancellations, tickets, replies, attachments, clientnotes, settings.
Clean-up options
Years of ClientExec usually leave old unpaid invoices and packages that were never billed. These options tidy them up after a full import (they are ignored with --only). Each changed row gets a note, so you can see why it changed.
| Option | What it does |
|---|---|
--cancel-stale-unpaid | Cancels unpaid invoices that don’t belong to a service or domain that still runs. Invoices of live packages stay unpaid. |
--cancel-unbilled | Cancels active services and domains that ClientExec never invoices (no next due date). |
--convert=HRK:EUR:7.5345 | Converts all amounts of a currency you no longer use into another one, at a fixed rate: invoices, payments, services, domains, credit and orders. Each converted invoice gets a note with the original amount. The old currency and its prices are removed. Several conversions are separated by commas. |
Example of a final import:
php bin/console import:clientexec --cancel-stale-unpaid --cancel-unbilled --convert=HRK:EUR:7.5345
Running the same command again gives the same result, so you can repeat it until the switch.
Passwords and the login form
Clients sign in with their old password. The billing recognises the password formats of ClientExec (PBKDF2, sha256:1000:…) and the WHMCS formats that ClientExec took over from an earlier WHMCS (bcrypt, md5:salt, plain MD5). At the first successful login the password is stored again in the billing’s own format.
The import also switches the client login form to ClientExec’s field names (email and passed_password). Password managers and saved browser logins keep filling in the form.
Clients who never had a password in ClientExec (for example accounts created by staff) use Forgot password.
Step 2: settings after the import
- Payment gateways: enter the PayPal, Stripe and other keys and enable the gateways.
- Servers: they are imported disabled because ClientExec encrypts their passwords. Enter the API key or password and enable them.
- Domains → Registrars: set up the registrar and assign it to the TLDs.
- Staff: enable the staff members you need and set their passwords.
- Settings: check the company details, invoice numbering and e-mail sender.
Step 3: switch
- Disable the ClientExec cron, then run the final import (step 1) with the clean-up options you need.
- Point the billing domain, or the old ClientExec domain, to the new installation.
- Change the IPN and webhook URLs in PayPal and Stripe. They are shown under Migration.
- Switch e-mail piping to
pipe.php. - Run
php bin/console billing:preview, check the result, then tick Automation enabled. - In the first days, check Subscriptions and Reports → Gateway reconciliation.
Common problems
| Problem | Cause and solution |
|---|---|
Set the ClientExec database in config.php | The clientexec section is missing or the database user can’t connect. |
stop: … were created here before the first import | The installation is not empty. Import into a fresh installation, or add --force. |
| A client’s password doesn’t work | The account had no password in ClientExec. The client uses Forgot password. |
| A service has no next due date | ClientExec didn’t invoice it (non-recurring fee). Set the date and price on the service, or use --cancel-unbilled. |
| Ticket attachments are missing | Set uploads_dir and run php bin/console import:clientexec --only=attachments. |