Case Study

Multi-Entity Billing System

Seamless company transition in WHMCS — automatically routing invoices to the correct legal entity based on date, with zero manual intervention.

Client
Internal / Hosting
Timeline
1 Week
Platform
WHMCS
Year
2025–2026

The Challenge

Problem

A hosting business was transitioning between legal entities. All invoices before January 1st 2026 needed to show the original company details (Company Y), while invoices from 2026 onwards needed to display the new entity (Company Z).

  • Different company names, addresses, and VAT details per entity
  • Different logos on invoice PDFs
  • Different bank account details for payments
  • Automatic assignment — no manual intervention per invoice
  • Historical invoices must remain unchanged

The Solution

Solution

Built a custom multi-entity billing module for WHMCS that automatically assigns the correct legal entity to each invoice based on the invoice date. The system uses hooks to intercept invoice creation and template overrides to render entity-specific details.

System Flow

Invoice Created
WHMCS
Hook Fires
Date Check
Entity Assigned
1 or 2
Template Renders
Correct Logo

Implementation

The system consists of four key components: a database table for entity details, a hook for automatic assignment, and template modifications for PDF and web invoice display.

📁 {whmcs_root}/includes/hooks/
billing_entity_assign.php # Auto-assigns entity on invoice creation
billing_entity_template.php # Injects entity data into templates
📁 {whmcs_root}/templates/{theme}/
invoicepdf.tpl # PDF with entity details + logo
viewinvoice.tpl # Client area invoice view
📁 {whmcs_root}/assets/img/
{company_y_logo}.png # Entity 1 logo (pre-2026)
{company_z_logo}.png # Entity 2 logo (2026+)

Core Logic: Simple date-based routing

billing_entity_assign.php
// Automatic entity assignment based on invoice date
if (strtotime($invoiceDate) < strtotime('2026-01-01')) {
    $entityId = 1;  // Company Y (original entity)
} else {
    $entityId = 2;  // Company Z (new entity)
}

// Update invoice with assigned entity
Capsule::table('tblinvoices')
    ->where('id', $invoiceId)
    ->update(['billing_entity_id' => $entityId]);

Database Schema

tbl_billing_entities
CREATE TABLE tbl_billing_entities (
    id INT PRIMARY KEY,
    company_name VARCHAR(255),
    address TEXT,
    vat_number VARCHAR(50),
    bank_details TEXT,
    logo_path VARCHAR(255),
    active_from DATE,
    active_to DATE
);

-- Entity 1: Company Y (historical)
INSERT INTO tbl_billing_entities VALUES (
    1, 'Company Y', 'Address...', 
    'VAT...', 'Bank details...', '{company_y_logo}.png',
    '2010-01-01', '2025-12-31'
);

-- Entity 2: Company Z (current)
INSERT INTO tbl_billing_entities VALUES (
    2, 'Company Z', 'Address...',
    NULL, 'Bank details...', '{company_z_logo}.png',
    '2026-01-01', NULL
);

Results

0
Manual intervention needed
100%
Invoices correctly routed
Instant
Entity transition

The system went live on January 1st, 2026. All new invoices automatically display the new company details, while historical invoices remain unchanged with the original entity information.

Tech Stack

WHMCS PHP MySQL Laravel Capsule Smarty Templates PDF Generation

Need custom billing automation?

We build systems that handle the complexity so you don't have to.

Get in touch