A NestJS integration layer moving 312,000 messages a day between an ERP, a web shop and the accounts system.
View live demo Opens a working demo with sample content in a new tab.
On location
Bricks WallPhoto: Jonas Nilsson Lee (CC0)
Wood LumberPhoto: Sven Scheuermeier (CC0)
Wood LumberPhoto: Jay Mantri (CC0)
Construction ZonePhoto: Leeroy (CC0)
Building ConstructionPhoto: 贝莉儿 NG (CC0)
About the Project
This ERP web shop integration was built for a wholesale building supplies distributor whose systems did not talk to each other. Stock levels were exported to the web shop once a night by CSV, so trade customers regularly ordered items that were already gone. Web orders were printed and re-typed into the ERP, invoices were re-typed again into the accounting package, and nobody could say where an order was without phoning two departments.
We built an integration layer in NestJS that owns the movement of data between the ERP, the web shop and the accounting system. Stock and contract pricing now flow continuously, orders flow back without duplicates, invoices post automatically, and operations staff can see and replay any message from a dashboard.
About the Client
The client is a wholesale distributor of building supplies selling to trade customers through a branch counter and a web shop. Its customers are builders and contractors who order against site deadlines and need to know that what they order is actually in the yard.
Behind the scenes, staff were spending hours re-keying orders and invoices, and every mistake meant a phone call, a credit note or an unhappy customer standing at the counter.
Project Goals
Keep web shop stock and contract pricing in step with the ERP in near real time.
Send web orders into the ERP automatically, with no risk of duplicates.
Post invoices to the accounting system without re-typing.
Make every message visible so problems are found and fixed quickly.
Let non-technical staff recover from failures without calling a developer.
Project Overview
The Challenge and Our Solution
The Challenge
Stock levels were exported to the web shop once a night by CSV, so customers regularly ordered items that were already gone. Web orders were printed and re-typed into the ERP, invoices were re-typed again into the accounting package, and nobody could say where a given order actually was without phoning two departments.
Our Solution
We built an integration layer in NestJS that owns the movement of data between the three systems. Stock and contract pricing flow from the ERP to the web shop continuously; orders flow back with idempotency keys so a retry cannot duplicate them; invoices post to the accounting system automatically. Every message is logged with its payload and outcome, failures retry with exponential backoff and surface on a dashboard, and an operations screen lets staff replay a message rather than call for a developer.
Real-Time Stock and Price Sync
The nightly CSV meant the web shop could be up to a day out of date. The integration layer now listens for stock and contract pricing changes in the ERP and pushes them to the web shop continuously through REST APIs and webhooks. Stock sync lag fell from up to twenty-four hours to under forty seconds.
Trade customers see the stock figure the branch sees and the price their account is entitled to, which ended the orders for items that were already gone.
Continuous stock updates from the ERP
Contract pricing per trade account
Changes queued with BullMQ and Redis for reliability
Idempotent Order Flow
Integrations fail occasionally — a timeout, a restart, a slow API — and the natural response is to retry. Without care, a retry can create the same order twice. Every order sent from the web shop to the ERP carries an idempotency key, so a retried message is recognised and cannot duplicate the order.
Manual re-keying of orders was eliminated entirely, and order status is now visible in one place, ending the inter-department phone calls.
Invoice Automation
When the ERP raises an invoice, the integration layer posts it to the accounting system automatically. The second round of re-typing disappeared, and so did the mismatches that used to surface at month end.
Invoices posted from ERP to accounts automatically
No duplicate entries thanks to idempotent messages
Reconciliation issues surfaced immediately, not at month end
Designing for Failure from the Start
Every integration eventually meets a slow API, a maintenance window or a malformed record. We designed this one on the assumption that it would, so each pipeline has queues, retries with backoff, idempotency and a complete message log from day one rather than added after the first incident.
The result is an integration the business can trust on a busy morning. When the accounting system was unavailable, invoices simply waited in the queue and posted once it returned; when a record was genuinely wrong, staff saw it on the dashboard, corrected the source and replayed the message in a minute.
An Operations Dashboard with Replay
Every message is logged with its payload and its outcome, stored in PostgreSQL. Failures retry automatically with exponential backoff, and anything that still fails appears on an operations dashboard with the reason.
From there, staff can replay a message once the cause is fixed, rather than calling for a developer. Failed messages are retried automatically and replayable by operations staff, so the integration stays dependable without becoming a support burden.
Our Process
How We Delivered It
1
Tracing Data Between Systems
Mapped how stock, prices, orders and invoices moved between the ERP, web shop and accounts — and where they were re-typed.
2
Integration Architecture
Designed a NestJS integration layer with queues, idempotency keys and a message log.
3
Connectors and Queues
Built ERP, web shop and accounting connectors with BullMQ queues, retries and backoff.
4
Operations Dashboard
Created the dashboard showing pipeline health, failures and one-click replay.
5
Parallel Run and Cut-Over
Ran the integration alongside the old process, compared results, then switched off manual re-keying.
Key Features
What We Delivered
Continuous stock & price sync
ERP changes pushed to the web shop within seconds, including contract pricing.
Idempotent order flow
Orders posted to the ERP with idempotency keys so retries never duplicate.
Invoice automation
Invoices raised in the ERP posted to the accounting system without re-entry.
Operations dashboard
Message log, failure queue and one-click replay for non-technical staff.
Outcome
Results and Impact
Stock sync lag reduced from up to 24 hours to under 40 seconds.
Manual re-keying of orders and invoices eliminated entirely.
Order status visible in one place, ending inter-department phone calls.
Failed messages retried automatically and replayable by operations staff.
Client Feedback
What the Client Says
★★★★
Stock used to be a day old and orders were re-typed twice. The integration ended both. It ran a fortnight longer than planned, but they were straight with us about why, and the replay screen means our team fixes a stuck message without calling anyone.
IT ManagerWholesale building supplies distributor
Services
Services Behind This Project
The Node.js, NestJS, API Development & Integration expertise we used to build this api & erp integration — and can bring to yours.
Custom REST and GraphQL API development plus integrations with CRMs, ERPs, payment gateways, shipping carriers and marketing platforms.
Learn more
FAQ
Frequently Asked Questions
Why build an integration layer instead of connecting systems directly?
Direct point-to-point connections are hard to monitor and fragile when one system changes. A dedicated layer owns all data movement, logs every message, handles retries consistently and gives staff a single place to see and fix problems. Adding another system later is also much simpler.
How fast does stock sync between the ERP and the web shop?
In this project, stock sync lag fell from up to twenty-four hours with nightly CSV exports to under forty seconds. Exact speed depends on what your ERP can expose, such as events, webhooks or efficient polling, which we assess early.
What stops a retried order from being duplicated?
Each order carries an idempotency key. If the same message is sent again after a failure, the receiving side recognises the key and does not create a second order. That makes automatic retries safe.
What happens when a message fails?
It is retried automatically with increasing gaps between attempts. If it still fails, it appears on the operations dashboard with the error, and staff can replay it once the cause, such as an unavailable accounting API, is resolved.
Which ERP and accounting systems can you integrate?
Most systems with an API, webhooks or a reliable file interface can be integrated. We review the documentation and test access at the start of the project, because integration options vary widely and they shape the design and timeline.
Do we need developers to run the integration day to day?
No. The operations dashboard is designed for non-technical staff: they can see pipeline health, investigate failures and replay messages themselves. Developers are only needed when a connected system changes or a new pipeline is added.
Similar Work
Related Projects
Case studies built with the same technologies or for similar needs.