Zo for Craft CMS

For Craft Commerce 5

Your store, in your books. Reconciled.

Most accounting connectors are a one-way pipe with a hopeful attitude, and they fail in two expensive ways: a retry writes a second invoice, or Commerce and Zoho quietly disagree on tax until somebody finds it at year end. Zo is built around not doing either.

Zo

Rehearses before it writes

The Preview payload button, the console dry run and the sync itself all call the same builders — so what you are reading is byte-for-byte what Zoho receives. Nothing is sent.

shell
$ php craft zo/sync/order 1042 --dry-run
invoice · 4 lines · total $1,248.60 · nothing sent

$ php craft zo/sync/status
1,904 of 1,911 orders in the books
not reconciled: 1 · failed: 0

$ php craft zo/sync/backfill --queue
7 orders queued, paced under Zoho's 100/min

Features

A link table with a unique index, two totals stored side by side, and a connection log that is safe to hand to somebody else.

It cannot make a duplicate

Every Craft ↔ Zoho pair is a row with a unique index, and Zo claims the row before it sends anything — treating the duplicate-key failure as the answer rather than checking first and inserting second.

  • A queue retry finds the first attempt's row and stops
  • There is one code path that can create a link

Every document is reconciled

Commerce's total and Zoho's total are both stored on the link, because the difference cannot be recomputed later from two systems that have each moved on. If "Not reconciled" is zero, your books agree with your store.

Tax, decided rather than hoped

By default Zo sends no tax rates at all and puts the difference in as one adjustment, so the invoice total equals what the customer paid, to the cent — and a custom adjuster is included without Zo modelling it. Or map your rates and let Zoho compute.

Money moves both ways

Commerce payment transactions become Zoho customer payments, and refunds become credit notes — with the cash movement recorded against your deposit account, which is the part most integrations skip.

  • Zoho cannot refund a paid invoice — a credit note is the correct shape
  • Products become Zoho items, so sales-by-item reporting works

Connects to the right region, first time

Zoho's eight data centres do not share data, and a token from one is a bare 401 at another. Zo reads the region out of Zoho's own redirect and corrects the setting for you, turning the commonest misconfiguration into a non-event.

A log you can hand to somebody

Every call, with the endpoint, the HTTP status, Zoho's own error code and how long it took. Client secrets, refresh tokens and bearer tokens are redacted before the row is written — not hidden on display.

Frequently Asked Questions

The questions worth answering before you connect it to your books.

One price, the whole integration

Zo is $99 with a $79/year renewal. There is no free tier and nothing held back for an upgrade: payments, refunds, item sync, sales orders, mapped tax, custom fields and bulk backfill are all in the one edition.