Shopify + Xero Integration
Sales, fees, refunds, and payouts flow from Shopify into Xero as invoices or daily summary journals, with a clearing account that makes the bank feed match to the cent. Xero keeps the books. It does not keep your stock, and this page is honest about why.
- mode:
- Shopify → Xero
- latency:
- Daily summary or per order
- maturity:
- Production-tested
what syncs
What syncs, which way, and how fast
Every row is a real data flow with a real trigger. The frequency column is what you should expect in production, not a best case.
Sales
- dir:
- Shopify → Xero
- frequency:
- Daily summary (default) or per order
The design decision that shapes everything else. Summary mode posts one invoice or journal per day, per currency and gateway. Per-order mode creates an ACCREC invoice for every checkout and stops scaling as volume grows.
Payouts and fees
- dir:
- Shopify → Xero
- frequency:
- Per payout
Shopify Payments deposits arrive net of fees. Gross sales sit in a clearing account, fees post to expense per payout, and the transfer matches the bank feed line to the cent.
Refunds
- dir:
- Shopify → Xero
- frequency:
- With each sync
Credit notes in per-order mode, negative lines in summary mode. A refund landing in a different payout than its sale is the classic reconciliation trap.
Customers
- dir:
- Shopify → Xero
- frequency:
- On order (B2B only)
B2C revenue posts against a single web-sales contact. Xero requires unique contact names, so syncing every buyer builds a contact list nobody can use.
Products
- dir:
- Shopify → Xero
- frequency:
- Optional
Line items can carry Xero item codes for sales reporting by product. We default to untracked items; see the inventory row for why.
Inventory
- dir:
- Not synced (deliberate)
- frequency:
- n/a
Xero tracked inventory is not a stock master at retail volume. Shopify or a dedicated inventory app owns quantities; Xero owns the values.
architecture
How it actually works
Xero is cloud-native with a well-documented OAuth 2.0 API, so connectivity is the easy part. The real design work is accounting design: which posting model, which clearing accounts, and how to stay inside per-minute and daily rate limits without falling behind.
Shopify webhooks + payout data
Order and refund events arrive by webhook, verified and queued rather than processed inline. Payout and fee detail is read from Shopify Payments so fees are recorded per payout as charged, not estimated from a rate card.
Queue + idempotency store
Every message carries the Shopify event id and processed ids are recorded, so a redelivered webhook can never post the same revenue twice. In an accounting integration a duplicate is not a nuisance, it is a misstatement.
Posting engine
Groups the day’s orders into summary invoices or journals per currency and gateway, or builds per-order invoices where volume allows. Chart of accounts, tax rate, and gift card rules live here, versioned and auditable.
Xero Accounting API
OAuth 2.0, connected per Xero organisation. Writes invoices, credit notes, payments, and manual journals, paced under Xero’s published rate limits with backoff and resume rather than dropped calls.
Reconciliation layer
One clearing account per payment gateway. Payout transfers are created for the exact net amount so the bank feed line matches in one click, which is the entire point of the design.
failure modes
What breaks, and what happens when it does
Every integration fails eventually. The difference between a good one and a bad one is whether it fails safely and tells you.
Per-order push hits Xero rate limits
A flash sale runs, and Xero falls hours behind with the queue still draining the next morning.
handling
Xero enforces per-minute and daily API limits per organisation. Past modest volume we post daily summaries instead, which turns thousands of calls into a handful. Where per-order invoices are genuinely required, writes are batched and paced below the limit with backoff, and you accept latency during spikes.
Payout does not match the bank feed
The bank rec shows a deposit that matches nothing, and the bookkeeper starts allocating by hand.
handling
Payouts arrive net of fees and refunds and can span several days of orders. Gross sales post to a clearing account, fees post per payout to an expense account, and a transfer for the exact net amount is created so the feed line matches to the cent.
Tracked inventory blocks revenue posting
Invoices for certain SKUs start failing while everything else posts fine.
handling
Xero will not let a tracked item’s quantity go negative, so any stock drift between Shopify and Xero blocks the post. We default to untracked items, with Xero owning values rather than quantities and cost of goods handled by journal. Tracked inventory is reserved for small, stable catalogues with a real reason.
Contact list bloat
The Xero contact list fills with thousands of one-time buyers and duplicated regulars.
handling
Xero requires unique contact names, so buyer names collide and get mangled into variants. B2C revenue posts against a single web-sales contact; only genuine B2B accounts with terms and statements get real contact records.
Tax mapping mismatch
The GST, VAT, or sales tax return prepared from Xero disagrees with what Shopify actually charged.
handling
Shopify is authoritative for tax charged at checkout. Each Shopify tax line maps to an explicit Xero tax rate rather than letting Xero recalculate, and rounding is reconciled at line level. US sales tax, GST, and VAT need different maps, so the mapping is built per region with your accountant.
Multi-currency drift
Revenue in Xero disagrees with Shopify reporting by a little more every month.
handling
We decide once whether sales post in presentment or settlement currency, then set the exchange rate on each transaction from actual settlement data where possible instead of mixing Shopify rates with Xero’s daily rates. Multi-currency is only available on Xero plans that include it, which we confirm during the audit.
field mapping
A real slice of the mapping
This is an abridged Order → Xero ACCREC invoice mapping, shown so you can sanity-check it against your own system.
Order → Xero ACCREC invoice
shopify → xero
order.nameInvoice.InvoiceNumberPer-order mode
order.idInvoice.ReferenceSupport lookups
customer.emailContact.EmailAddressB2B only
line_item.skuLineItem.ItemCodeOptional, untracked
line_item.priceLineItem.UnitAmountTax-exclusive
total_taxLineItem.TaxTypeMapped, not recalculated
order.currencyInvoice.CurrencyCodepayout feesJournal line (fee expense)Posted per payout
Per-order mapping shown. Summary mode aggregates the same figures into one invoice or journal per day, per currency and gateway. Chart of accounts and tax rates are mapped with your accountant during the audit.
implementation
Timeline and cost
typical duration
2 to 4 weeks
included in scope
- Discovery with your accountant: chart of accounts and tax mapping
- Posting model decision, summary versus per order, documented in writing
- Clearing accounts, fees, refunds, and gift card liability handling
- Rate-limit-aware sync with queue, retry, and idempotency
- First month-end reconciliation walked through with your bookkeeper
- Runbook and handover for whoever owns the books
what moves it up
- Multiple Shopify stores or currencies posting into one Xero organisation
- Additional payment gateways, each needing its own clearing account
- Historical backfill of orders and payouts
- B2B invoicing with real contacts, payment terms, and statements
- POS or marketplace channels joining the same organisation
questions
Questions buyers actually ask
Should every Shopify order become a Xero invoice?
Only on low-volume stores, or where individual invoices genuinely matter, such as B2B customers who expect an invoice with payment terms. Past a modest daily volume, per-order push runs into Xero’s per-minute and daily API limits, bloats the contact list, and hands your accountant thousands of documents to review instead of one. The daily summary approach posts one invoice or journal per day, per currency and payment gateway, carries the same totals, and reconciles faster. Most stores should summarise; the exceptions know who they are.
Why does our Shopify payout never match the invoices in Xero?
Because the payout is net and the invoices are gross. Shopify Payments deducts its fees and any refunds before the money lands, and one payout can span several days of orders. The fix is a clearing account: sales post gross to it, fees post per payout to an expense account, refunds post as credit notes or negative lines, and a transfer for the exact net amount moves clearing to bank. Set up this way, the bank feed line matches in one click. Without it, someone reconciles by hand forever.
Can Xero tracked inventory be our stock master?
Not at retail volume, and we will not build it that way. Tracked inventory in Xero is designed for small, stable catalogues: it costs on a rolling average, and it will refuse to post an invoice that would take an item’s quantity negative, which means any drift between Shopify and Xero blocks your revenue from posting. Shopify or a dedicated inventory app should own quantities; Xero should own the values, with cost of goods handled by journal. If a vendor proposes running live stock levels through Xero, ask them what happens during a flash sale.
What are Xero’s API rate limits and will we hit them?
Xero enforces both per-minute and daily API limits per connected organisation, and the exact numbers matter less than the shape of the problem: a busy store pushing an invoice, a contact check, and a payment for every order multiplies calls quickly, and a flash sale can put the sync hours behind. Daily summary posting nearly eliminates the risk, because a full day of trading becomes a handful of API calls. If per-order invoicing is a hard requirement, the sync has to pace itself under the limits with a queue and backoff, and you accept some latency during spikes.
How is tax handled between Shopify and Xero?
Shopify is treated as authoritative for the tax actually charged at checkout, and each Shopify tax line maps to an explicit Xero tax rate rather than letting Xero recalculate. What those rates are depends on where you file: US sales tax, Australian and New Zealand GST, and UK or EU VAT are configured differently in Xero, and the filing obligations differ too. We build the tax map with your accountant during the audit and reconcile rounding at line level, so the return prepared from Xero agrees with what the store charged.
Does the integration support multi-currency?
Yes, with two conditions. Your Xero plan has to include multi-currency, which not all plans do, and you have to decide once whether sales post in the customer’s presentment currency or your settlement currency. Mixing the two, or letting Shopify rates and Xero’s daily rates disagree silently, is how revenue drifts a little further from the store’s reporting every month. Where possible we set the exchange rate on each transaction from actual settlement data, so the books reflect what the bank received.
Do we need a custom build or will a connector app do?
Try a connector first. Established apps such as A2X and Link My Books handle payout-based summary accounting from Shopify to Xero well, and for a single store in a single currency they are usually the right answer at a fraction of the cost of a build. Custom work earns its keep when you run multiple stores or currencies into one Xero organisation, need B2B invoices with terms alongside B2C summaries, take payment through gateways a connector does not reconcile, or have an accountant with specific posting requirements. If a connector covers you, we will say so and set it up properly.
shopify + xero
Get a Xero setup your accountant signs off on
Tell us your order volume, currencies, and who does your books. If a connector app covers it, we will say so. If it does not, you get a scope and a fixed price.