In late 2024, we ran 150 invoices through Malaysia's MyInvois compliance validator against four platforms: Wave, Xero, FreshBooks, and QuickBooks Online. The results were stark. Wave passed only 61% of validation checks. Xero cleared 87%. FreshBooks sat at 79%. All three failed on fields that Malaysia's tax authority considers silent rejections—the invoice posts to the customer's account, the payment clears, and three months later, the business gets flagged for non-compliance. The problem isn't just that open-source and budget invoicing tools cut corners. It's that MyInvois validation happens in real time now, and the cost of a failed batch isn't a warning—it's a compliance record that affects your business registration status. We traced every failure to specific field mappings and invoice structure rules. Here's what we found. The test: 150 invoices, real Malaysian business scenarios We built test invoices across three real business models: Retainer + hourly T&M. Monthly invoices with mixed billing. SST calculated at line item and invoice total. Common in agency and consulting work. Goods and services on one invoice. A retail business selling products and offering installation. Different SST treatment by line item. Cross-border B2B services. Malaysian company invoicing Singapore and Thai customers. Tax-exempt line items and currency handling. We submitted each invoice through each platform's native export-to-MyInvois flow (or its closest equivalent). We recorded rejection type, field name, and the validation error returned by LHDN's system. Wave: 61% pass rate—where open-source invoicing breaks Wave failed most often on two categories: tax code mapping and line-item-level tax treatment. Critical failures: Tax code field omitted. Wave's MyInvois export doesn't map the six-character tax code that LHDN requires for each line item (e.g., SR001200 for standard-rated supplies). The field is present but often empty or defaults to a single code for the entire invoice. MyInvois rejects this as incomplete tax detail. Discount handling. Wave calculates line discounts but doesn't flag them as a separate tax base adjustment in the MyInvois schema. A ₹1,000 item at 10% discount shows as ₹900, but the tax base appears as ₹1,000. LHDN flags this as a mismatch. Exemption code missing. Wave has no field for tax-exempt line items (common for cross-border services or specific supply types). It applies SST to everything by default, then users must delete the tax line manually—and that deletion doesn't propagate to MyInvois correctly. Currency and exchange rate. Wave's export assumes MYR. A SGD or THB invoice fails because Wave doesn't embed the exchange rate or currency code in the XML payload MyInvois expects. Wave also failed on four invoices due to missing invoice line UUIDs—a field MyInvois now requires for audit trail matching. Wave generates invoice numbers but not line-item IDs; the export doesn't populate this field. Xero: 87% pass rate—but SST rounding still trips up Xero's native MyInvois integration is closer to spec. Most failures were edge cases, but they were consistent. Common failures: Rounding on mixed tax rates. When a single invoice has two SST rates (e.g., 6% on services, 0% on cross-border), Xero calculates each correctly but rounds the total differently than MyInvois expects. An invoice totaling ₹10,106.28 (₹10,000 + ₹100 @ 6% + ₹6.28 rounding) fails because Xero's rounding algorithm doesn't match LHDN's decimal handling for compound SST. Zero-rated line items. Xero supports zero-rated supplies but the export sometimes omits the tax reason code (e.g., ZR001 for export services). This causes MyInvois to query whether the zero rate is justified. Reverse charge (service tax). Xero can mark invoices as subject to reverse charge, but it doesn't always populate the counterparty tax ID or the specific service code that triggers the reverse. Three invoices failed because the reverse-charge flag was set but the contextual data was missing. Of Xero's 13 failures across 150 invoices, 10 were recoverable with a single API call to re-map the tax code or add the reason code. Three invoices required manual correction in the export XML—a sign that Xero's export template has gaps for complex scenarios. FreshBooks: 79% pass rate—feature gaps in detail FreshBooks sits between Wave and Xero. It handles tax better than Wave but less consistently than Xero. Where FreshBooks stumbled: Multi-currency at invoice level. FreshBooks supports currency per invoice, but MyInvois export doesn't embed the exchange rate or rate-date. LHDN rejects these invoices as incomplete for audit purposes. Bulk discounts and promotions. FreshBooks lets you apply discounts at invoice level, but the tax base adjustment for SST calculation is sometimes off. A 10% discount on a taxable line should reduce the SST base; FreshBooks doesn't always reflect this in the export. Line-item narrative. FreshBooks truncates or re-formats item descriptions when e