Commerce
Autovõti
A car-key cover shop jumping from WooCommerce to Laravel and React, with a key finder, Montonio payments and EU VAT.

In development · replacing WooCommerce
A shop built around one question.
Autovõti sells covers for car keys, and every customer arrives with the same question: which of these fits my key? The answer depends on the car brand and the shape of the key, two things a generic shop platform has no opinion about. The old WooCommerce shop answered it with nested categories, and the same cover had to be filed under every brand that uses that key.
So the shop is making the jump from WooCommerce to Laravel. The home page leads with a finder: pick the car brand, pick the key shape, and the shop shows only the covers that fit. A customer who doesn't know what their key shape is called can take a photo of it instead, and the shop matches the photo to the right shape.

One Laravel application, React in the browser.
It is a single Laravel application with an Inertia and React front end: no
separate API and no second deployable. The server renders Inertia pages with
server-side rendering, and React 19, with the React Compiler, takes over in the
browser. Routes are typed with Wayfinder and localised, so the same product page
lives at /product/… in English and /et/toode/… in Estonian.
Payments go through Montonio, which covers Baltic bank links, cards and buy-now-pay-later in one integration. Delivery is to Omniva parcel lockers, by DPD courier or as pickup. EU VAT is handled properly, with OSS, reverse charge for verified business customers, and live VIES checks.
Checkout
- 01Finder
- 02Cart
- 03Checkout
- 04Montonio
- 05Webhook
- 06Paid
A checkout that can't be talked into anything.
Placing an order is one Action inside one database transaction: the cart is locked, pricing is computed once into a single object, and stock is reserved for 30 minutes rather than deducted. Money is stored in integer cents, order lines snapshot what was sold, and Postgres CHECK constraints refuse negative stock and unknown order and payment statuses even if the code tries.
The customer's browser never marks an order as paid. Only Montonio's webhook can, and only after the amount and currency match what the shop stored, under a lock and behind idempotency keys. Refunds have three outcomes instead of two: a gateway timeout is recorded as pending rather than failed, so the same money can't be refunded twice.

Features
Brand and key finder
Two clicks from car brand to the covers that fit, loaded with Inertia partial reloads.
Search by photo
An AI agent describes the key as structured data, matched against every key shape.
Montonio payments
Bank links, cards and BNPL, confirmed only by a verified webhook.
EU VAT
OSS, reverse charge and VIES checks, with invoices broken down by rate.
Custom admin
A menu builder, a page builder with real-time co-editing, and visual automations.
Designed end to end
All 36 pages and 23 emails redesigned in one interactive studio, now being applied.
Conventions enforced by tests.
The backend keeps business logic in small, final Actions with a single
handle() method; there are 158 of them. Controllers only authorise, map the
request to a typed data object and call an Action. Those rules are Pest
architecture tests rather than a style guide, and the front end has its own
architecture tests in Vitest. PHPStan runs at the highest level with a baseline
that can only shrink, and both line and type coverage are held at 100%.
Technical Highlights
- Laravel 13 and Inertia with React 19
- Typed, localised routes with Wayfinder
- Locked, transactional checkout
- Webhook-only payment confirmation
- Refunds safe against double refunds
- EU VAT with OSS and reverse charge
- Visual search with laravel/ai and pgvector
- Real-time co-editing in the admin
- 100% line and type coverage
The full story
This case study is the short version. The long one, with code, screenshots and the parts that aren't finished yet, is Autovõti: the jump from WooCommerce to Laravel.
Topics