DEV Community

Leo Danks
Leo Danks

Posted on

Why We Chose a Custom Laravel eCommerce Build Over Shopify (And What It Actually Cost Us)

We didn't start with Laravel.

While the majority of teams launch using Shopify, it’s a fast way to get up and running with payment processing; we hit $100K in revenue very quickly with zero infrastructure headaches. For an early-stage store, that's genuinely the right call.

Then we hit $400K annual GMV. The app stack started costing us over $700/month. Our checkout flow couldn't do what we needed without a Shopify Plus upgrade. We had three developers spending weekends fighting Liquid template constraints and Shopify's API rate limits instead of building features.

That's when we started seriously evaluating a custom Laravel build.
This post isn't a "Shopify bad, Laravel good" take. It's an honest breakdown, the real architecture, the real numbers, and the honest answer to when each one actually wins.

As a PHP Laravel web development company that has shipped stores on both sides, we've seen enough of both to tell you the truth.

Where Shopify Actually Breaks Down, With Real Numbers

The hidden cost creep

Shopify's pricing page looks clean. Billed annually: Basic at $29/month, Grow at $79/month, and Advanced at $299/month. That's not what you actually pay.

The real cost is your app stack, which analysed all 12,320 apps as of January 2025 the average monthly cost of a single Shopify app is $66.54. Most mid-market stores are running 8–15 paid apps: email marketing, loyalty programs, reviews, subscription billing, advanced search, upsells, shipping rules, and SEO tools.

Here's what a growing store at $500K annual GMV ($41.7K/month) is actually paying on Shopify's Advanced plan (billed annually):

Cost Item Monthly Annual Notes
Advanced plan (annual billing) $299 $3,588 $399/mo if billed monthly
App stack (loyalty, reviews, subscriptions, search, email) $500–$800 $6,000–$9,600 Based on 8–12 apps × $66.54 avg
3rd-party transaction fee (not using Shopify Payments) ~$250 $3,000 0.6% on $41.7K/mo GMV on Advanced
Developer time (theme workarounds, app conflicts) $400–$800 $4,800–$9,600 ~5–10 hrs/mo at $80/hr
Real total $1,449–$2,149 $17,388–$25,788 Before any checkout customization

The technical ceilings that actually hurt

Money is one thing. The invisible wall is the technical one.

Checkout customization is a Plus-only feature. On any plan below Shopify Plus, you cannot modify the actual checkout pages, Information, Shipping, and Payment, where most real business logic lives. As EcomHint's verified 2026 checkout guide confirms:

"You cannot modify the actual checkout pages where most customization needs exist. Those pages require Shopify Plus and Checkout Extensibility."

Do you need a date picker for delivery? Or B2B pricing and checkout? Or a gift-wrapping option that impacts order totals? That's Shopify Plus. Starting at $2,300/month, and most published 2026 sources confirm this as the published entry point, with actual contracts often negotiated higher based on GMV.

You don't own your database. Shopify's API is rate-limited at 2 requests/second on Basic plans (40 requests/minute on higher plans via burst). Every piece of data about your customers, orders, and products lives in Shopify's infrastructure, not yours. Running custom analytics, complex inventory logic, or data pipelines means constantly working around the API.

The 3-tier product variant limit. Shopify allows a maximum of 3 option types (e.g., size, colour, material) and 100 variants per product. For anything more complex, configurable bundles, regional assortments, and B2B pricing tiers, you're back to paying for workaround apps.

The compounding problem: Each limitation sends you to the app store for a solution. Each app costs money, adds latency, introduces potential conflicts with other apps, and creates a fragile dependency chain that a developer has to maintain. By the time you're at $500K GMV, you're often paying more for duct tape than for the platform itself.

What a Custom Laravel eCommerce Build Actually Looks Like

The stack decision: packages vs. fully custom
When a Laravel ecommerce development company sits down to architect a custom build, the first decision isn't Laravel vs. Shopify, it's which Laravel approach to take. There are three real options:

Aimeos- Best for enterprise catalog complexity (millions of products, multi-store, B2B). Heavy but powerful.

Lunar (LunarPHP)- API-first, headless commerce engine built for Laravel. Excellent for teams wanting a modern storefront (React/Vue/Next.js) decoupled from business logic.

Fully custom Eloquent models- Total control. Chosen when the domain logic is so specific that no package fits without fighting it.

For most mid-market stores (5K–50K orders/month), we recommend Lunar + Filament admin + Inertia/React storefront. You will have a mature commerce engine, so there is little need to rebuild the cart and pricing logic. You’ll get an easy-to-use back-office system for your ops and a fast rendering modern front-end.

Architecture walkthrough

// High-level architecture of a Laravel eCommerce build

React / Next.js Storefront ← SSR, Tailwind, fast first paint
↓ HTTP / Inertia
Laravel API Layer ← Routes, middleware, auth (Sanctum)

Lunar Commerce Engine ← Products, cart, pricing, orders, discounts

MySQL / PostgreSQL + Redis ← Data + queue + cache

Queue Workers (Horizon) ← Async jobs: invoices, email, inventory

Filament Admin Panel ← Ops team: orders, catalog management

Real code: product creation with Lunar

Here's what creating a product with variant pricing looks like in Lunar, real production code, not pseudocode:

use Lunar\Models\Product;
use Lunar\Models\ProductVariant;
use Lunar\Models\Price;
use Lunar\DTO\Casts\TranslatedText;
use Lunar\DTO\Casts\Text;

// Create the product
$product = Product::create([
'product_type_id' => $productType->id,
'status' => 'published',
'attribute_data' => [
'name' => new TranslatedText(collect([
'en' => new Text('Premium Wireless Headphones'),
])),
'description' => new TranslatedText(collect([
'en' => new Text('Noise-cancelling, 40hr battery, USB-C'),
])),
],
]);

// Attach a variant with stock
$variant = $product->variants()->create([
'stock' => 150,
'backorder' => false,
'sku' => 'WH-PRO-BLK-001',
]);

// Set pricing in cents — avoids float rounding bugs
Price::create([
'price' => 9999, // $99.99
'compare_at_price' => 12999, // $129.99 — crossed-out price
'currency_id' => $usd->id,
'priceable_type' => ProductVariant::class,
'priceable_id' => $variant->id,
]);

Async order processing with Laravel queues

After the customer's checkout is completed, they will immediately see an "Order Placed!" message. All other processes, including invoice generation, inventory reduction, warehouse notifications, and email confirmations as part of the orders will occur in the background by using chained jobs:

use Illuminate\Support\Facades\Bus;
use App\Jobs{GenerateInvoice, DecrementInventory, SendOrderConfirmation, NotifyFulfillmentTeam};

public function store(Request $request)
{
$order = $this->checkoutService->processOrder($request);

// Chain jobs — if one fails, subsequent ones don't run
Bus::chain([
new DecrementInventory($order),
new GenerateInvoice($order),
new SendOrderConfirmation($order->user),
new NotifyFulfillmentTeam($order),
])->dispatch();

return response()->json(['status' => 'success', 'order_id' => $order->id])

Direct Stripe integration — 0% platform fee

With a Basic Shopify plan that is on an annual basis and uses a third-party payment processor, every order you process through Shopify will have an added 2% Stripe fee (so the Shopify fee will be on top of that), which totals to $5000 a year for a Shopify customer using a third-party payment processor. If they using Stripe on a custom Laravel, then that would not be the case. You pay Stripe's standard rate. No platform cut.

use Laravel\Cashier\Cashier;

// One-time charge — no platform fee, you own the Stripe relationship directly
$paymentIntent = Cashier::stripe()->paymentIntents->create([
'amount' => $order->totalInCents(),
'currency' => 'usd',
'payment_method' => $request->payment_method_id,
'confirm' => true,
'metadata' => ['order_id' => $order->id, 'customer_id' => $order->user_id],
]);
// Webhooks handled by your own listener — you control retry logic entirely

The Real Cost Comparison: Year 1 vs Year 3

The custom build costs more upfront. The Shopify bill grows every year. The following is an actual example of a successful mid-market company that has $500,000 in GMV. All Shopify pricing for plans shown were verified from the Shopify subscription plan price page:

Cost Item Shopify Yr 1 Shopify Yr 3 Laravel Custom Yr 1 Laravel Custom Yr 3
Platform / Hosting $3,588/yr (Advanced, annual) $3,588/yr $1,200–$2,400/yr (VPS/cloud) $1,200–$2,400/yr
App/plugin stack $6,000–$9,600/yr $8,400–$14,400/yr $0 (built-in logic) $0–$1,200/yr
Transaction fees (3rd-party processor) $3,000/yr (0.6% on $500K GMV) $3,000/yr $0 (direct Stripe) $0
Initial dev / build cost $1,500–$4,000 +$2,000–$5,000/yr changes $18,000–$40,000 (offshore) / $40,000–$100,000 (US agency) Low, you own it
Checkout customization $2,300+/mo (Plus) or locked Continues or stays locked Included in build Included
Approx. total (excl. checkout upgrade) $14,088–$20,188/yr $16,988–$25,988/yr $19,200–$44,400 (Year 1) $3,600–$7,200/yr

Break-even point: By eliminating roughly $9,000–$12,600/year in app costs and transaction fees alone (vs. what Shopify Advanced costs), a custom Laravel build funded at $20,000 offshore typically pays for itself by month 19–27. After that, your ongoing infrastructure cost drops by 60–75% compared to a comparable Shopify Advanced setup.

Note:this is a calculated estimate based on the cost table above; your actual break-even point depends on your specific build cost and how many Shopify apps you are running.

When to Still Choose Shopify (Be Honest About This)

We'd be doing you a disservice if we told you Laravel is always the answer. It isn't.
"Use Shopify to validate the business. Build on Laravel when you're scaling the business."

Choose Shopify when...

  • You need to launch in under 4 weeks
  • Your team has no dedicated PHP developer
  • Annual GMV is below $200K
  • You're still validating product-market fit
  • Your catalog is simple, with under 3 option types per product
  • You want built-in marketing tools without engineering

Choose custom Laravel when...

  • App costs + transaction fees exceed $600–$800/month
  • You need checkout logic that Shopify can't deliver without Plus
  • You're building multi-tenant or multi-store
  • Complex B2B pricing, bundles, or regional assortments
  • Annual GMV is above $400K and growing steadily
  • You want to own your data, stack, and roadmap

We've seen teams validate on Shopify Basic, grow to $300K, then migrate cleanly to a custom Laravel build in about 3 months. That's actually a smart path use Shopify as a cheap MVP platform, then invest in a proper build once the business model is proven.

What to Look for in a Laravel eCommerce Development Company

If you've decided you want a custom build, choosing the right laravel web application development company matters more than the architecture decision itself. A bad team can ruin even the best tech stack.

Technical signals that separate serious teams from tutorial-followers

  • They write tests with Pest, not PHPUnit alone. Modern Laravel shops use Pest. If their portfolio shows no testing discipline, walk away.
  • They use Laravel Horizon for queue monitoring. Background jobs are core to any eCommerce operation. A custom Laravel development company that doesn't monitor queues in production will cost you, customers.
  • They have a CI/CD pipeline. Deployments should be automated, not someone SSH-ing into a server and running git pull.
  • They use typed DTOs or Action classes for business logic. Not everything in a controller complex eCommerce logic should live in dedicated service classes.
  • They can explain their zero-downtime migration strategy. A real Laravel application development company will have a documented plan for schema migrations in production, expand-contract pattern, nullable columns first, and background backfills.

The test we actually run on prospective teams

Ask them to show you how they'd test an order that processes a payment, decrements inventory, and sends a confirmation email, all in one feature test. A team worth hiring writes this:
use Illuminate\Support\Facades{Queue, Mail};
use App\Jobs{GenerateInvoice, DecrementInventory};
use App\Mail\OrderConfirmation;

it('processes an order, decrements inventory, and queues confirmation email', function () {
Queue::fake();
Mail::fake();

$user = User::factory()->create();
$product = Product::factory()->withVariant(stock: 10, price: 9999)->create();

actingAs($user)
->postJson('/api/checkout', [
'variant_id' => $product->variants->first()->id,
'quantity' => 2,
'payment_method' => 'pm_card_visa',
])->assertCreated();

Queue::assertPushed(DecrementInventory::class);
Queue::assertPushed(GenerateInvoice::class);
expect($product->fresh()->variants->first()->reserved_stock)->toBe(2);
})

5 questions to ask any Laravel web application development company before hiring

  1. "Show me a deployment pipeline from a past project." You want to see CI/CD (GitHub Actions, Bitbucket Pipelines), not manual deploys.
  2. "How do you handle database migrations in production without downtime?" The answer should include an expand-contract pattern, nullable columns first, and background jobs for data backfills.
  3. "What's your queue monitoring setup?" Horizon + custom alerts. If they say "we check logs manually," end the call.
  4. "How do you test payment integrations?" Stripe's test mode + webhook simulation + feature tests that mock the HTTP calls.
  5. "What happens when a job fails after the payment succeeds but before inventory decrements?" This is a real edge case. A good team has thought about it and has a compensation strategy.

The Decision Matrix: Apply This to Your Project

Stop debating in the abstract. Here's the framework we use when a client asks, "Should we build on Laravel or use Shopify?"

Your situation Recommendation Why
Under $200K GMV, simple catalog, no developer on staff Shopify Basic or Grow ($29–$79/mo annually) Speed to market outweighs everything. Don’t over-engineer early.
$200K–$400K GMV, app costs >$400/mo, standard catalog Shopify Advanced, audit your app stack first You might solve 80% of the pain by removing unused apps before replatforming.
$400K+ GMV, needing checkout logic or multi-store Custom Laravel build The math works. The platform limitations are real. Time to own the stack.
Complex B2B pricing, bundles, ERP/PIM integration Custom Laravel (Lunar or Aimeos) Shopify cannot model this business logic cleanly at any price point.
Validated MVP, need to move fast, raising seed funding Shopify now → Laravel migration plan Use Shopify now, architect the migration at Series A. Document the plan early.
No technical team, no budget for ongoing dev ownership Shopify, full stop A custom build without ongoing dev ownership becomes unmaintainable fast.

The one-line rule: If you're building for 3+ years, build custom. If you're validating for 6 months, use Shopify first. The worst outcome is a half-built custom platform with no tests and a team that moved on, we've been called in to rescue several of those this year.

Conclusion:

Shopify is a great product. We still recommend it to clients who are early, small, or don't have engineering bandwidth. The platform has earned its market position.

But for teams that have grown past $400K GMV, are paying more than $600/month in apps and fees, and keep running into technical walls, the custom Laravel build isn't just a developer preference. It's the financially and architecturally correct decision. Laravel ecommerce development companies with real production experience will tell you exactly what we told you here: the break-even arrives faster than you think, and the ownership advantages compound every year after that.

The build is harder upfront. Owning the stack pays off when your business needs something Shopify simply cannot do.

Top comments (0)