We submitted 50 invoices to MyInvois, Xero, FreshBooks, and Wave and logged every failure. Our test set included retainer contracts with GST splits, SST calculations, multicurrency transactions, and mixed billing (hourly + project + retainer on one invoice). The results were uneven enough that one platform consistently caught errors the others missed, and one failed outright on Malaysian tax codes. The test setup: What we actually submitted Our 50 invoices were real—drawn from three months of billing across Malaysia, Singapore, and Indonesia. We split them into five categories: Retainer invoices (10) : Monthly recurring with GST or SST applied to the full amount, then split across service lines. Tax ID validation at invoice start. Mixed billing (10) : Hourly rate (line 1), fixed project fee (line 2), retainer credit (line 3). Each line with different tax treatment. A real-world nightmare. Multicurrency (10) : SGD invoices to Malaysian clients, USD invoices to Indonesian vendors. Exchange rate rounding and tax-inclusive totals under test. SST edge cases (10) : Invoices with SST at 6% on services, 0% on digital services, mixed on one invoice. Vendor tax ID format validation. GST reversals (10) : Invoices issued, then reversed with credit notes. Tax ID matching on reversal documents. Each platform received the same 50 invoices via its native UI (not API), then we validated the result against the LHDN MyInvois test environment. We logged pass, fail, warning (invoice accepted but with deviation from tax code), and error (invoice rejected outright). Xero: 48/50 passed, but one SST rounding error was silent Xero's pass rate was the highest, but the failure was instructive. On a ₹50,000 invoice with 6% SST split across three service lines, Xero rounded the SST on line 2 up by 1 rupiah. The invoice total was correct (₹53,000), but the tax allocation did not match the LHDN line-item audit trail. Xero flagged a warning in the UI, but did not block submission. The other failure: a multicurrency SGD invoice to a Malaysian client. Xero accepted it but did not validate that the vendor's tax ID was Malaysian format. The invoice passed Xero's own checks but failed at LHDN submission because the tax authority expected a Malaysian BRN on a SGD-billed invoice to a MY entity. This is a subtle but costly gap—the invoice was rejected, requiring a resubmission with corrected metadata. Pass rate: 48/50 (96%). Failures: SST rounding mismatch (1), tax ID format for foreign currency (1). FreshBooks: 44/50 passed; retainer and SST splits broke consistently FreshBooks struggled with invoices that used service splits. On retainer invoices with GST applied to a multi-line split, FreshBooks applied the tax at the invoice level first, then allocated it back to lines. This created rounding errors on 4 out of 10 retainer invoices. The tax total was correct, but the line-item detail did not reconcile, and LHDN rejected 2 of those 4 due to audit-trail mismatch. On SST invoices, FreshBooks did not allow per-line tax rates. If you wanted 6% SST on one service and 0% on another, you had to create two separate invoices or use a workaround that FreshBooks did not document. We tested both; both failed validation because the invoice structure did not match the LHDN schema. Multicurrency invoices went through, but FreshBooks did not warn when you issued a SGD invoice to a Malaysian entity with an Indonesian tax ID. It should have, and LHDN rejected it. Pass rate: 44/50 (88%). Failures: retainer line-item tax split (4), SST per-line tax rate (2). Wave: 41/50 passed; tax ID validation was absent Wave had the lowest pass rate. The platform did not validate tax ID format at invoice creation. We submitted invoices with typos in vendor tax IDs (e.g., a Malaysian BRN with one digit transposed), and Wave accepted them without warning. LHDN rejected all 3. Wave also could not handle mixed-billing invoices with different tax treatments per line. On 6 out of 10 mixed-billing tests, Wave either collapsed the lines into a single tax rate or required manual override. Two of those 6 ended up as warnings (accepted but flagged) instead of passes. SST invoices worked better than in FreshBooks, but multicurrency invoices were a weak point. Wave did not flag currency-mismatched invoices (e.g., SGD to a MY entity with a MY tax ID but no MY currency default), and 2 failed at LHDN. Pass rate: 41/50 (82%). Failures: missing tax ID validation (3), mixed-billing tax splits (4), currency mismatch (2), SST per-line treatment (1). FreshBooks and Wave: The core problem Both FreshBooks and Wave were designed for North American markets first. Their tax logic assumes a single tax rate per invoice (or a simple two-tier system like US sales tax + shipping tax). Southeast Asia's SST regime—where tax rates vary by service type, and you need granular line-item control—does not map cleanly onto their data model. This is not a bug; it's a design mismatch. Fixing it would require rearchitecti