(Amr) Posted April 2 Share Posted April 2 I have reported the following on 19th Feb 2026 : == Affected Version == WHMCS 9.0.1 == Description == When a client attempts to upgrade an existing yearly/recurring service to a one-time (lifetime) service, WHMCS throws a fatal DivisionByZeroError in includes/upgradefunctions.php inside SumUpPackageUpgradeOrder(). This happens on the latest WHMCS version running on PHP 8.3 and occurs even with all custom hooks/modules disabled, indicating a core issue. This was working fine with PHP 7.4 ex : Error: DivisionByZeroError: Division by zero in public_html/includes/upgradefunctions.php:0 Stack trace: #0 public_html/upgrade.php(0): SumUpPackageUpgradeOrder('9043', 10, 'monthly', '') #1 {main} == Steps to Reproduce == Use the latest WHMCS version on PHP 8.3. Create a recurring product (e.g., yearly billing cycle). Create a second product with pay type “One Time”. Set up an upgrade path from the yearly product to the one-time product. Log in as a client with the yearly service. Go to Client Area ? Upgrade/Downgrade and attempt to upgrade to the one-time product. The upgrade page fails with a fatal error. == Expected Result == The upgrade page should load normally == PHP Version == 8.3 == Severity == High This was confirmed to be a bug [ case WHMCS-25204 ]. Since then, two minor versions (WHMCS v9.0.2 & v9.0.3) were released, and this is not fixed yet! 1 Quote Link to comment Share on other sites More sharing options...
wtools Posted April 2 Share Posted April 2 It's unfortunate that they are still not fixed it If you are affected, You should be able to handle this with a hook till they come up with a permanent solution. I had done some hook for upgrade handling in the past, so it should be possible. 0 Quote Link to comment Share on other sites More sharing options...
(Amr) Posted April 3 Author Share Posted April 3 Unfortunately, the error happens before any hook is triggered, so no way to fix it on my end. 0 Quote Link to comment Share on other sites More sharing options...
(Amr) Posted 2 hours ago Author Share Posted 2 hours ago Any update on this ? 0 Quote Link to comment Share on other sites More sharing options...
Evolve Web Hosting Posted 15 minutes ago Share Posted 15 minutes ago 2 hours ago, (Amr) said: Any update on this ? I have not tested this because I'm not using 9.x but this is an AI generated response that you could try on a test install by adding a hook and a small amount of code to clientareaproductdetails.tpl <?php /** * Fix: DivisionByZeroError when upgrading to a one-time product * Affected: WHMCS 9.x + PHP 8.x — upgradefunctions.php::SumUpPackageUpgradeOrder() * * Root cause: PHP 8.x throws a DivisionByZeroError where PHP 7.4 silently * returned 0. When upgrading to a one-time product, WHMCS attempts to * divide by the billing cycle days, which is 0 for one-time products. * * Save as: /includes/hooks/fix_upgrade_onetime_division.php */ // Hook files are loaded before upgrade.php runs its calculations, // so we can register an exception handler here at file level to // intercept the DivisionByZeroError before it becomes a fatal crash. if ( isset($_SERVER['SCRIPT_FILENAME']) && basename($_SERVER['SCRIPT_FILENAME']) === 'upgrade.php' ) { // Capture any existing handler so we can chain it for unrelated errors $previousUpgradeExceptionHandler = set_exception_handler(null); set_exception_handler(function (\Throwable $e) use ($previousUpgradeExceptionHandler) { // Only intercept the specific bug — let everything else propagate normally if ( $e instanceof \DivisionByZeroError && strpos($e->getFile(), 'upgradefunctions.php') !== false ) { $serviceId = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0; header( 'Location: clientarea.php?action=productdetails' . '&id=' . $serviceId . '&upgrade_error=onetime' ); exit; } // Not our error — pass to the previous handler or PHP default if (is_callable($previousUpgradeExceptionHandler)) { call_user_func($previousUpgradeExceptionHandler, $e); } else { restore_exception_handler(); throw $e; } }); } /** * After the redirect, display a clear notice on the product details page * so the client knows what happened and what to do next. */ add_hook('ClientAreaPageProductDetails', 1, function ($vars) { if (empty($_GET['upgrade_error']) || $_GET['upgrade_error'] !== 'onetime') { return []; } return [ 'upgradeOnetimeError' => true, 'upgradeOnetimeMessage' => 'Upgrading to a one-time payment product is not ' . 'supported via the self-service upgrade tool. Please contact support ' . 'and we will arrange this for you manually.', ]; }); Add to clientareaproductdetails.tpl {if $upgradeOnetimeError} <div class="alert alert-warning"> {$upgradeOnetimeMessage} </div> {/if} 0 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.