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-ChannelXero

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.