Lemon Squeezy vs Stripe for a Symfony SaaS: the merchant-of-record decision
Who handles EU VAT, what the fees really buy, when each one wins — and why the sane architecture lets you switch without rewriting your billing.
Every European founder hits this question the week they want to charge money: Stripe or a merchant of record? It looks like a pricing comparison. It's actually a question about who files your taxes — and an architecture question about whether you'll be able to change your mind. ShipAnvil ships both providers behind one interface, so I've implemented each twice over; here's the honest breakdown.
The actual difference: who is the seller
Stripe is a payment processor. Your customer buys from you. You owe the invoice, the VAT determination, the registration thresholds in every jurisdiction where your customers live, and the quarterly filings. Stripe Tax can calculate the right rate for you, but calculating was never the hard part — registering and remitting is, and that stays yours.
Lemon Squeezy is a merchant of record (MoR). Your customer legally buys from Lemon Squeezy, which resells your software. EU VAT, UK VAT, US sales tax where applicable — determination, collection, filing, remittance — are its problem, because it is the seller. You invoice one counterparty: Lemon Squeezy pays you out.
For a solo founder or small team selling worldwide, that single sentence — "VAT is not my problem" — is the entire pitch, and it's a good one.
What you pay for it
Ballpark as of mid-2026 (check the pricing pages — these move): Stripe's base processing in Europe runs a low single-digit percentage plus a fixed fee per transaction, with Stripe Tax, Billing and invoicing as add-ons. Lemon Squeezy charges a flat ~5% + 50¢ on everything — the MoR service, tax handling, checkout, license keys included.
So on a 29 €/month subscription, the MoR premium is very roughly a euro per customer per month versus a fully-assembled Stripe stack. Compare that to what an accountant charges for one foreign VAT registration, and the math at small scale is not subtle: below a few thousand euros of MRR, the MoR premium is the cheapest employee you'll ever hire. At serious scale the percentages flip and finance teams renegotiate — which is why the ability to migrate matters more than the initial pick.
Where each one wins
Lemon Squeezy when: you're small, international from day one, allergic to tax paperwork, selling self-serve at price points where a percentage point is invisible. Bonus: built-in license keys (that's what ShipAnvil itself sells through — the store funnel runs on it).
Stripe when: you need the deepest billing toolbox (usage-based pricing, complex proration, multi-entity), B2B invoicing with your own paper trail, the absolute lowest per-transaction cost, or integrations that assume Stripe (most of fintech does). The API and docs remain the reference standard.
Both, sequenced, is the quiet pro move: launch on the MoR while you're too small to staff tax compliance, switch (or split: B2C on MoR, B2B invoiced via Stripe) when the volume justifies it.
The architecture that keeps the choice reversible
The trap is letting provider vocabulary leak into your domain. If your
code checks stripe_status === 'past_due' in forty places, the MoR
evaluation will feel impossible whatever the spreadsheet says.
The structure that keeps you free — exactly how ShipAnvil's billing module is built:
- One interface for everything a provider does: create a checkout, open the customer portal, cancel, resume, change plan, verify and translate a webhook.
- Normalized state: your
Subscriptionentity speaks your enum (active,trialing,past_due,canceled) and attaches to the organization. Nothing outside the adapter knows whose webhook fed it. - One write path: every provider's webhooks funnel into the same updater (the webhook-inbox pattern — store once, process idempotently through Messenger).
- Plans in config, holding a
stripe_price_idand alemon_squeezy_variant_id. Switching providers is an env var, not a migration; both webhook endpoints stay mounted so a migration period can run them side by side.
Do this and "Stripe vs Lemon Squeezy" stops being a one-way door. Skip it and you've made a five-year decision in week one.
ShipAnvil ships both adapters tested against signed webhook fixtures — full lifecycles, both providers — plus a local sandbox provider so the whole thing runs without any account at all. Walk the checkout in the live demo, or see the pricing if you'd rather not build billing twice like I did.