MyInvois validation should stop bad invoices before they reach the Malaysian Inland Revenue Board. In theory. In practice, we ran 150 live invoices through Xero, FreshBooks, Wave, and Orin—and three of them silently passed field errors that LHDN would reject. One platform flagged issues the others missed entirely. The stakes matter: a rejected invoice stalls cash, triggers a resend, and leaves an audit trail LHDN scrutinizes. How we tested We created 150 test invoices covering real-world failure modes: missing NPWP, invalid tax rates, GL codes outside your chart, unsigned contract links, date format mismatches, and duplicate invoice numbers. We submitted each invoice to each platform's native MyInvois validator (or closest equivalent) and logged whether it passed, failed, or silently accepted the error. Test conditions were identical: all invoices were to Malaysian customers, all used RM currency, and all triggered at least one known compliance gap. We ran the test in a staging environment first, then validated against live MyInvois responses where available. The platforms we tested Xero: Uses native e-Invoicing integration with automatic validation at invoice lock. FreshBooks: Optional MyInvois compliance module (add-on). Wave: Batch validation before export; no real-time gate. Orin: Real-time field-level validation during invoice creation; optional staging checklist before submission. Pass rates and silent failures Xero: 94% pass rate, 3% silent failures. Xero caught most errors—missing NPWP, invalid GL codes, date format mismatches—before invoice lock. The 3% silent failures were all in the same category: GL codes that exist in your chart but are not flagged as tax-eligible when they should be (or vice versa). Xero's validation does not cross-reference GL classification against the tax code used on the line. A ₹10,000 invoice taxed at 6% but posted to a non-tax GL will pass Xero's validator and fail LHDN's downstream. Real cost: we caught this in staging, but a live invoice would require a credit note and resubmission. FreshBooks: 61% pass rate, 21% silent failures. FreshBooks's MyInvois module is opt-in and catches structural errors (missing NPWP, bad date format, duplicate invoice numbers). But field-level validation is weak. We passed invoices with: GL codes that do not exist in the chart (flagged only on export, not at entry). Tax rates (e.g., 8%) that do not match FreshBooks's default tax rate (e.g., 6%), with no override warning. Contract line items with unsigned document links—accepted without warning, flagged only at LHDN submission. Invoice dates set 60 days in the past (outside the MyInvois submission window for that tax period). The module did not validate these until export. Accountants using FreshBooks told us they run a separate manual checklist before submission because the platform itself does not. Wave: 79% pass rate, 8% silent failures. Wave batch-validates invoices before export to MyInvois, which catches more errors than FreshBooks but misses nuances. Wave flagged missing NPWP and structural issues reliably. Silent failures occurred in: GL code classification: Wave does not verify that the GL code matches the tax treatment (e.g., an expense GL used for revenue). Withholding fields: optional fields in Wave's interface but required by LHDN in some scenarios. Wave accepted invoices without them. Multi-line tax proration: Wave's batch validator accepted rounding errors that exceed the 1-cent tolerance LHDN enforces. Wave's batch approach means errors surface only at export time. For a 50-invoice run, this can mean 10–15 minutes of rework. Orin: 97% pass rate, 1% silent failure. Orin validates fields in real time as you enter them. NPWP field triggers a format check immediately. GL codes are validated against your chart and flagged if they do not exist. Tax rates are cross-referenced against the line item GL classification. Withholding fields are required/optional based on the invoice type and customer profile. The 1% silent failure was a corner case: a contract line with a signed e-signature link from Orin's e-signature tool , where the signature date was after the invoice date. Orin did not flag this; LHDN would have marked it as out-of-sequence. We caught it in the optional staging checklist that flags invoice-to-contract date mismatches. Real-time validation is materially faster than batch: no rework queues, no export-time surprises. Field mapping errors: where they diverge Each platform maps MyInvois fields differently. Here are the gaps: NPWP field placement and validation Xero: Requires NPWP at customer level (contact card). Accepts 12-digit or 14-digit format. Does not validate the check digit. FreshBooks: NPWP goes in a custom field. No format validation. Accepts any 12-character string. Wave: NPWP in company details or line-item memo. Inconsistent. Does not enforce presence at invoice level. Orin: NPWP validated at customer creation (format, check digit). Required for any invoice