A small residential HVAC and mechanical crew was catching payroll mismatches every single week by hand. One call surfaced four separate bugs, and by the end of it, every technician's pay was within about a hundred dollars of what the office had calculated on her own.
Most HVAC owners assume a payroll bug, if one exists, will be big and obvious: a decimal in the wrong place, a technician who got paid twice for the same job, something that jumps off the page. In practice, the bugs that actually cost money are quieter than that. They hide in a dropdown menu, a fee schedule, a job type that got logged wrong on a busy holiday shift. They only show up if someone is checking the math by hand, every week, against a second source.
That's exactly what was happening at a small residential HVAC and mechanical services company running a handful of field technicians out of one back office. The company had recently moved technician commissions onto a dedicated bonus platform, and the office manager, the person responsible for actually cutting checks, kept a shadow spreadsheet. Every week, she ran her own numbers from the same source data and compared them line by line against what the software calculated. Most weeks, they were close. Some weeks, they weren't, and she couldn't always tell why.
The report that didn't match
The mismatches weren't dramatic. A technician's pay would come out $50 high. Another week, a different technician would be missing money for calls that had clearly happened. None of it looked like fraud or a system failure. It looked like noise, the kind of thing that's easy to write off as rounding or a data lag. But noise that shows up every week isn't noise. It's a pattern, and this office manager was sharp enough to keep tracking it instead of shrugging it off.
She raised it on a routine call with her ShareWillow implementation specialist, and instead of promising to look into it later, they opened the actual numbers together, technician by technician, right there on the call.
It's worth pausing on why she kept the shadow spreadsheet in the first place. Plenty of office managers, handed a new payroll tool, would take the software's number at face value simply because that's what it's there for. She didn't, and not because she distrusted the platform specifically. She'd been burned before by systems that looked right and weren't, and she'd learned that the only way to actually know is to run the numbers a second way and compare. That habit is what turned four buried bugs into a fixed problem instead of a slow leak nobody noticed for another six months.
Four things wrong, one phone call
What they found wasn't one bug. It was four, stacked on top of each other in ways that made the final number look plausible even though several separate pieces of it were wrong.
1. The same job, counted twice
The office manager had noticed something odd in her own report: two commission lines with the same job number and the same customer number. "It's weird," she said, and she was right to flag it. A deduplication rule was supposed to prevent exactly this, but it wasn't firing correctly, so a handful of jobs were being paid out twice under two nearly identical entries. It's the kind of error that's almost invisible unless you're the one holding both numbers side by side.
2. A holiday call filed under the wrong job type
The company pays a flat $25 bonus for emergency, after-hours service calls, and that bonus only triggers when a job is tagged correctly. On a July 4th holiday shift, a technician had taken an after-hours emergency call, but whoever logged it that day filed it as a routine residential service call instead of an emergency call. The system did exactly what it was told: it paid the job as routine, and the $25 premium never appeared. Not a software bug so much as a data-entry habit that happens on every busy holiday shift, in every trade.
3. A technician's commissions that just weren't syncing
One technician's service commissions were showing up as close to zero for the period, even though the underlying completed jobs were sitting right there in the source field service report. This one didn't have an obvious cause on the surface. It took pulling up the raw report and tracing individual jobs to confirm the data existed upstream and simply wasn't making it into the payout calculation, a sync issue rather than a data-entry mistake.
4. A fee rule that didn't match how the company actually pays
The fourth issue was a policy mismatch, not a bug in the traditional sense. When a customer pays for a new unit by credit card, this company deducts the card processing fee (a few percent) before calculating the technician's commission on that sale. But that rule was never meant to apply to service commissions, the smaller, more frequent payouts for repairs and maintenance calls. The platform was applying the fee deduction to both, quietly shaving roughly ten percent off commissions that were never supposed to be discounted at all.

Fixing it live, not later
What made this call different wasn't that the bugs got found. Plenty of support calls surface a problem and end with a promise to look into it. This one ended with fixes, in the moment, while the office manager was still on the line watching it happen.
The deduplication logic got corrected first, since it was the fastest fix: a rule was tightened so a repeated job number and customer number combination could only be counted once, and that week's pay run was reprocessed under the corrected logic. The after-hours mapping came next. Rather than relying on office staff to tag every holiday call perfectly under pressure, the job-type logic was rebuilt so the $25 emergency premium ties directly to the "emergency after-hours" job type field, with a plan to review historical entries for the same mistake. The missing service commissions took longer. The rep pulled up the raw report, found the jobs, attempted a live remap, and when that didn't fully resolve it in the moment, filed an engineering ticket rather than pretending the number was fixed when it wasn't. And the fee logic was corrected so the credit card processing deduction applies only where the company's own policy says it should: unit and product sales, not service commissions.
I know I'd added logic where I said don't count the same job number. That is quick to fix.
That's the ShareWillow rep, mid-call, after the office manager pointed out the duplicate lines. It's a small quote, but it captures the tone of the whole conversation: less "let us investigate," more "let's fix this while we're both looking at it."
What the numbers looked like after
The clearest before-and-after came from the two technicians whose pay had the widest gaps that week. One technician's payout closed from roughly $150 off to about $39 off, once a mistaken "solo job" tag (which should have reflected a helper on-site) and the duplicate-job issue were both corrected. A second technician had the steepest gap in the group: the platform's number was short by $50 in missed after-hours premiums and roughly $218 in unsynced service commissions, a combined gap of $268 against the office manager's hand calculation. After the after-hours mapping fix and a manual resync of the missing commissions, that same technician's number landed within $100 of her figure.
Every technician reviewed on that call ended up within about a hundred dollars of the office manager's independent number, down from gaps that had run as high as $268 for one person that week alone.
But the difference is a hundred dollars... very, very close. Perfect.
That's the office manager's own summary, and it's worth sitting with. A hundred-dollar gap isn't zero. But it's the difference between a number she has to personally reconcile every week by hand and a number she can trust enough to spot-check.

Profit sharing
made simple.
Give your team a stake in the company’s success. ShareWillow helps you create and manage profit-sharing programs that motivate employees and drive business results.
Why "close enough" isn't actually the standard
It's tempting to read this story and file it under small potatoes: a few hundred dollars, a handful of technicians, one busy week. But the dollar amount was never really the point. The point is what happens to a crew when a bonus check looks wrong and nobody can say exactly why.
Technicians talk. If one guy's check comes in light two weeks in a row for no reason he can identify, that doesn't stay quiet. It becomes the thing techs mutter about in the parking lot before a job, and once a crew decides the bonus math can't be trusted, the whole incentive stops working as an incentive. It becomes something people tolerate instead of something that motivates them to hustle on the last call of the day.
This is also why the office manager's habit of hand-checking every single week wasn't overkill. It was exactly the right instinct for a system that hadn't yet earned her trust. The goal of fixing these four issues wasn't to make her double-checking unnecessary in theory. It was to make it unnecessary in practice, because the numbers were finally landing close enough, consistently enough, that she didn't have to rebuild them from scratch every Friday.
A quick audit any HVAC or mechanical shop can run today
You don't need to be switching platforms to have some version of these four issues sitting quietly in your own payroll data right now. A few places worth a look:
- Duplicate job protection. Ask what happens, mechanically, when a job gets reopened for a callback, a warranty visit, or a follow-up. Does it inherit a brand new job number that could get counted twice against the same customer record?
- After-hours and emergency tagging. If premium pay depends on a job type field being set correctly, check what happens on your busiest, most chaotic shifts, holidays, storms, the days when dispatch is moving fast and a dropdown gets picked in a hurry.
- Commission sync gaps. Pick one technician and trace three of their completed jobs from your field service software all the way through to their paycheck. If any of them don't show up cleanly, that's worth a second look before it happens to everyone.
- Fee logic by commission type. If you deduct card processing fees on some commission types and not others, confirm your payroll system actually knows the difference. A rule built for unit sales can quietly bleed into service commissions if nobody checks.
None of this requires new software. It requires about an hour with whoever owns your dispatch and payroll data, and a willingness to trace a handful of real jobs end to end instead of trusting the summary total.
You're not the only crew catching this
Quiet payroll drift like this shows up across residential HVAC and mechanical shops more often than most owners assume, and it rarely looks the same way twice. Another HVAC and duct cleaning company found a nearly identical set of payroll bugs hiding in job type mapping and duplicate job counting, while a multi-trade shop had a totally different sync issue causing commission data to fall out of step between systems.
The common thread isn't the specific bug. It's that nobody had looked closely enough, recently enough, to catch it. If you run a technician bonus or commission plan today, whether it lives in dedicated software or a spreadsheet held together with good intentions, treat payroll accuracy as its own project. Whatever industry you're in inside the HVAC and mechanical services world, the fix usually isn't more oversight from whoever runs payroll. It's a system precise enough that they don't have to provide it themselves, every single week, by hand.
Conclusion
Payroll trust isn't built by getting the number right once. It's built by getting it right every week, in front of the person who's checking.
Create incentives
that
drive results
You shouldn't need complex equity plans to align your team. ShareWillow makes it simple to create transparent profit-sharing programs that motivate employees and grow your business.

Incentive plans to help
small businesses thrive.
.png)
"I was able to leverage the knowledge of the ShareWillow team to learn how other companies were designing their bonus plans. The template was extremely helpful."

