ejosterberg / opensalestax-whmcs
WHMCS addon: replace WHMCS's built-in tax handling with the self-hosted OpenSalesTax engine for destination-based US sales tax on hosting / domain / SaaS invoices
Requires
- php: >=8.2
- ext-json: *
- ejosterberg/opensalestax: ^0.1
- guzzlehttp/guzzle: ^7.8
- psr/log: ^1.0 || ^2.0 || ^3.0
Requires (Dev)
- phpstan/phpstan: ^1.11
- phpunit/phpunit: ^10.5
This package is auto-updated.
Last update: 2026-05-16 03:45:30 UTC
README
A WHMCS addon module that replaces WHMCS's built-in tax handling with the self-hosted OpenSalesTax engine for destination-based US sales tax on hosting, domain, and SaaS invoices.
Status: v0.1.0-alpha — first installable release, hosting-provider integration testing pending. See
specs/handoff.mdfor the v0.2 roadmap.
What it does
- Hooks into WHMCS's
InvoiceCreationPreEmailevent (the documented post-tax-calc, pre-email hook). - Reads the invoice + client billing details via WHMCS's Local API.
- Recomputes the tax using your self-hosted OST engine, keyed on the client's billing ZIP-5.
- Overwrites the invoice's
taxandtaxratefields before the customer email goes out. - Logs everything to the WHMCS Activity Log under the
OpenSalesTax:prefix.
What it does NOT do
- Tax filing or remittance — the merchant remits.
- Non-US destinations — anything outside
country = USis left untouched (WHMCS default proceeds). - Non-USD invoices — same: untouched.
- Per-product tax category mapping — every line is treated as
generalfor v0.1 (per-category mapping is a v0.2 enhancement). - Address validation — we trust the WHMCS client's billing address.
Install
Via the merchant ZIP (recommended)
- Download
opensalestax-whmcs-vX.Y.Z.zipfrom the Releases page. - In WHMCS Admin: System Settings -> Addon Modules -> Upload Module, select the ZIP, click upload.
- The addon now appears in the Addon Modules list. Click Activate.
- Open Addons -> OpenSalesTax in the top nav.
- Configure:
- Engine URL — base URL of your self-hosted OST engine, e.g.
https://ostax.example.com. - (optional) API key — bearer token if your engine is auth-gated.
- TLS verification — leave
Yesfor production. - Allow private-network engine URL —
Yesonly for self-hosted-on-LAN. - Fail hard on engine errors — leave
No(default) so engine outages don't block invoice creation. - Per-state nexus filter + Nexus states — leave the filter
Noto engage every US destination. - Cache TTL (seconds) — default
3600. Lower for testing.
- Engine URL — base URL of your self-hosted OST engine, e.g.
- Save.
- Create a test invoice for a US client — verify the tax line uses your destination-based engine output.
Via composer (developer install)
composer require ejosterberg/opensalestax-whmcs
This pulls the source, but you still need to copy modules/addons/opensalestax/ into your WHMCS install. The ZIP build is the canonical merchant artifact.
Compatibility
| WHMCS | 8.x (8.0+) |
| PHP | 8.2 / 8.3 / 8.4 |
| OpenSalesTax engine | v0.14+ (any release that ships the v1 calculate API) |
| OpenSalesTax PHP SDK | ejosterberg/opensalestax ^0.1 (bundled in the ZIP) |
WHMCS 7.x is not officially supported; the addon-module API hooks have been stable since 7.0 but it's untested.
Configuration reference
Settings are stored in WHMCS's tbladdonmodules table under module = 'opensalestax'.
| Key | Type | Default | Notes |
|---|---|---|---|
engine_url |
text | (empty) | Empty = addon is inert |
api_key |
password | (empty) | Optional bearer token |
tls_verify |
yes/no | yes | Constitution §6 |
allow_private_nets |
yes/no | no | Constitution §6 |
fail_hard |
yes/no | no | Constitution §5 |
nexus_enabled |
yes/no | no | Constitution §9 |
nexus_states |
text | (empty) | Comma-separated 2-letter codes |
cache_ttl_seconds |
text | 3600 | Bounded 0-86400 |
Architecture decisions
- Hook choice:
InvoiceCreationPreEmail— seespecs/decisions/001-hook-choice.md. - Calculation only, never filing:
specs/constitution.md§3. - US + USD only:
specs/constitution.md§4. - Fail-soft default:
specs/constitution.md§5.
Development
git clone https://github.com/ejosterberg/opensalestax-whmcs cd opensalestax-whmcs composer install composer check # PHPUnit + PHPStan max + composer audit
Built and tested with PHP 8.2 (XAMPP on Windows). See CONTRIBUTING.md for the commit / DCO / dual-license rules.
To produce the merchant ZIP locally:
PHP_BIN="/c/xampp/8.2.4/php/php.exe" \ COMPOSER_BIN="/c/xampp/8.2.4/php/php.exe /c/Users/ejosterberg/.local/bin/composer.phar" \ bash tools/build-zip.sh
(Linux / macOS users can drop the PHP_BIN / COMPOSER_BIN overrides if php and composer are on $PATH.)
License
Distributed under your choice of:
- Apache License, Version 2.0 (
LICENSE-APACHE.txt), OR - GNU GPL v2 or later (
LICENSE-GPL.txt).
SPDX expression: Apache-2.0 OR GPL-2.0-or-later.
See LICENSE for details. Contributors agree their contributions are licensed under both options (see CONTRIBUTING.md).
Disclaimer
Tax calculations are provided as-is for convenience. The merchant is solely responsible for tax-collection accuracy and remittance to the appropriate jurisdictions. Verify against your state Department of Revenue before remitting.
Sibling connectors
opensalestax-woocommerce(WooCommerce)opensalestax-opencart(OpenCart 4.x)opensalestax-magento(Magento 2)opensalestax-bagisto(Bagisto)opensalestax-invoice-ninja(Invoice Ninja v5)opensalestax-vendure(Vendure)opensalestax-saleor(Saleor)opensalestax-medusa(Medusa)