Squarespace E-Commerce to Xero Accounting Sync (n8n)

Automate sales reconciliation and tax compliance using n8n's workflow engine and secure credential management.

Tools: SquarespaceXero

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.