Sager for Craft CMS

FAQ

What does Sager do?

It connects Craft Commerce 5 to Sage Business Cloud Accounting. Completed orders become Sage sales invoices, customers become Sage contacts, captured payments become contact payments allocated against the invoice, and refunds become sales credit notes. Nobody retypes an order into Sage again.

Which Sage product does it work with?

Sage Business Cloud Accounting, through the Sage Accounting v3.1 API. Sage has also sold it as Sage Accounting, and formerly Sage One. It doesn't work with desktop Sage products such as Sage 50 or Sage 200.

Which Craft, Commerce and PHP versions are supported?

Craft CMS 5.3+, Craft Commerce 5.0+ and PHP 8.2+.

How much does it cost?

$129, then $99 a year for updates. There's one edition, with everything in it.

What's the licence?

Sager is licensed under the Craft License, the same terms as Craft's commercial plugins. Each licence covers one production install. See LICENSE.md.

Do I have to type in GUIDs or build fields?

No. Sage won't accept an invoice line without a ledger account and a tax rate, and both are IDs that differ for every business. Sager reads your chart of accounts and tax rates out of your own Sage business and gives you dropdowns. There's no field, Matrix block or entry type to set up.

Will installing it send my existing orders to Sage?

No. Nothing is sent until you connect, and then only orders completed from that point on are sent automatically. Older orders wait for you to send them, with Queue everything not sent or php craft sager/sync/pending.

Can Sager slow down or break checkout?

No. Everything Sager does with Sage happens in Craft's queue, after the order is complete. If Sage is slow or down, orders queue and retry. A Sage outage can't stop a customer paying, or a refund being recorded.

Can an order end up in Sage twice?

No. Sager records every document it creates, and a unique database index means an order can only ever have one invoice. Only one process at a time can send a given order, so two queue workers can't both post it. Payments and credit notes are recorded per transaction, so they're sent once each.

Will the totals in Sage match Commerce?

Yes, to the penny. Every amount is taken from Commerce's own figures and sent explicitly, so Sage doesn't recalculate anything. The invoice is then checked against the order total. A difference of a few cents gets a visible Rounding line. Anything larger stops the order with an explanation, rather than posting numbers your accountant would have to chase. See Usage.

How is shipping handled?

On Sage's own shipping fields on the invoice, with its own tax rate. It isn't faked as a line item.

How are discounts handled?

A discount on a line reduces that line, and Sage sees the discount amount. A discount on the whole order becomes its own negative line, on a ledger account you choose, so it stays visible in your books.

Does it work with tax-inclusive prices?

Yes. Lines are sent with Sage's price includes tax flag, and the included tax is taken out of the net, using Commerce's own tax figure.

Can I see what will be sent before it's sent?

Yes. Preview payload on any order shows the exact JSON Sage would receive, with a note for every decision Sager made. It's built by the same code as the real push, so it isn't an approximation. php craft sager/sync/preview <number> does the same from the console.

What happens with partial refunds?

Commerce refunds an amount, not specific items, so a partial refund can't be matched to lines. It becomes a one-line credit note, with tax split in the same proportion as the invoice. A full refund mirrors the invoice line for line.

Does it create duplicate contacts?

It tries hard not to. Before creating a contact, Sager looks for one it created before, then for exactly one Sage customer with the same email. Only then does it create one.

Does it sync products or stock?

No, not in this version. Product and stock sync need per-shop decisions that deserve more than a checkbox.

Do changes made in Sage come back to Craft?

No. Sage has no webhooks, so Sager sends from Craft to Sage only. Editing or voiding an invoice in Sage doesn't change anything in Craft.

Does it work on production with admin changes turned off?

Yes. Connecting to Sage, choosing the business, reloading Sage's lists and clearing the log all work on production, because they're stored in the database. Settings and mapping are project config, so they're read-only there. Change them on dev and deploy.

Can dev and production use different Sage businesses?

Not without extra work. The mapping is saved as project config, and its values belong to one Sage business. Connect every environment to the same business, or override the mapping per environment in config/sager.php. See Configuration.

Are my Sage credentials safe?

The client secret has to be an environment variable, so it never lands in project config or git. The OAuth tokens are stored in the database, encrypted with Craft's security key, and never in project config or the log. The log redacts secrets and tokens from every request and response.

What does the log contain?

Every HTTP request Sager makes to Sage and every response, with bodies up to 64 KB, credentials redacted. It does contain customer names, emails and addresses, because that's what you need to see when an invoice goes wrong. It's pruned after Log retention days, 30 by default, and only users with View the connection log and Commerce's Manage orders can read it.

What happens if the connection expires?

Sager stops and says so: Reconnect Sager to Sage. Sage's refresh tokens last 31 days and are replaced on every use, so a lost one can't be recovered. Reconnect from Sager → Settings, then send the orders that failed. See Troubleshooting.

Does it work with several Commerce stores?

Sager sends every store's orders to the one connected Sage business, using one set of settings and mapping. Each invoice is in its order's currency.

What happens to my data if I uninstall?

Sager's five tables are dropped. Everything already in Sage stays there. See Installation.