Skip to content

Laravel and Sage. Which Sage, Though?

Sage is a family of products with almost nothing in common at the API layer. Working out which one a client runs, and where it runs, decides the architecture before a line is written.

6 min read

A discovery call where someone says "we use Sage" has told you roughly as much as "we use a database". It narrows the vendor and nothing else. The products that share the name were built in different decades by different companies, several of them acquired, and at the point where your Laravel application has to talk to one, they have close to nothing in common.

This is not a complaint about Sage. It is a very large product family serving businesses from a sole trader to a manufacturer with plants in four countries, and no single interface would serve both. But it does mean the first hour of the project is a question rather than a schema.

The question that decides everything

Sage Accounting, the small-business product, is a hosted service with a REST interface and OAuth 2. If that is what the client runs, the integration looks like any other modern SaaS integration and the work is the business rules.

Sage 50 is a desktop application with a data file. Depending on the edition and the era, the way in is a driver or a local service that runs on the machine holding that file. The important word in that sentence is local: the thing you would call is not on the internet and was never meant to be.

Sage 200 splits. One edition is hosted by Sage with a published interface. The other is installed on the customer's own servers, and its interface runs there, behind whatever the customer's network does. Those two are not the same integration and they are not the same estimate.

Sage Intacct and Sage X3 are different products again, aimed at larger finance teams, with their own interfaces, their own authentication and their own vocabulary for the same accounting concepts.

So the questions to get answered before anyone commits to a date:

  • Which product, and which edition of it.
  • Where it physically runs, and who administers that machine.
  • Which version, because interfaces have been added and retired across versions.
  • Who at the client can grant access, and how long their approval takes.

That last one is not a technical question and it is frequently the longest item on the plan.

When there is nothing on the internet to call

Say it is Sage 50 on a server in the client's office, or Sage 200 on their own infrastructure. Your Laravel application is on a host somewhere with a public address. There is no route between them, and no library fixes that.

There are three honest shapes for this, and they are choices about the client's infrastructure as much as about your code.

A connector the client installs. A small process on their network, next to the Sage data, which talks outward to your application over HTTPS. Because it makes the connection, no inbound firewall rule is needed, which is what makes it acceptable to most IT departments. It also becomes software you have to version, monitor and support on a machine you cannot log into.

A private network path. A VPN or a dedicated tunnel between their network and your host. Cleaner to reason about once it exists, and it exists when their IT team has time, which is the risk. Worth pushing for when the client already has this arrangement with another supplier.

File exchange. Export from your side on a schedule, drop it where the product imports from, or read the export it produces. Dismissed too quickly by people who prefer APIs. It is observable, a failed run leaves the file sitting there, and a person can open it and see what was wrong.

Whichever it is, the design consequence is the same and it should be stated to the client in the first week: the data in your application is a copy with a delay, the delay depends on a machine in their building being switched on, and the interface has to say so rather than presenting a stale figure as current.

Queue everything, and mean it

Against Sage Accounting this is ordinary advice. Against an on-premise install it is the difference between a working system and one that falls over every Thursday afternoon when their weekly reports run and the server is busy.

A synchronous call into a system like that will eventually take ninety seconds, and if it is inside a web request you have a timeout, a user who has seen an error, and no reliable way to know whether the write landed. Put every interaction on a queue, give it a generous timeout, and make the retry safe - the same at-least-once reality applies here, with the extra hazard that the other side may not be able to tell you whether your first attempt succeeded.

Keep a record of each attempt with the request, the response and the timestamp, and keep it for longer than you think you need. When the finance team asks in March why a February invoice is missing, that table is the only thing that answers.

VAT, and staying out of it

For UK clients this comes up immediately, because Making Tax Digital means VAT returns are submitted from software rather than typed into a website.

The instinct is to build the submission. Usually the correct move is the opposite. If the business keeps its VAT record in a supported Sage product, that product submits, and your integration's job is to make sure the numbers reaching it are right and arrive before the deadline. Adding a second submission path creates a reconciliation problem with a tax authority at the end of it.

Where it does become your problem is the shape of the data you hand over. Tax point versus invoice date, the treatment of a credit note issued in a later period, rounding at line level against rounding at invoice level, and reverse charge on cross-border supplies. Get those wrong and the submission is correct software producing an incorrect return. The engagement notes for our UK work go into what that means contractually.

What to do before writing code

Ask for a copy of the data, or read access to a test company. Not a specification, not a screenshot: the actual records, with the fields the client's staff have renamed and the customer accounts that were set up in 2011 and never tidied. Every estimate that goes badly wrong was made from a description of the data rather than the data.

Then write down the direction of truth for each entity, in a document the finance team signs off rather than one only developers read. It is a page of prose. It is also the only artefact from the project that still matters in two years, because the code gets rewritten and that page is what the rewrite is checked against.

If the ledger is Xero rather than Sage, the access question disappears and a different one replaces it - the token lifecycle, which has a failure mode that disconnects customers silently. Our integration engineering page covers how both kinds of engagement are scoped.

Related questions

Can we just use the Sage API?
There is no single Sage API. Sage Accounting, Sage 50, Sage 200, Sage Intacct and Sage X3 are separate products with separate interfaces, separate authentication and, in several cases, separate hosting models. Work out which product and which edition before anyone estimates the work, because the answer changes the architecture rather than the details.
The client says their Sage is in the cloud. Does that settle it?
Not by itself. Several Sage products are commonly run on a hosted Windows desktop, which the people using them reasonably describe as being in the cloud because they reach it through a browser. That is not the same as a product with an internet-facing API, and the difference decides whether you can call it at all. Ask what they see when they log in.
Do we have to handle VAT submission ourselves?
Usually not, and usually you should not want to. Where a supported Sage product is already the business record for VAT, it submits to HMRC itself, and an integration that also submits creates two filings and an argument. Your job is normally to get accurate data into it early enough for the deadline.
What if there is no usable API at all?
Then the integration is a file exchange, and that is a legitimate answer rather than a defeat. A watched folder, a CSV in the layout the product imports, an import run on a schedule. It is unglamorous, it is auditable, and for a business filing monthly it is often the correct amount of engineering.

← Back to all articles

Call us+1 848 272 7583WhatsApp+90 850 308 5436Emailinfo@codefacture.comContact page