A2X Payout Reconciliation and Xero Journal Sync (n8n)

Automate summarized e-commerce financial reporting with granular audit trails and error handling in n8n.

Tools: A2XXero

Platform: n8n

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.