Most retail software problems reduce to one question: where is the stock, and is that number true?
Almost every visible failure traces back to it. Overselling, delayed dispatch, a customer arriving to collect an item that is not there, a marketplace penalty for a cancelled order: each begins with the system believing it had inventory it did not have. Stock accuracy is not one feature among many; it is the constraint the rest of the architecture serves.
The same discipline applies either side of conventional retail. A marketplace tracks listings rather than stock, and a trade or service business tracks installed equipment rather than either, but the question is the same one: does the record match what is actually there?
What we build
- E-commerce platforms. Custom storefronts and checkout, where an off-the-shelf platform constrains the business model rather than supporting it.
- Inventory management. Stock across warehouses and stores, movements, adjustments, and reconciliation against physical counts.
- Order management and fulfilment. Routing each order to the right location, split shipments, click-and-collect, returns and exchanges.
- Omnichannel integration. One view of stock, customer and order across web, store and marketplace channels.
- Back-office tooling. The interfaces merchandisers and customer service actually spend their day in, which are routinely the least considered part of a retail build.
- Trade and service businesses. Quoting, scheduled servicing, asset registers and invoicing for companies that sell and maintain equipment rather than move stock.
What we design around
Stock is a distributed system
Web, till and marketplace all decrement the same pool, usually without coordinating. That is a concurrency problem, and it needs a concurrency answer.
Reservation at the point of add-to-basket, with an expiry, prevents most overselling. It does not prevent all of it, and the remainder needs a defined resolution path: substitute, refund, partial ship, or backorder. That path should be decided by the business in advance rather than improvised by customer service.
The related decision is whether to sell down to zero. Holding a small buffer against known count inaccuracy costs a little revenue and prevents a lot of cancellations. Which trade-off is right depends on margin and on how forgiving the category is.
Peak is an order of magnitude, not a busy Tuesday
Black Friday traffic is not a scaled-up normal day, and testing against uniform load will tell you nothing useful. The shape matters: browse traffic spikes first, checkout spikes later and harder, and the two stress entirely different parts of the system.
The design principle worth committing to is that checkout degrades last. If something has to fail under load, it should be recommendations, or reviews, or the personalised homepage, never the ability to complete a purchase. That requires those dependencies to be genuinely optional at runtime, which is an architectural decision made long before peak season.
Returns are part of the product
Retailers routinely see return rates well into double figures, and in some categories far higher. Treating returns as an afterthought produces both the worst part of the customer experience and the least reliable stock data, because returned items that are not promptly and correctly restocked are inventory the system cannot see.
Returns need first-class handling: the reason, the condition, whether the item goes back to sellable stock or elsewhere, and how the refund reconciles against the original payment.
Marketplace rules are not yours
Amazon, eBay and similar impose their own dispatch windows, acknowledgement requirements and penalties for cancellation. These are hard constraints that arrive from outside and change without consulting you.
They belong in the integration layer, expressed as per-channel policy, rather than spread through your order logic. A channel-specific rule that leaks into the core fulfilment path is how a marketplace policy change turns into a release.
Pricing and promotions get complicated faster than expected
Base price, channel price, customer-group price, promotional price, multi-buy, basket-level discount, and the order in which they apply. Retailers almost always want more flexibility here than the initial specification suggests, and the promotions engine is a common source of late-project surprise.
Modelling it as data with an explicit evaluation order, rather than as accumulated conditional logic, is what keeps it maintainable once marketing starts using it properly.
Integration landscape
A retail platform typically connects to payment providers, an ERP or accounting system, warehouse management, carriers and shipping aggregators, marketplaces, and increasingly an EPOS system for store stock and click-and-collect.
The ERP is usually the difficult one. It is often older than everything else, frequently the system of record for product and price, and rarely designed for the request volume a storefront generates. Caching from it, rather than querying it live, is normally necessary, which reintroduces the question of what happens when the cache and the truth disagree.
What we would ask you first
How many channels you sell through and which is the system of record for stock; what your current overselling rate looks like and how it is handled; whether you offer click-and-collect or ship-from-store; what your peak is relative to your average; and what your ERP is and how it exposes data.
If nobody can say confidently which system is authoritative for stock, that is the first thing to fix, before any of the rest is worth designing.