Automated Multi-Channel Ecommerce to Xero Reconciliation (n8n)
Streamline global ecommerce sales into Xero with automated tax routing and duplicate prevention using n8n.
Tools: Multi-Channel → Xero
Platform: n8n
Short Answer
A fully automated pipeline that captures orders from your multi-channel tool, handles complex tax logic via n8n expressions, and ensures every sale is recorded as a paid invoice in Xero with 100% accuracy.
The Problem
Manually reconciling high-volume sales from multiple marketplaces (Amazon, eBay, Shopify) into Xero is time-consuming and prone to human error. Businesses struggle to map varying tax rates and prevent duplicate contact/invoice creation, leading to messy financial reporting.
The Outcome
A fully automated pipeline that captures orders from your multi-channel tool, handles complex tax logic via n8n expressions, and ensures every sale is recorded as a paid invoice in Xero with 100% accuracy.
Step-by-Step Guide
1. **Create Webhook Trigger**: Start your n8n workflow with a 'Webhook' node. Set the HTTP Method to POST. This will receive real-time order data from your Multi-Channel tool.
2. **Configure Multi-Channel Credentials**: Add an HTTP Request node to pull full order details if the webhook payload is partial. Authenticate using 'Header Auth' or 'OAuth2' depending on your tool (e.g., Linnworks/ChannelAdvisor).
3. **Sanitize Data with 'Set' Node**: Use a 'Set' node to normalize fields. Use expressions like `{{ $json["total"].toNumber() }}` to ensure price fields are numbers, and trim whitespace from emails.
4. **Check for Existing Contact**: Add a 'Xero' node. Select the 'Contact' resource and 'Get All' operation. Use a filter expression: `email == {{ $json.customer_email }}`.
5. **Logic Branching (If Node)**: Use an 'If' node to check if the Xero search returned a result. If false, route to a 'Xero: Create Contact' node; if true, proceed to mapping.
6. **Map Line Items with Code**: Use a 'Code' node or complex expressions in a 'Set' node to transform your platform's line items into Xero's required format: `[{ "Description": "Item A", "Quantity": 1, "UnitAmount": 10.00, "TaxType": "OUTPUT" }]`.
7. **Dynamic Tax Mapping**: Use a 'Switch' node to look at the `shipping_country` field. Route 'US' to one tax code and 'UK' to another to ensure VAT/Sales Tax compliance.
8. **Create Sales Invoice**: Add a 'Xero' node, resource 'Invoice', operation 'Create'. Link the Contact ID from previous steps and the line items array.
9. **Apply Payment**: To close the invoice, add another 'Xero' node. Resource 'Payment', operation 'Create'. Map the `InvoiceID` from the previous step and specify the 'Bank Account ID' (e.g., your clearing account).
10. **Global Error Handling**: Create a separate workflow with an 'Error Trigger' node. Connect it to a 'Slack' or 'Email' node to notify you if an invoice fail due to a locked accounting period or API timeout.
Data Mapping
| Tool A Field | Xero Field | n8n Expression / Transformation |
| :--- | :--- | :--- |
| `order_number` | `Reference` | `{{ $json["order_id"] }}` |
| `customer_email` | `Contact: EmailAddress` | `{{ $json["email"].toLowerCase().trim() }}` |
| `currency_code` | `CurrencyCode` | `{{ $json["currency"] || 'USD' }}` |
| `line_items` | `LineItems` | Use `item.map()` in a Code node to match Xero JSON |
| `total_tax` | `TotalTax` | `{{ $json["tax_amount"].toNumber() }}` |
| `shipping_cost` | `LineItem (Shipping)`| Add as a separate line item if not in main array |
Gotchas & Failure Modes
• **Rate Limiting**: Xero has a limit of 60 calls per minute. If processing bulk historical data, use the 'Wait' node or 'Split in Batches' node (set to 50 items) to avoid 429 errors.
• **Date Formats**: Xero requires ISO8601 or specific date strings. Use `{{ $now.format('yyyy-MM-dd') }}` in your expressions.
• **Rounding Discrepancies**: Ecommerce platforms often round differently than Xero. Calculate the 'Adjustments' line item if the `Grand Total` doesn't match the sum of line items.
• **Workflow Timeouts**: If your multi-channel tool expects a response within 2 seconds, move heavy Xero processing to a sub-workflow and respond to the webhook immediately.
Verification Checklist
- [ ] Webhook URL is successfully registered in the Multi-Channel platform.
- [ ] Xero Credentials show 'Connection tested successfully'.
- [ ] Test run: An order is placed, and the logic correctly identifies an existing contact via email.
- [ ] Invoice in Xero appears in 'Authorized' or 'Paid' status (not just 'Draft').
- [ ] Currency conversion works if the order is not in your base currency.
- [ ] Error Trigger workflow sends a notification when a 'Bad Request' is forced (e.g., missing SKU).
Ready to Automate?
Build this automation with n8n in minutes.