You deliver work in three shapes: a $2,000 monthly retainer for ongoing support, a $5,000 fixed-price project for a new website, and 12 hours of ad-hoc consulting at $150/hour. Your client wants one invoice. Your accountant wants line-item tax clarity. Your invoicing platform wants to silently fail. Mixed billing—combining retainer, project, and hourly on a single document—breaks reconciliation in most platforms. Tax gets orphaned on hourly rows. Proration math drifts at month boundaries. The reconciliation audit turns into archaeology. We tested four platforms—Xero, FreshBooks, Wave, and QuickBooks Online—against a deliberately complex scenario: a mid-month invoice mixing all three billing types across two tax jurisdictions. Here's what actually works, and where each platform leaks. The problem: Why mixed billing breaks accounting A single invoice with retainer + project + hourly creates three separate revenue recognition patterns and tax treatments: Retainer (time-based): Recognised as earned on invoice date. Tax applies to the full amount. If you invoice mid-month, proration is implied but rarely tracked. Project (fixed-price): Recognised on delivery or milestone. Tax on the invoice amount, not the cost. If the project straddles tax periods, line-item split matters. Hourly (time-tracked): Recognised as hours are logged. Tax applies per line item. If hours span tax weeks or months, each line needs separate tax treatment. When these three live on one invoice, the platform must: Keep each billing type in its own revenue GL account Apply tax correctly to each line, accounting for quantity and date Sync each component back to its source (time tracker, project manager, retainer schedule) Allow the accountant to audit proration without reconstructing the invoice Most platforms do 1–2 of these well. None of them do all four without manual intervention. Test scenario: What we actually invoiced Invoice date: 15 March, 2025. Tax jurisdiction: Malaysia (SST 6%). Client: a mid-market services buyer. Retainer: $2,000 monthly support (prorated to 16 days: $1,032). SST applies to full amount. Project: Website build, milestone 1 completed 10 March: $5,000 (delivered before invoice date, no proration). SST applies. Hourly: 12 hours logged between 1–14 March at $150/hr: $1,800. 8 hours logged 15–31 March: $1,200. Both at SST rate. Invoice total (pre-tax): $9,032. Total SST: $541.92. Net: $9,573.92. The audit requirement: Can the platform (a) split retainer proration per line, (b) keep project revenue separate, (c) show each hourly batch with its own tax calculation, and (d) sync back to GL accounts for revenue recognition without manual reconciliation? Xero: Line-item tax works; reconciliation needs a trace Xero handled the mixed invoice cleanly at the line level. Each line gets its own tax treatment. Retainer proration is explicit—you enter the full amount and the date range, and Xero calculates the daily rate. What worked: Multi-line tax is itemised; each row shows tax separately. Retainer proration is built in—no manual date math. Hourly batch import works if you feed it from a time tracker. Xero reads the date and applies the correct tax rate per batch. GL account mapping is explicit. Retainer goes to revenue code 200, project to 201, hourly to 202. Clean separation. What broke: If hourly hours span two tax weeks or months, Xero doesn't auto-split the line. You must create two separate line items manually, or the tax audit trail becomes unclear. Syncing back to time tracker (Harvest, Toggl) is one-way. Hours logged post-invoice don't update the invoice tax; you reconcile offline. Proration audit is visual, not queryable. You can't run a report that says "$1,032 of the $2,000 retainer for the period 15 March–30 April." You can only see the invoice total. Verdict: Xero is the strongest for mixed billing. Tax math is sound. The gap is post-invoice reconciliation—you need a spreadsheet alongside it to justify proration at audit. FreshBooks: Multi-line works; hourly reconciliation orphans FreshBooks handles retainer and project smoothly on one invoice. Hourly is the fault line. What worked: Retainer and project line items coexist. Tax is calculated per line. Retainer proration is straightforward—mark it as "recurring" and let FreshBooks handle the percentage of the billing cycle. Multi-currency support is native (relevant if you're invoicing across regions). What broke: Hourly time entries don't sync natively to invoices if the invoice is already created. You can import hours into a new invoice, but adding hours retroactively to a mixed invoice requires a new line item or a separate invoice. Tax on hourly batches spanning dates is a single rate applied to the total. If 8 hours are logged in one tax period and 4 in another, FreshBooks applies the invoice date's tax rate to all 12 hours. The audit trail is a single cell: "12 × $150 = $1,800 + 6% tax." Reconciling which tax rate applies to which hour is manual. GL account mapp