Automated Shopify Order to Xero Invoice Sync (n8n)

Eliminate manual bookkeeping by automatically syncing Shopify orders and line items to Xero via n8n's robust workflow engine.

Tools: ShopifyXero

Platform: n8n

Short Answer

A self-hosted or cloud-based n8n workflow that triggers on every New Order, validates customer data, handles multi-line items via expressions, and generates a formatted invoice and payment record in Xero instantly.

The Problem

Manual entry of e-commerce sales into accounting software is time-consuming and prone to human error. Discrepancies between Shopify revenue and Xero ledger often lead to reconciliation nightmares during tax season and inaccurate financial reporting.

The Outcome

A self-hosted or cloud-based n8n workflow that triggers on every New Order, validates customer data, handles multi-line items via expressions, and generates a formatted invoice and payment record in Xero instantly.

Step-by-Step Guide

1. **Create Workflow**: In n8n, create a new workflow and add the 'Shopify Trigger' node. Set the event to 'Order Created'. 2. **Configure Credentials**: Select 'Shopify API' credentials. You will need your Shopify Store Name and an Admin API access token (configured in Shopify Apps > Develop Apps). 3. **Identify/Create Contact**: Add a 'Xero' node. Choose the 'Contact' resource and 'Get or Create' operation. Use an expression to map `{{ $json.customer.email }}` from Shopify to the 'Email Address' field in Xero to prevent duplicates. 4. **Handle Line Items**: Use a 'Code' node or 'Set' node with the 'Line Items' array from Shopify. n8n treats arrays as separate items; use an expression like `{{ $json.line_items.map(item => ({ Description: item.name, UnitAmount: item.price, Quantity: item.quantity })) }}` to format them for Xero's API. 5. **Format Dates & Currency**: Use the n8n expression `$now` or Shopify's `created_at` field. Ensure the date format is `YYYY-MM-DD` using the `.format('YYYY-MM-DD')` JavaScript method within the expression. 6. **Create Invoice**: Add another 'Xero' node. Set Resource to 'Invoice' and Operation to 'Create'. Map the Contact ID from Step 3 and the line items from Step 4. Set 'Status' to 'AUTHORISED' for immediate ledger impact. 7. **Log Payment**: Add a final 'Xero' node. Resource: 'Payment', Operation: 'Create'. Link this to the Invoice ID generated in Step 6 to mark the invoice as paid. 8. **Implement Error Handling**: Create an 'Error Trigger' node. Connect it to a 'Gmail' or 'Slack' node to notify you if an API limit is hit or if a tax rate is missing. 9. **Test Workflow**: Click 'Execute Workflow' and place a test order in Shopify (in Bogus Gateway mode) to verify data flow in n8n's execution log.

Data Mapping

| Shopify Field | Xero Field | Transformation / Expression | Required | | :--- | :--- | :--- | :--- | | `customer.email` | Contact Email | `{{ $json.customer.email }}` | Yes | | `order_number` | Reference | `Shopify-{{ $json.order_number }}` | No | | `line_items` | LineItems | `{{ $json.line_items }}` (Mapped via JSON Object) | Yes | | `total_tax` | TotalTax | `{{ parseFloat($json.total_tax) }}` | Yes | | `currency` | CurrencyCode | `{{ $json.currency }}` | Yes | | `created_at` | Date | `{{ $json.created_at.split('T')[0] }}` | Yes |

Gotchas & Failure Modes

* **Line Item Mapping**: n8n's Xero node expects an array of objects. Mapping individual fields one-by-one in the UI often fails; use a 'Set' node with 'Keep Only Set' active to clean the data first. * **Rate Limiting**: Xero has a limit of 60 calls per minute. If you have a high volume of orders, use an n8n 'Wait' node or the 'Split In Batches' node to throttle traffic. * **Tax Rates**: Xero requires specific Tax Types (e.g., 'OUTPUT', 'NONE'). If Shopify tax names don't match Xero's internal codes, use an 'IF' node or 'Switch' node in n8n to map them. * **Rounding Errors**: Ensure you use `parseFloat()` in n8n expressions to avoid string concatenation issues with price values.

Verification Checklist

- [ ] Shopify Webhook status shows 'Active' in n8n Trigger Node. - [ ] Xero Contact is found by email (no duplicate contacts created). - [ ] Line items display correct quantities and unit prices in Xero Invoice draft. - [ ] Invoice status is 'AUTHORISED' (or 'DRAFT' if you prefer manual approval). - [ ] Payment record is successfully attached to the Invoice ID. - [ ] Execution log in n8n shows 200 OK for all node steps.

Ready to Automate?

Build this automation with n8n in minutes.