Xwift Boost: The Boring Integration That Has Run For Years

The Order That Gets Typed Four Times

The client is a production company, and their products have to get to building sites all over Europe. Every one of those shipments starts as a transport order.

Before this platform existed, that order got typed out more than once. Once into the transport management system so the planner could see it. Once into the format the carrier’s own system wanted. Once again, in a slightly different shape, for the tracking platform. And finally into the invoicing, because somebody has to bill the transport.

Four systems, one order, and a human retyping between each pair. Every retype is a chance to swap two digits in a postcode, or to lose the pickup contact, or to invoice the wrong country’s rate.

The failure mode is not dramatic. Nothing crashes.

A truck just turns up at the wrong address, and somebody spends an afternoon on the phone finding out why.

A loading dock at night under sodium light, a driver checking a paper docket against the labels on a stack of crates One order, four systems, and a fresh chance to mistype an address at every hand-off.

What The Platform Does

An order comes in as a webhook. Their system posts it, authenticated with a shared secret, and from that point on nobody touches it by hand.

The platform parses the payload, whether it arrives as JSON or XML. It looks up the pricing table for the destination country and estimates the transport cost. It maps the client’s own customer codes onto internal contractors, finds or creates the contractor record, and finds or creates three separate contacts, because a transport order has a billing address, a delivery address and a pickup address, and they are rarely the same place.

Then it writes the order to the database and generates TAS XML, the format the transport partners speak.

That XML goes out three ways: over FTP to Xwift, over FTP to Go4Log, and over SFTP to FleetGo. Depending on how the contractor is configured, it also goes to TransForm or to XwiftOS.

Invoicing runs through Billit, live against the production API, not a sandbox.

An order that arrives at nine in the morning is in every downstream system before anyone opens the admin screen.

shared secretFTP and SFTPreplayInbound orderParse payloadPrice by countryMap to contractorFind or createcontactsSave orderGenerate TAS XMLPlanning andtelematics systemsInvoiceBillitXML and input kept ondisk
One inbound order, parsed once, then written out to every system that needs it.

The Admin Side

There is a Next.js admin interface on top of all this, because automation that you cannot inspect is not automation, it is a black box that occasionally ruins your week.

Planners can look up any order, see what was received, see what was generated, and see the integration log for every upload attempt. They can regenerate a PDF, mail it, create the invoice, or push the order to the integrations again if a partner’s FTP server was down when the webhook fired.

That last one matters more than it sounds. Partner systems go offline. The point of keeping the generated XML on disk, per order, is that a replay is a button rather than a support ticket.

There is also a small Go service in the stack that does one thing: look up cells in uploaded spreadsheets. Country-specific pricing arrives as XLSX from the business side, and rather than asking anyone to convert it, the platform reads it where it lands.

A planner late in the day at a cluttered desk in a dim office, scrolling records on a laptop with printouts stacked beside it Automation earns trust by being watchable, not by being quiet.

Three Languages, On Purpose

The API is PHP 8.2 on Symfony 6.4 with MySQL. The admin interface is Next.js 13 with React and Material UI. The spreadsheet lookup is Go 1.21, generated from its own Swagger spec.

That is not architectural fashion. Each piece is the shape of its job. The Symfony API is the part with the business rules, the integrations and the persistence, and it is boring, layered code: presentation, application, infrastructure, with the webhook flow as a thin controller delegating to a single action. The front end is a front end. The spreadsheet reader is forty files that read a cell out of an XLSX and has no database at all.

A gradual rewrite of the PHP order path into Go runs alongside it, sharing the same MySQL database, switchable per order with a flag. Right now that flag is off in production and PHP owns the flow.

Migrations that can be turned off one order at a time are the only kind worth doing on a system this old.

What Years In Production Teaches You

This platform has been running for years, which is a different kind of achievement than launching one.

The customer mapping is code, not configuration. The client’s customer codes map to internal contractors in a class that has to be edited when the mapping changes. That is not elegant. It is also honest: the mapping is business logic with exceptions in it, and pretending it is a config table would have hidden the exceptions rather than removed them.

The filesystem is part of the design. Order input JSON and generated XML are written to disk per order, and the integration log reads them back. That looked like an implementation detail for years. It is the audit trail, and it is what makes replay possible.

Uploads can be switched off. In production the webhook path can skip the uploads while the save path in the admin still pushes them. Being able to decouple those two is what lets you debug a partner integration without stopping order intake.

Environments diverge. Production runs on Docker Compose on a legacy host, staging has moved to k3s, and DNS for both happens to resolve to the same address. Anyone who has ever debugged the wrong environment for an hour knows why that fact is written down in large letters.

Who Needs This

Manufacturers who ship a lot and outsource the trucks. If your transport partners each want a different file in a different place, the integration is your problem, not theirs.

Anyone whose order data crosses more than two systems. The cost of a retype is not the minute it takes. It is the wrong delivery, three weeks later, that nobody can trace back.

Companies with a working process and no appetite to replace it. This platform did not replace the client’s systems, or Xwift’s, or FleetGo’s, or Billit. It sits between them and moves the order.

The Point

There is no dashboard here with a number on it that goes up. The measure of success is that transport orders arrive in every system they need to reach, correctly, without anyone typing them a second time, and that this has been true for years.

That is what a good integration looks like. Boring, in the best sense. The interesting part is what stopped happening.


Xwift Boost is built by glue.blue - we stick solutions to problems. Permanently.

Got an order that gets retyped into four systems? → Contact Us

Posted in: Transport, Logistics, System Integration, Manufacturing