Oh, finally someone said it out loud. I've been screaming this into the void for months. Meta's default attribution is basically a free-for-all: 7-day click, 1-day view. That means if someone sneezes near your ad and buys from an email three days later, Meta still high-fives itself for the sale. Meanwhile your UTM data is sitting there like, "mate, that was a direct click-through from a newsletter." Both are technically correct, they're just measuring different things. Even with CAPI dialled in, you'll still see a gap.
I run a server-side tracking tool for Shopify, but don't worry, I'm not about to pitch you. Honestly, server-side tracking isn't a magic wand for this discrepancy. It fixes the data that never reaches Meta (like browser blocks, iOS chaos, that kind of nonsense), but it won't align Meta's attribution window with your UTM reports. The gap is an attribution problem, not a data loss problem. No tool on the planet reconciles those two worlds, because they speak entirely different languages.
So yeah, you're not going crazy. The numbers will never match perfectly. You just have to pick your poison and know which system is lying about what.