Xero Status grid columns
A sortable + filterable Xero Status column on:
- Sales → Invoices (
/admin/sales/invoice/index) - Sales → Credit Memos (
/admin/sales/creditmemo/index)
The chip tells you, at a glance, whether each row reached Xero — without leaving the Magento admin you already live in.
The five chip variants
| Chip | Meaning |
|---|---|
| ✓ Synced | Reached Xero successfully. Hover for the Xero invoice URL. |
| ⏳ Pending | In flight — outbox row enqueued, not yet drained or not yet round-tripped. Typically clears within 60 s. |
| ⏸ Skipped | Filtered out by sync policy. Hover for the skip-reason code (e.g. payment_method_not_mapped, outside_sync_since, zero_value_invoice). |
| ✗ Failed | Hard failure in the chassis — auth issue, validation error, Xero 4xx. Hover for the error-code class (e.g. provider, validation, http). Investigate via the ledger dashboard's sync history. |
| — | No sync attempted. Either the row pre-dates the install, the binding wasn't connected when this row was created, or the row falls outside the sync filters in a way that didn't even produce a skipped_by_policy row. |
Coexistence with Sage Accounting
If you also have byte8/magento-sage-accounting installed, both connectors live side-by-side on the grids — two columns: "Sage Status" and "Xero Status". Each chip reflects sync state for its own provider.
Behind the scenes the Xero grid LEFT JOINs byte8_entity_sync_state with the table alias byte8_sync_fa and column suffix _xero to keep the two providers' UI columns from colliding. You don't need to know about that — but it's why column names like byte8_sync_status_xero show up if you inspect the grid XML.
Sorting + filtering
Click the Xero Status column header to sort. Use the column's filter dropdown to narrow the grid to one chip variant — useful for "show me everything that failed in the last 24h."
Why pending appears immediately
The chip flips to ⏳ Pending the moment the merchant clicks Submit Invoice — not 60 s later when the cron drain finally picks it up. This is the PR7 write-through behaviour:
ByteClient::enqueueEventwrites the outbox row AND apendingrow inbyte8_entity_sync_statesynchronously.- The grid LEFT JOINs against
byte8_entity_sync_state(filtered toprovider = 'xero') per row → chip renders pending immediately.
When the chassis terminal callback lands (typically 5-60 s later), the same row is UPSERTed with the terminal status (synced / skipped / failed). Refresh the grid to see the chip update.
Hover tooltip
The chip's title attribute carries useful context per row:
- Synced → Xero invoice URL (
https://api.xero.com/v2/invoices/<uuid>— opaque to humans but useful in support tickets) - Skipped → skip-reason code (
payment_method_not_mapped,outside_sync_since, etc — see Sync behaviour for the full list) - Failed → error-code class (one of:
auth,not_found,validation,rate_limited,provider,http,database,serde,internal)
For the human-readable Xero reference, see the next page — the detail-page info block shows it explicitly.
What if I see — on an invoice that should have synced?
Three common causes:
- The invoice pre-dates the install. The chassis only writes mirror rows for terminal
mark_*calls after PR7 deployed. Historical invoices (synced before PR7) have no mirror row. Either retry from the ledger dashboard (re-fires the callback and populates the row), or backfill via SQL — see Troubleshooting → Backfill pre-PR7 rows. - Binding wasn't connected when the invoice was raised. Check the chassis dashboard — was the Xero binding
connectedat the time? Reconnect + retry. - Cron isn't running. Verify
bin/magento cron:run --group=defaultworks manually. If your install relies on system cron, check it's calling Magento's cron entry point on the minute.
No chip on Sales → Orders
Intentional. Orders aren't synced directly — we sync invoices, of which an order can have 0..N. A row-level chip on the Orders grid would either need a synthetic rollup (obscuring multi-invoice partial-sync state) or arbitrarily pick one invoice. Operators drill into the Invoices tab from the order to see per-invoice status.
This may change in v1.1 if a design partner asks for an Orders-grid roll-up — let us know if you'd find it useful.
No chip on Customers grid
Same reasoning. One Magento customer maps to one Xero contact, which is simpler than the Sage per-currency model — but a row-level chip would still need to surface "did this customer's contact upsert succeed" without the row-level signal of a specific event. Customer detail-page block with the chassis-resolved Xero contact URL is the planned v1.1+ surface.