Xero Finance Sync
/admin/xero/logs. Engineering guide: Xero Finance Sync Module.
Package soq-sg-xero · permissions 90160–90164
Xero Finance Sync
What this screen is
Sends TMS sales to Xero automatically: contact, invoice, optional payment, optional organization bill, and refund credit notes. Checkout does not call Xero directly; it queues rows so learner payment is not blocked by Xero downtime or missing mappings.
What you see
- Connection & mapping (
/admin/xero): Client ID, encrypted Client secret, Connect / Disconnect, sync switch, sync date, account and tax mapping. - Sync log (
/admin/xero/logs): Pending / Synced / Failed / Skipped rows, Xero document links, dry-run preview, Retry, Retry all failed and Sync now.
Field / control guide
| Field / control | Required? | Operator guidance |
|---|---|---|
| Integration environment | Yes | Choose Live Xero API for real OAuth2 sync or Internal Mock Sandbox for local/UAT verification without real credentials. Strictly locked out on production. |
| Client ID / Client secret | Yes before live connect | Use the Xero app credentials. The secret is stored encrypted; leave it blank later to keep the stored value. Not required in Mock mode. |
| Connect / Reconnect | Yes | Use Xero Demo Company for UAT, then connect the live organisation at go-live. |
| Sync enabled | Yes for live sync | Turn on only after revenue, tax and payment mappings are ready. When off, new paid sales do not create queue rows. |
| Sync sales from | Yes for live sync | Go-live date such as 2026-10-03. Sales before this date are never queued. |
| Currency | Usually SGD | Keep SGD for Singapore courses unless the accountant requires another currency. |
| Default revenue account | Yes | Select a Xero income account such as Sales, Training Income, Course Revenue or account code 200. |
| Diploma / sale-type revenue accounts | Optional | Use only when the accountant wants separate income accounts. Blank values fall back to the default revenue account. |
| GST tax type | Required if GST sales exist | Select the Xero output GST code, commonly Standard-Rated / GST on Income / OUTPUT2 in the demo company. |
| No-GST tax type | Yes | Use NONE / Tax Exempt unless the accountant gives another no-tax code. |
| Online gateway account | Required if creating Stripe payments | Select a bank or clearing account such as Business Bank Account or Stripe Clearing. |
| Create payment switches | Optional | On = invoice plus payment. Off = invoice only; accountant matches the bank feed manually. |
| Wallet / offline accounts | Only for those flows | Map wallet to a wallet liability or clearing account, and offline to the bank transfer account. |
| Organization bills | Optional | Turn on only for organization seller payouts. Requires bill expense account and bill tax type. |
Settings bagInternal Mock Sandbox directly.APP_KEY. |
Accountant Guide: Operating the Internal Mock Sandbox (Sprint 4)
For staging environments, UAT verification, and accountant training without requiring real Xero OAuth2 credentials or affecting live financial books:
- Navigate to Admin → Financial → Xero (
/admin/xero). - At the top of the Connection & mapping card, locate the Integration environment selector.
- Switch from
Live Xero APItoInternal Mock Sandbox. - The system immediately bypasses OAuth token expiration checks and initializes the mock connection as SOQ International Academy (Mock Sandbox).
- The account mapping dropdowns are automatically populated with a standard Singapore Chart of Accounts:
- Revenue Accounts:
200 - Sales Revenue,205 - Course Fee Revenue,260 - Other Income. - Bank Accounts:
400 - Operating Bank Account (SGD),405 - Online Clearing (Stripe),800 - TMS Wallet Liability. - Tax Rates (IRAS):
Standard-Rated (9% GST),Zero-Rated (0%),Tax Exempt (NONE, 0%).
- Revenue Accounts:
- Configure the mapping rules and click Save mapping.
- Create or simulate test purchases on the storefront.
- Navigate to Sync log (
/admin/xero/logs) and click Dry-run or Sync now. The sync runner generates simulated invoices (e.g.INV-MOCK-XXXXX) with audit payloads. - Production Safety Guard: Mock Sandbox mode is strictly locked out in production environments (
!app()->environment('production')), enforcing real OAuth2 credentials for live financial operations.
How to complete the task
- Enter the Client ID and Client secret, click Connect to Xero, and select the organisation.
- Save the minimum mapping: sync date, default revenue account, GST / no-GST tax types, and Stripe payment account or payment creation off.
- Pay for a new course order after sync is enabled. Orders paid earlier are not backfilled automatically.
- Wait at least 60 seconds, open
/admin/xero/logs, preview the invoice payload, then click Sync now or runphp artisan soq:xero-sync --limit=50. - If a row fails, read the error, fix the mapping, and click Retry. Synced rows include a link to the Xero document.
Notes / pitfalls: Sync now only processes rows already present in xero_sync_records; it does not create missing rows for old sales. Production needs the scheduler so soq:xero-sync runs every 5 minutes. The module never pays money out; accountants still pay organization bills and record refund payments in Xero.