Skip to main content

v1.0.0 — initial release

· 5 min read
Magento + commerce specialists

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 provider column; webhook URL carries ?provider=xero query. 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 carries payment_terms_in_days (Xero quirk #1).
  • Payments (invoice.paid) — bank_transaction_explanation against 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 → Xero Products, virtual / downloadable → Services by default. Per-Magento-type item-type override available. Composite types skipped intentionally.

Coexistence with Sage Accounting

  • Both connectors share the byte8/module-client chassis (outbox, JWT auth, sync-state mirror). Outbox provider column + per-provider grid join aliases (byte8_sync_fa table alias, _xero column 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:inspect triage CLI (provider-filterable via --provider=xero).

Operator surfaces

  • Console commands for outbox triage: byte8:client:outbox:{inspect,requeue,cleanup}. The previous byte8: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}/settings with 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/sync with 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_days required 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 read url to 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-accounting on 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 sends null today. v1.1+ — needs a getter on the provider trait so reference rides 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.captured for 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_reference end-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)