Skip to main content

How it works and daily use

Once the bridge is paired and sync is enabled, it runs by itself. This page explains what it is actually doing, so that when something looks odd you know where to look instead of guessing.

The sync engine in plain languageโ€‹

1. A change raises an eventโ€‹

Every relevant change in WHMCS fires a WHMCS hook: a client is added or edited, a contact is created, an invoice is finalised, a payment lands, an order is placed, a service is provisioned or suspended, a ticket is opened or replied to.

The hook does not make an HTTP call. It writes a small event into an outbox table (mod_perfexbridge_outbox) and returns instantly.

Why the outbox exists

If a WHMCS hook called Perfex directly, a slow or unreachable Perfex server would block a WHMCS admin page or a customer's checkout. Writing to a local table takes a millisecond and can never fail because of somebody else's network. Everything after that happens in the background.

2. The cron drains the queueโ€‹

On every WHMCS system cron tick, the dispatcher takes a batch of due events out of the outbox and POSTs each of them to your Perfex installation over HTTPS.

Each request carries two headers alongside the JSON body: a timestamp, and an HMAC-SHA256 signature computed over that timestamp plus the exact request body, using your shared secret. Perfex recomputes the signature with its own copy of the secret and rejects anything that does not match, or whose timestamp is more than 300 seconds old.

You can force an immediate drain at any time with Run Sync Now on the WHMCS module page.

3. Failures retry, then dead-letterโ€‹

A failed send is not lost, and it is not retried in a tight loop. It is rescheduled with exponential backoff: about 60 seconds after the first failure, then 2 minutes, 4, 8, and so on, capped at 6 hours between attempts.

After 15 attempts, which spans roughly 40 hours, the row is marked dead. Dead rows are never retried automatically and never pruned. They are your dead-letter drawer: the Dead events counter at the top of the WHMCS module page tells you how many there are, and the log row tells you why.

A dead event is a signal, not a disaster

Dead-lettering means the same event failed for nearly two days for the same reason. Almost always the cause is one of four things: a currency missing in Perfex, a secret mismatch, a Free plan blocking a Pro event, or Perfex being offline. Fix the cause and re-queue the work. See Troubleshooting.

4. Pausing does not lose anythingโ€‹

Unticking Enable Sync pauses delivery only. Hooks keep writing events into the outbox, so nothing is dropped while you are paused. Re-enable it and the backlog drains on the next tick, or immediately with Run Sync Now.

5. Echo suppression stops infinite loopsโ€‹

Two-way sync creates an obvious hazard: WHMCS applies a change that came from Perfex, that write fires WHMCS's own hooks, and the change bounces straight back. Left alone, one edit would ping-pong forever.

The bridge prevents this with layered guards, applied on both sides:

  • An in-request origin flag, set while the bridge is applying an inbound change, so writes it makes itself are not treated as fresh user edits.
  • An entity and reply-ID map lookup, so a ticket reply the bridge just created is recognised rather than re-sent as new.
  • A checksum comparison, which turns an event into a no-op when the data already equals the last-synced state.

Each side has its own origin flag, and the checksum acts as a backstop if a flag is ever bypassed. The guards deliberately fail open: if a guard cannot make a decision, one extra harmless send is preferred to a silently dropped update.

6. Housekeepingโ€‹

Both sides run a self-throttled daily prune, at most once every 24 hours:

  • delivered outbox rows older than 7 days are deleted;
  • log rows older than 90 days are deleted;
  • pending and dead rows are never pruned, because pending is undelivered work and dead is your dead-letter drawer.

What syncs, and in which directionโ€‹

WHMCS to Perfex CRMโ€‹

DataFreeProWhat lands in Perfex
๐Ÿ‘ฅ Clientsโœ…โœ…A Perfex customer, plus a primary contact carrying the client's name and email
๐Ÿ‘ค Contactsโœ…โœ…Additional contacts under the same Perfex customer
๐Ÿ—‘๏ธ Client deletionโœ…โœ…The Perfex customer is deactivated, not destroyed
๐Ÿ“„ Invoicesโž–โœ…A Perfex invoice with line items, a tax row, matching totals, status, and the WHMCS invoice number in the admin note
๐Ÿ’ณ Payments and transactionsโž–โœ…A payment record against the mirrored invoice, with the gateway and transaction ID. Duplicates are refused
๐Ÿ’ธ Refundsโž–โœ…The Perfex mirror is cancelled and annotated
๐Ÿ›’ Ordersโž–โœ…A Perfex lead per order, or a note on the customer, or nothing, per Order Sync Target
๐Ÿ“ฆ Servicesโž–โœ…Rows on the customer's WHMCS tab: product name, domain, status, billing cycle, amount and next due date
๐ŸŒ Domainsโž–โœ…Rows on the same tab: registrar, status, expiry and next due date
๐ŸŽซ Tickets and repliesโž–โœ…A Perfex ticket under the customer, in the mapped department, with replies and status
Free tier detail

On the Free plan a client's status and notes travel in the payload but are not written into Perfex. Only client deletion acts on the Perfex record, by deactivating the customer.

Perfex CRM to WHMCS (Pro only)โ€‹

Change made in PerfexWhat happens in WHMCS
Customer company info editedThe WHMCS client record is updated, subject to the conflict policy
Primary contact editedThe WHMCS client identity fields are updated, because the primary contact is the client identity
Non-primary contact editedThe matching WHMCS contact is updated
Staff replies to a mirrored ticketThe reply appears on the WHMCS ticket, attributed to your Ticket Reply Admin if set, otherwise to the Perfex staff name
Ticket status changedThe WHMCS ticket status follows
Perfex-side deletions are never pushed to WHMCS

Deleting a customer or a record in Perfex does not delete anything in WHMCS. Billing records are preserved regardless of what happens in the CRM. This is deliberate and is not configurable.

Known behaviours worth knowing before you rely on themโ€‹

These are documented decisions, not bugs:

  • Tickets created directly in Perfex stay in Perfex. They are never created in WHMCS, because a WHMCS ticket needs a client account and a support department that a CRM-side ticket may not have.
  • Ticket status changed through the full Perfex ticket-settings form does not propagate. The single-ticket status dropdown, replies, bulk status changes and auto-close all sync correctly.
  • Time logged on a per-ticket Perfex task is not synced back to WHMCS. The task exists for native Perfex timesheet reporting.
  • Recurring-invoice cadence is not modelled. WHMCS invoices mirror as plain one-off Perfex invoices.
  • Merging two WHMCS clients is not handled. After a merge, remap or remove the map rows for the absorbed client.
  • A Perfex staff reply on a synced ticket can produce two customer emails, one from Perfex and one from WHMCS. If your customers live in the WHMCS client portal, disable the Perfex ticket-reply email template under Setup > Email Templates > Tickets.

Where the logs areโ€‹

This is the section that saves the most time. People habitually look in the wrong place.

WHMCS side: the module's own pageโ€‹

Go to Addons > Perfex CRM Bridge and scroll to Recent activity.

Not the WHMCS Activity Log

The bridge does not write to the WHMCS Activity Log under Utilities > Logs. Its own table is rendered as the Recent activity panel on the module page, and that is the only place to look on the WHMCS side.

The table shows the last 50 events, with these columns:

ColumnMeaning
TimeWhen the row was written
Dirout for WHMCS to Perfex, in for Perfex to WHMCS
EventFor example client.upsert, invoice.upsert, cron.drain
Entityclient, contact, invoice, ticket, and so on
WHMCS IDThe record's WHMCS ID
StatusGreen ok or red error
MessageThe outcome, or the exact error text

Just above it, the header line shows Queue pending and Dead events counts. Those two numbers are your health summary: pending should drain to zero within a cron cycle or two, and dead should stay at zero.

Perfex side: two panels on the settings pageโ€‹

Go to Setup > WHMCS Bridge.

Recent inbound events lists what WHMCS has sent to this Perfex installation, with the event type, the WHMCS ID, the Perfex ID it mapped to, a status badge and a message. This is where a rejected request appears as an auth.rejected row, which means a signature or timestamp problem, almost always a secret mismatch. Rejected rows are capped at 10 per minute so a flood cannot fill your disk.

Outbound queue lists Perfex-side changes waiting to be pushed to WHMCS, with:

  • pending and dead counts in the panel heading;
  • one row per queued change showing the event, entity, status, number of tries, next attempt time and the last error;
  • a plain-English explanation instead of a raw error where the cause is known. A 403 from an unlicensed WHMCS reads "Two-way sync requires Pro on the WHMCS side" with an upgrade link, rather than a JSON dump.

Only the latest 20 rows are shown. Delivered rows clear themselves after 7 days; pending and dead rows are kept.

Which log answers which questionโ€‹

QuestionLook here
๐Ÿ“ค Did my WHMCS change leave WHMCS?WHMCS: Recent activity, direction out
๐Ÿ“ฅ Did Perfex accept it?Perfex: Recent inbound events
๐Ÿ”‘ Is my shared secret wrong?Perfex: auth.rejected rows in Recent inbound events
๐Ÿ” Did my Perfex edit reach WHMCS?Perfex: Outbound queue, then WHMCS: Recent activity, direction in
โฐ Is the cron running?WHMCS: the Cron delivering checklist row
๐Ÿ”‡ Why is two-way sync silent?Perfex: the WHMCS plan panel. If it says Free, that is your answer

The backfill wizard (Pro)โ€‹

Live sync only ever handles new activity. If you install the bridge on an established WHMCS installation, your existing clients and invoices are not in Perfex until you backfill them.

The Backfill wizard sits on the WHMCS module page, below the settings form. It queues your existing records onto the same outbox that live sync uses, so they inherit the same signing, retries, backoff and dead-lettering.

Scopesโ€‹

Tick one or more:

ScopeWhat it queues
Clients + contactsEvery client in range. Contacts ride along with their client automatically
InvoicesEvery invoice in range
Services + domainsEvery service and domain in range, populating the Perfex WHMCS tab
Tickets are not backfillable

Historical tickets do not sync. Only new ticket activity flows across after the bridge is live. This is a documented limitation, not a configuration problem.

Modesโ€‹

ModeBehaviour
All historyEvery record in the chosen scopes
Date rangeOnly records created inside a YYYY-MM-DD from and to window. An invalid range, for example a "from" later than a "to", is rejected with a clear message and nothing is queued
Only new (not yet synced)Skips records that are already mapped. This is the mode to use for repeat runs

The 500-entity cap and how to resumeโ€‹

Each run queues at most 500 entities, so a backfill on a large installation cannot flood the queue or stall your cron.

When the cap is hit, the wizard tells you. The routine is:

  1. Click Queue Backfill. An information banner reports how many were planned, how many were queued, how many errored, and whether the run was truncated.
  2. Watch the Queue pending counter at the top of the page drain, either on the cron or with Run Sync Now.
  3. Re-run the wizard in mode Only new (not yet synced).
  4. Repeat until a run plans nothing new.

There is no risk of duplicates. Already-mapped records are skipped, and an event whose data already matches the Perfex side is answered as a no-op.

Two ordering rules that save you timeโ€‹

Backfill clients before, or together with, services and invoices

A child record whose parent client is not yet in Perfex is answered "not mapped, will retry" and stays in the queue until the parent lands. Usually the queue's own ordering sorts this out. But if you backfill only services or invoices on an installation whose clients were never synced, those events retry for about 40 hours and then dead-letter.

Either tick Clients + contacts in the same run, or backfill clients first.

Configure your Perfex currencies first

An invoice in a currency Perfex does not know is rejected and retried, and dead-letters after about 40 hours. Before backfilling invoices, add every currency your WHMCS clients use under Setup > Finance > Currencies in Perfex, using the exact ISO code.

Historical paid invoicesโ€‹

Backfilled invoices that were already paid in WHMCS are settled in Perfex with a synthetic payment record, so they show as Paid rather than Overdue. Re-running a backfill does not create duplicate payments.

Everyday operationโ€‹

Once you are set up there is very little to do. A short weekly glance at the WHMCS module page is enough:

What to look atHealthy
Setup checklistAll green, with grey on the licence row if you run Free
Queue pendingSmall, and dropping between cron ticks
Dead events0
Recent activityMostly ok rows
Perfex Outbound queue0 pending, 0 dead, on Pro two-way installs

If anything on that list is wrong, Troubleshooting has the cause and the fix.