v1.0.0 — initial release
· 5 min read
The first public release of Byte8 Xero Accounting is out. SaaS connector for Magento 2 → Xero — invoices, credit notes, customers, products, and payments syncing within minutes, with full sync-status visibility from the Magento admin and side-by-side coexistence with Sage Accounting on the same Magento install.
What's in v1.0.0
Connect flow
- Pairing-code Connect — generate a 30-min code in Magento admin, paste into
ledger.byte8.io, the chassis handshakes back. No OAuth client secret on disk, no callback URL wrangling. - Xero OAuth — fully chassis-side. Tokens encrypted at rest (AES-GCM), refreshed transparently, never seen in PHP. Single global API endpoint (
api.xero.com/v2); sandbox available on request. - Per-provider routing — outbox carries
providercolumn; webhook URL carries?provider=xeroquery. Sage + Xero can pair on the same tenant + the same Magento install without colliding.
Outbound sync (Magento → Xero)
- Invoices (
invoice.created) — Open AR with full line items, addresses, currency, per-line discounts, dedicated shipping line. Always carriespayment_terms_in_days(Xero quirk #1). - Payments (
invoice.paid) —bank_transaction_explanationagainst the matching Xero invoice URL, routed per the per-tenant payment-method map. Invoice transitions Open → Paid in Xero. - Credit notes (
creditmemo.created) — refunds routed to the same contact as the original invoice, with shipping refund line and original-invoice date for accountant reporting. - Customers (
customer.upserted) — Magento customer → Xero contact. Lookup-by-email self-heal on duplicate POST 422. - Products (
product.upserted, opt-in) — simple → XeroProducts, virtual / downloadable →Servicesby default. Per-Magento-type item-type override available. Composite types skipped intentionally.
Coexistence with Sage Accounting
- Both connectors share the
byte8/module-clientchassis (outbox, JWT auth, sync-state mirror). Outboxprovidercolumn + per-provider grid join aliases (byte8_sync_fatable alias,_xerocolumn suffix) keep the two from trampling each other. - Sales → Invoices grid renders two columns when both connectors are installed — "Sage Status" + "Xero Status" — each with its own chip and tooltip. Same on credit-memo grid + invoice / credit-memo detail pages.
- Independent pairing + disconnect surfaces; one provider's outage doesn't block the other.
Magento admin visibility (PR7)
- Xero Status column on Sales → Invoices and Sales → Credit Memos grids. Sortable + filterable. Chips: ✓ Synced / ⏳ Pending / ⏸ Skipped / ✗ Failed / —. Hover for Xero invoice URL, skip-reason, or error code.
- Xero Accounting info block on every Invoice + Credit Memo detail page — chip, Xero URL, last sync timestamp, skip / error context.
- Write-through pending mirror — chip appears the moment the merchant clicks Submit Invoice, not 60 s later when the cron drain catches up.
- Dead-letter banner on the config page surfaces failed deliveries + links to the
byte8:client:outbox:inspecttriage CLI (provider-filterable via--provider=xero).
Operator surfaces
- Console commands for outbox triage:
byte8:client:outbox:{inspect,requeue,cleanup}. The previousbyte8:sage:outbox:*namespace is renamed — outbox triage is provider-agnostic and lives on the shared chassis CLI. - Settings dashboard at
ledger.byte8.io/dashboard/bindings/{id}/settingswith five cards: Sync Behaviour, Xero Defaults, Payment-method Map, Item-type Map, Commercial Knobs. Server-side validation against the live Xero reference cache; red-underline field errors before save. - Sync history dashboard at
ledger.byte8.io/dashboard/syncwith full per-event audit + per-row retry button. Provider filter chip lets you scope to Xero rows only. - Disconnect dialog — when disconnecting from the chassis dashboard, a structured "What gets removed" / "What stays" breakdown surfaces before the operator commits.
Catalogued Xero quirks
Two non-obvious Xero v2 behaviours captured + worked around:
- §1 —
payment_terms_in_daysrequired on every POST. Even on net-cash invoices, even on £0 lines. Chassis always sends a value (default 30, configurable per binding). - §2 — Numeric fields stringified on responses.
exchange_rate: "1.0",total_value: "100.00", etc. Chassis decodes create responses through minimal envelopes that only readurlto dodge the asymmetric encoding.
Full catalogue: apps/ledger/__docs/XERO_API_QUIRKS.md. New entries land any time the worker logs a 4xx that isn't an obvious operator typo.
Distribution
byte8/magento-xero-accountingon Cargoman (Byte8 private Composer registry) for the closed-beta cohort. Public Packagist + Magento Marketplace listing follow.
Intentionally NOT in v1
- No Xero Status chip on Sales → Orders or Customers grids. Orders aren't synced directly (we sync invoices, 0..N per order); customer mirror is single-row but the chassis doesn't publish contact-resolution status as a grid signal yet. Order-rollup info block + customer-block surfacing are planned v1.1+.
- No
provider_reference(e.g. Xero's human-readable invoice number) populated on the chip yet. Column exists in the schema; chassis sendsnulltoday. v1.1+ — needs a getter on the provider trait soreferencerides back with the Xero create response. - No manual "Resync now" button on Magento detail pages. Operators use the chassis dashboard's per-row retry; no need to duplicate the surface yet.
- No standalone
payment.capturedfor offline payments. Magento has no API to attach an offline payment to an existing invoice — accountants reconcile manually in Xero's bank feed when the cheque / bank transfer lands. - No Xero → Magento writeback. Enterprise on request — needs Xero webhook surface + Magento write endpoints + conflict-resolution policy. Build only on a custom contract.
- No stock-level sync. Xero's product catalog isn't designed to track inventory; merchants who need stock sync use Sage Accounting instead.
- No projects / timeslips. Out-of-scope for an e-commerce connector.
What's next (v1.1+)
If you have specific asks, email helo@byte8.io. We'll prioritise based on the design-partner cohort feedback. Likely first hits:
provider_referenceend-to-end (the human-readable Xero invoice numbers)- Customer detail-page block (per-binding Xero contact URL)
- Order detail-page rollup block (per-invoice statuses on the order)
- Backfill CLI for pre-PR7 invoices
- Per-customer payment terms map (currently binding-level only)