The shop sold faster than the warehouse could split the parcels
An order management system for a fertiliser maker – it pulls orders from Shopify, splits them into parcels by weight and shipping rules, and drives the whole fulfilment process.
A shop on a hosted platform launches in a week and works fine for the first few months. The trouble starts when volume grows and the product is heavy, liquid or covered by rules on transporting chemicals. At that point an order stops being the same thing as a parcel.
What it looked like before
Scotts Miracle-Gro sells fertilisers and lawn care products. The shop runs on Shopify, which is excellent at taking orders and has no opinion on how to split twenty kilos of product across parcels with a weight limit, or what to do when one line ships from a different warehouse than the rest.
That decision was made by hand, in the warehouse, on every larger order. It works up to a point and then starts to cost: splitting mistakes, repacking, shipments pricier than they needed to be, and a customer who receives three parcels on three different days with no explanation.
What we built
An application that sits between the shop and fulfilment and takes over the order logic.
Pulling orders from the shop. A Shopify integration that takes the order and makes sure none is lost on the way or processed twice.
Splitting into shipments. Weight, warehouse and product rules decide how many parcels an order becomes and what goes into each. The same order splits differently in different configurations, and the system does it rather than a person with a calculator.
Driving the process. The order moves through its states up to dispatch, and every step is recorded. When something jams, it is clear where.
Feeding the business back. Order data comes back in a form that can be used for planning instead of living only inside the shop admin.
What changes day to day
The main shift is that splitting a shipment stops being a warehouse worker’s judgement call. The same rule applies the same way every time, so shipping cost is predictable and “why did this arrive in three parcels” stops depending on how somebody felt that day.
The second shift is resilience. An unguarded shop integration loses orders during any longer outage – and you hear about it from the customer. Here processing is queued and repeatable, so a temporary outage on either side does not cost a lost order.
Why we built it this way
A hosted shop platform is a good place to sell and a poor place to keep a company’s operating rules. The splitting logic therefore lives outside the shop, in a separate application. Changing shipping rules does not mean touching the shop, and changing sales platform later does not mean rebuilding order handling from scratch.
Show the technology stack
- NestJS
- TypeORM
- TypeScript
- RxJS
- Swagger
- Jest
- CQRS
- DDD
- Google Cloud Tasks
- Google Cloud Logging
- Winston