I’ve been updating my Beancount chart of accounts for clients this week, and the new OBBBA payroll reporting requirements are giving me a headache. Figured I can’t be the only one.
What Changed
Starting with 2026 W-2s, the IRS is requiring employers to separately report qualified tips and qualified overtime using new W-2 fields:
- Box 12, Code TT — Total qualified overtime compensation (only the premium portion, the “half” in time-and-a-half)
- Box 12, Code TP — Total qualified cash tips reported to employer
- Box 14b — Treasury Tipped Occupation Code (TTOC) to verify eligibility
These new fields support the “no tax on tips” and “no tax on overtime” provisions. Employees can deduct up to $12,500 ($25,000 MFJ) in qualified overtime and up to $25,000 in qualified tips from taxable income.
The deductions phase out above $150K MAGI ($300K MFJ), so this primarily benefits hourly workers—restaurants, construction, healthcare, hospitality.
My Beancount Problem
For my 20+ small business clients, my payroll journal entries used to look like this:
2026-03-15 * "Payroll - J. Rodriguez"
Expenses:Payroll:Wages 3,200.00 USD
Expenses:Payroll:Taxes:FICA 244.80 USD
Liabilities:Payroll:FedWithholding -384.00 USD
Liabilities:Payroll:FICA -244.80 USD
Assets:Bank:Checking -2,816.00 USD
Simple. One wages line. But now I need granularity to match the W-2:
2026-03-15 * "Payroll - J. Rodriguez" #payroll
Expenses:Payroll:Wages:Base 2,400.00 USD
Expenses:Payroll:Wages:Overtime:Qualified 600.00 USD
Expenses:Payroll:Wages:Tips:Qualified 200.00 USD
Expenses:Payroll:Taxes:FICA 244.80 USD
Liabilities:Payroll:FedWithholding -384.00 USD
Liabilities:Payroll:FICA -244.80 USD
Assets:Bank:Checking -2,816.00 USD
That’s not terrible for ONE employee. But I have clients in the restaurant industry with 15-30 employees, bi-weekly payroll. That’s 30+ payroll runs per month where I need to correctly split base wages, qualified overtime premium, and qualified tips—and the tips need to be genuinely voluntary (mandatory service charges don’t qualify).
The Importer Challenge
My Python importers pull payroll data from Gusto and ADP CSV exports. Those exports didn’t have separate columns for qualified vs. non-qualified overtime until Q3 2026 (Gusto just shipped the update; ADP still in beta). So for H1 2026, I have to retroactively categorize overtime—cross-referencing time tracking to determine which overtime is FLSA-required vs. voluntary.
Has anyone built a Beancount payroll importer that handles the new W-2 codes? My current approach is ugly:
def classify_overtime(hours_worked, regular_rate, total_ot_pay):
"""Only FLSA-required OT premium qualifies."""
if hours_worked <= 40:
return 0 # No FLSA OT
ot_hours = hours_worked - 40
# Only the premium portion (0.5x) qualifies, not the full 1.5x
qualified_ot = ot_hours * (regular_rate * 0.5)
return min(qualified_ot, total_ot_pay)
Questions for the Community
-
How granular is your payroll account structure? Do you track by pay component (base, overtime, tips, bonuses) or lump everything into one wages account?
-
Are you tracking the $12,500 deduction cap? For employees working heavy overtime, they’ll hit the annual limit. Are you building BQL queries to flag when employees approach the cap?
-
Restaurant/hospitality bookkeepers: How are you separating qualified tips (voluntary) from non-qualified tips (mandatory service charges)? This distinction matters enormously.
-
For FIRE folks tracking your own pay: If your overtime is now effectively tax-free up to $12,500, does this change your savings rate calculations? Your Roth conversion math?
I’ve been a bookkeeper for 10 years and this is the most impactful payroll reporting change I’ve seen since the ACA employer mandate. The IRS gave penalty relief for 2025 W-2s (no separate reporting required yet), but 2026 is the real deal.