An order arrives. Something has to notice, tell a human, hold the details securely, and track the device from that moment to a delivered box. Every e-commerce platform solves this. We built it ourselves, which is usually the wrong answer.
This is why it was the right one here, and where it stops being right.
Why not a platform
We tried. The mismatch was not features — it was assumptions.
Standard platforms assume you take payment online. Ours is cash on delivery, so the entire payment layer is not merely unused but actively in the way: order states assume a payment event that never happens.
They assume inventory. We have none. Devices are built after they are ordered, in a numbered run, so "in stock" is the wrong question and the answer to it is always wrong.
They assume a catalogue. We sell one thing.
We would have been configuring around three core assumptions to get a system that mostly did not apply. The build was smaller than the workaround.
What we built
Order intake. The checkout posts to a small endpoint that stores the order. No payment step, because there is no payment to process yet.
A dashboard behind real authentication. Orders, statuses, customer contact details. Sessions are signed cookies; passwords are hashed with a slow function and a per-user salt; an edge gate rejects unauthenticated requests before any file is served rather than after. This holds names, phone numbers and addresses, so it is protected properly.
Push notifications with a sound. Orders arrive irregularly and a dashboard nobody has open notices nothing. The dashboard installs as an app on a phone and makes a noise when an order lands. This is the single most useful thing we built — the gap between an order arriving and someone knowing about it went from hours to seconds.
A live batch counter. The number on the public site reads from the order system. It is not set by hand and does not reset when it gets uncomfortable.
What we deliberately did not build
- Analytics. Nothing on the public site tracks visitors.
- A CRM. Customers are a list with statuses. Anything more would be building for a volume we do not have.
- Automated emails. Every order gets a phone call instead. Worse at scale, better right now.
- Multi-currency, tax rules, shipping zones. We deliver within one country in one currency.
- An admin UI for editing everything. Some things are changed by editing a file and deploying. That is fine at three people and would not be at ten.
The list of things not built is longer than the list of things built, and that ratio is the point. Most of what a platform offers is infrastructure for problems we do not have yet.
What it actually cost
Less than expected, because the scope was honest. Order intake is a form posting to an endpoint. The dashboard is a list with filters. The expensive parts were the two that touch real risk — authentication and notifications — and both are expensive for the same reason: they have to work every time.
Authentication in particular is not somewhere to be clever. We used well-understood approaches, no invented cryptography, and we test that unauthenticated requests are rejected rather than assuming it.
Where it breaks
Being clear about this, since "we built our own" is a decision with an expiry date:
- Volume. Phone-calling every order stops working somewhere in the low hundreds per month.
- More than one product. Much of this assumes one thing being sold.
- Selling abroad. Real payments, currencies and tax mean using infrastructure built by people who specialise in it.
- More people. Roles, permissions and audit logs are the sort of thing you can skip at three and cannot at ten.
When we hit any of those, moving to a platform is the right call and we will make it without treating this as sunk cost.
The rule we would keep
Build the part that is specific to how your business actually works. Buy everything else, later, when the volume justifies it.
What made ours worth building was not that we could do it better. It was that three of our core assumptions — no online payment, no inventory, one product — are unusual enough that configuring around them cost more than a small system that assumed them from the start.