AutoSuspend Testing Guide
Important
This guide covers proper testing procedures for the AutoSuspend script. Following the correct sequence prevents “stuck” suspension states.
Overview
The FusionPBX AutoSuspend script automatically suspends/unsuspends client services based on their credit balance. It tracks suspension state in the mod_fusionpbx_suspend_account database table to prevent duplicate operations.
Warning
The script uses state tracking to determine if a service is already suspended. Testing must follow the proper sequence to keep the database state synchronized with the actual gateway status.
How It Works
Suspension Trigger: When client credit ≤ $0 or outstanding invoices exceed credit
State Tracking: Script records
suspend = 'yes'inmod_fusionpbx_suspend_accountSkip Logic: If already marked as suspended, script skips (prevents duplicate API calls)
Unsuspension: When credit is restored, script sets
suspend = 'no'and reverses the configured suspension method (re-enables the gateway or extensions per the product’s Auto Suspend Mode)
Scope, Triggers, and Exemptions
AutoSuspend evaluates every active client holding at least one FusionPBX product. The decision is based solely on the client’s WHMCS credit balance versus outstanding FusionPBX invoices - it does not consult the package’s Real-Time Billing flag, Free Minutes allowance, or tariff configuration.
Condition |
Result |
|---|---|
Client credit ≤ $0 |
All FusionPBX services on the account are suspended |
Outstanding FusionPBX invoices > credit |
All FusionPBX services on the account are suspended |
Credit restored / invoices paid |
Next cron run unsuspends automatically |
Suspension applies to the VoIP service only - the client account and non-VoIP services are never affected.
Suspension Method
The suspension method is configured per product via the module setting Auto Suspend Mode:
Gateway - disables the tenant’s SIP trunk gateway in FusionPBX (blocks all calls)
Extension - disables individual extensions assigned to the service (gateway stays active)
Manual suspension should be performed on the service itself (Client Profile → Products/Services → Suspend) so the configured suspension method is invoked. Client-level toggles do not run the module’s suspend/unsuspend routines.
Exempting a Client
To exempt a client from AutoSuspend entirely - for example, a fixed-fee metered subscription that must never be credit-suspended - set the client custom field FusionPBX Suspended to Never Suspend. The cron skips that client completely.
Note
The exemption is client-level and applies to all of the client’s FusionPBX services. There is currently no per-product exemption.
Free Minutes and Real-Time Billing
Free Minutes is a billing/rating concept only - it has no effect on the AutoSuspend decision. Likewise, the Real-Time Billing flag on a package does not exempt it from AutoSuspend. Any client with a FusionPBX service and a zero or negative credit balance will be suspended on the next cron run unless the Never Suspend flag is set.
Warning
Manually unsuspending a service does not change the credit condition that triggered the suspension. If credit remains ≤ $0, the next cron run suspends the service again - including re-triggering when the tracking table still shows suspend = 'yes' against an unsuspended service. The correct recovery is to add credit or pay the outstanding invoices; the script then unsuspends automatically.
Critical Testing Rules
✅ DO |
❌ DON’T |
|---|---|
Always complete the full suspend → unsuspend cycle |
Manually enable gateway in FusionPBX UI during testing |
Use the autosuspend script for all state changes |
Directly modify |
Run in browser debug mode first to verify logic |
Skip the unsuspend step before testing suspend again |
Check debug output for “Already suspended - skipping” |
Assume the script failed without checking state table |
Verify gateway status directly in FusionPBX tenant |
Use ictVoIPBilling Client Services / Gateways to verify |
Where to Verify Gateway Status
Tip
CORRECT: Check the gateway status directly in the FusionPBX tenant UI:
Login to FusionPBX → Gateways → Check if gateway is Enabled/Disabled
Check Sofia Status to confirm gateway is running/stopped
Danger
INCORRECT: Do NOT use ictVoIPBilling → Client Services → Gateways to verify:
This view is not live - it shows cached/synced data
Must be manually resynced to reflect current FusionPBX state
Will show stale data if gateway was changed by autosuspend
Proper Testing Sequence
Test 1: Suspension
Set client credit to $0 or create unpaid invoice exceeding credit
Run autosuspend script in browser (debug mode)
Verify output shows “Suspending service…”
Check FusionPBX tenant - gateway disabled (Gateway mode) or extensions disabled (Extension mode)
Confirm
mod_fusionpbx_suspend_accountshowssuspend = 'yes'
Test 2: Unsuspension
Add credit to client account (or pay invoice)
Run autosuspend script again
Verify output shows “Unsuspending service…”
Check FusionPBX tenant - gateway/extensions re-enabled per the product’s Auto Suspend Mode
Confirm
mod_fusionpbx_suspend_accountshowssuspend = 'no'
Test 3: Re-Suspension
Remove credit again
Run autosuspend script
Should now suspend properly (state was reset in Test 2)
Troubleshooting Stuck States
If testing was done out of sequence and the script shows “Already suspended - skipping” but the gateway is actually enabled:
Option 1: Complete the Cycle
Add credit and run unsuspend first, then remove credit and suspend again.
Option 2: Reset Database State (Admin Only)
-- Check current state
SELECT * FROM mod_fusionpbx_suspend_account WHERE service_id = [SERVICE_ID];
-- Reset to allow fresh suspension
UPDATE mod_fusionpbx_suspend_account
SET suspend = 'no', updated_at = NOW()
WHERE service_id = [SERVICE_ID];
Warning
After resetting the database, you must run the autosuspend script to re-sync the actual gateway state.
CRON Setup
For production use, set up the CRON job with the ?runfrom=cron parameter:
# Run every 5 minutes (recommended)
*/5 * * * * TZ=America/Toronto curl -s "https://yourwhmcs.com/modules/servers/fusionpbx/autosuspend.php?runfrom=cron" >/dev/null 2>&1
Note
The ?runfrom=cron parameter suppresses HTML output and runs silently.
Debug vs CRON Mode
Mode |
URL |
Output |
|---|---|---|
Debug (Browser) |
|
Full HTML with status messages |
CRON |
|
Silent (no output) |
Database Table
The mod_fusionpbx_suspend_account table tracks suspension state:
Column |
Type |
Description |
|---|---|---|
id |
int |
Primary key |
service_id |
int |
WHMCS hosting service ID |
client_id |
int |
WHMCS client ID |
suspend |
varchar |
Current state: ‘yes’ or ‘no’ |
created_at |
timestamp |
First suspension time |
updated_at |
timestamp |
Last state change |
Script Version: 1.1.0
Author: ictVoIP Canada