Squarespace E-Commerce to Xero Accounting Sync (n8n)
Automate sales reconciliation and tax compliance using n8n's workflow engine and secure credential management.
Tools: Squarespace → Xero
Platform: n8n
Short Answer
A self-hosted or cloud-based n8n workflow that automatically creates Xero contacts, generates authorized invoices, and records payments the moment a Squarespace order is placed, ensuring real-time financial visibility.
The Problem
Manual entry of Squarespace orders into Xero is time-consuming and prone to human error, leading to inaccurate tax reporting and delayed reconciliation. High-growth businesses struggle to scale when financial data is siloed in a CMS rather than a regulated ledger.
The Outcome
A self-hosted or cloud-based n8n workflow that automatically creates Xero contacts, generates authorized invoices, and records payments the moment a Squarespace order is placed, ensuring real-time financial visibility.
Step-by-Step Guide
1. **Configure Credentials:** In n8n, go to 'Credentials' and set up 'Xero OAuth2 API'. Note: You must create an app in the Xero Developer Portal to get your Client ID and Secret. Set the Redirect URI to your n8n instance.
2. **Setup Squarespace Webhook:** Add a 'Webhook Node' in n8n. Set the method to POST. Copy the Production URL. In Squarespace: Settings > Advanced > Developer Tools > Webhooks, and paste the URL, selecting 'Order Created' as the event.
3. **Handle Squarespace Signatures (Security):** (Optional but recommended) In the Webhook node, enable 'Only allow from specific IPs' or use a 'Crypto Node' to verify the `x-squarespace-signature` header against your secret key.
4. **Data Normalization:** Use an 'Edit Image' or 'Set' node to map Squarespace nested JSON data into flat variables. Use expressions like `{{ $json.customerEmail }}` and handle date formatting using `$now.format('yyyy-MM-dd')` for Xero compatibility.
5. **Contact Lookup Logic:** Add a 'Xero Node' with the resource 'Contact' and operation 'Get All'. Use a filter for `EmailAddress == "{{ $node["Webhook"].json["customerEmail"] }}"`.
6. **Branching with IF Node:** Use an 'IF Node' to check if the Contact search returned a result. Match by `ID` to determine if you should Route to a 'Create' or 'Update' Xero node.
7. **Item/SKU Mapping:** If your Squarespace order has multiple line items, use the 'Split In Batches' node (or n8n's native looping) to ensure every product SKU is validated against your Xero inventory items.
8. **Invoice Creation:** Use the 'Xero Node' (Action: Create Invoice). Map the Contact ID from previous steps and the line items. Ensure the `Status` is set to `AUTHORISED` to allow payment recording in the next step.
9. **Record Payment:** Add another 'Xero Node' (Action: Create Payment). Link it to the Invoice ID created in step 8 and specify the 'Bank Account ID' in Xero where the funds should be reconciled.
10. **Global Error Handling:** Create a separate 'Error Trigger' workflow. This ensures that if the Xero API is down or a tax code mismatch occurs, you receive an automated alert instead of silent data loss.
Data Mapping
| Squarespace Field | Xero Destination | n8n Expression / Transformation |
| :--- | :--- | :--- |
| `customerEmail` | `Contact.Email` | `{{ $json.customerEmail }}` (Required) |
| `billingAddress.firstName` | `Contact.Name` | `{{ $json.billingAddress.firstName + ' ' + $json.billingAddress.lastName }}` |
| `orderNumber` | `Invoice.Reference` | `{{ 'SQ-' + $json.orderNumber }}` (Used for ID lookup) |
| `lineItems` | `Invoice.LineItems` | Use n8n `Item Lists` node to map sub-arrays |
| `grandTotal` | `Payment.Amount` | `{{ $json.grandTotal.value }}` (Float) |
| `orderDate` | `Invoice.Date` | `{{ $json.createdOn.toISODate() }}` |
| N/A | `Invoice.Status` | Fixed Value: `AUTHORISED` |
Gotchas & Failure Modes
* **Xero Rate Limits:** Xero has a limit of 60 requests per minute. If processing bulk historic orders, use n8n's 'Wait' node or 'Split In Batches' to throttle requests.
* **Tax Discrepancies:** Ensure n8n passes the 'TaxType' code (e.g., OUTPUT2) rather than the tax name. Mapping based on name often fails due to slight character differences.
* **Workflow Execution Mode:** n8n Webhook nodes do not trigger in 'Manual' mode unless you click 'Execute Workflow' first. Always use 'Production URL' for live Squarespace data.
* **Currency Codes:** Squarespace provides currency in 3-letter codes (USD, GBP). Ensure your Xero Organization supports these currencies or n8n will return a 400 Bad Request.
Verification Checklist
- [ ] **Webhook Handshake:** Send a test payload from Squarespace and verify the Webhook node in n8n receives a 200 OK status.
- [ ] **Credential Refresh:** Verify the Xero OAuth2 token refreshes automatically (check n8n execution log after 35 minutes).
- [ ] **Duplicate Check:** Run the same order twice; verify the 'IF Node' prevents creating a second duplicate Contact in Xero.
- [ ] **Line Item Precision:** Check a multi-item order in Xero to ensure total tax and shipping line items match Squarespace exactly.
- [ ] **Error Notification:** Manually break the Xero node (e.g., change the Bank ID to a fake one) and verify your Error Trigger workflow fires.
Ready to Automate?
Build this automation with n8n in minutes.