Short Answer
A fully automated workflow that triggers on A2X settlements, transforms data into Xero-ready journal entries, uploads a PDF audit trail to Xero's inbox, and sends Slack alerts for any reconciliation discrepancies.
The Problem
Manual entry of e-commerce payouts into Xero is error-prone and time-consuming, especially when dealing with gross sales, fees, and taxes. While a native sync exists, it lacks the flexibility to create external backups, custom discrepancy alerts, or multi-step validation required for complex bookkeeping.
The Outcome
A fully automated workflow that triggers on A2X settlements, transforms data into Xero-ready journal entries, uploads a PDF audit trail to Xero's inbox, and sends Slack alerts for any reconciliation discrepancies.
Step-by-Step Guide
1. **Setup A2X Webhook**: In n8n, add a 'Webhook' node. Set HTTP Method to POST. Copy the URL and paste it into A2X Settings > Notifications > Webhooks for 'Settlement Posted'.
2. **Configure Credentials**: Navigate to the 'Credentials' tab in n8n. Create 'Xero OAuth2 API' credentials. Follow the n8n documentation to map the Redirect URL from n8n to your Xero Developer Portal app.
3. **Extract Data (Code Node)**: A2X sends a complex JSON payload. Use a 'Code' node with JavaScript to structure the `line_items`. Map A2X account codes to your Xero Chart of Accounts using a `Map` object for speed.
4. **Handle Multi-Currency**: If the payout currency differs from Xero's base currency, add an 'HTTP Request' node to fetch current rates (e.g., via Fixer.io) and multiply values using an n8n Expression like `{{ $json.amount * $vars.rate }}`.
5. **Create Xero Journal**: Add a 'Xero' node. Select the 'Manual Journal' resource and 'Create' operation. Map the Date, Narration (A2X Payout ID), and the array of Journal Lines generated in Step 3.
6. **Implement Duplicate Prevention**: Use a 'Filter' node before the Xero node. Use an expression to check a local database or Google Sheet for existing `payout_id` to prevent double-posting if a webhook retries.
7. **Binary Data Fetch**: Use an 'HTTP Request' node to download the PDF summary from the A2X `summary_url`. Set the 'Response Format' to 'File'.
8. **Upload to Xero Inbox**: Add another 'Xero' node. Choose 'File' resource and 'Upload' operation. This attaches the source document to Xero for audit purposes.
9. **Error Handling**: Create an 'Error Trigger' node. Connect it to a 'Slack' or 'Email' node to notify the accounting team if a journal fails to post due to a locked period or missing account code.
Data Mapping
| A2X Field | Xero Table/Field | Transformation Function | Required |
| :--- | :--- | :--- | :--- |
| `settlement_id` | Manual Journal: Narration | `A2X Payout: {{ $json.id }}` | Yes |
| `posted_date` | Manual Journal: Date | `{{ $json.date.substring(0,10) }}` | Yes |
| `gross_sales` | Line Item: Credit | `Math.abs(value)` | Yes |
| `platform_fees` | Line Item: Debit | `Math.abs(value)` | Yes |
| `tax_amount` | Line Item: Credit/Debit | Conditional mapping based on sign | No |
| `tracking_id` | Tracking Category | `{{ $json.store_name }}` | No |
| `summary_pdf` | Attachment | Binary Data Buffer | No |
Gotchas & Failure Modes
* **Xero Rate Limits**: Xero allows 60 calls per minute. If processing a high volume of historical settlements, use the n8n 'Wait' node or 'Split in Batches' node (set to 5 items) to stay below limits.
* **Date Formats**: Xero requires ISO 8601 (YYYY-MM-DD). Use n8n expressions like `{{ $now.format('yyyy-MM-dd') }}` if the A2X timestamp is in milliseconds.
* **OAuth 2.0 Refresh**: n8n handles token refresh automatically, but ensure your Xero App in the Xero Developer Portal is set to 'Web App' and not 'Desktop/Mobile' to avoid session timeouts.
* **Locked Periods**: Ensure the settlement date in A2X isn't in a 'Locked' period in Xero; n8n will return a 403 error. Use an IF node to check the date before posting.
Verification Checklist
- [ ] Trigger a 'Test' webhook from A2X and verify n8n receives the JSON payload in the execution log.
- [ ] Check the 'Code' node output to ensure Credits and Debits balance to zero (Xero requirement).
- [ ] Run the workflow in 'Manual' mode to see the Journal appear in Xero as a 'Draft'.
- [ ] Verify the PDF attachment appears in the Xero 'Files' inbox.
- [ ] Force an error (e.g., change an account code) and confirm the Error Trigger sends a Slack notification.
Ready to Automate?
Build this automation with n8n in minutes.