Short Answer
A robust n8n workflow that automatically creates Bills or Expenses in QuickBooks whenever an item is published in Dext. The workflow ensures zero duplicates, creates missing vendors on the fly, and attaches the original document image for 100% audit compliance.
The Problem
Manual data entry from receipts into QuickBooks is prone to errors, and Dext's native integration often lacks the conditional logic needed for vendor verification or complex approval routings. Businesses struggle with missing audit trails when receipt images aren't correctly linked to transactions.
The Outcome
A robust n8n workflow that automatically creates Bills or Expenses in QuickBooks whenever an item is published in Dext. The workflow ensures zero duplicates, creates missing vendors on the fly, and attaches the original document image for 100% audit compliance.
Step-by-Step Guide
1. **Establish Credentials**: In n8n, go to 'Credentials' and set up 'QuickBooks Online OAuth2'. For Dext, create a 'Header Auth' credential using the Dext API Key.
2. **Configure Dext Trigger**: Add a 'Webhook' node (or a polling 'Dext' node if using a community/custom node) set to listen for the `item.published` event.
3. **Extract Item Details**: Use a 'Code' node or 'Set' node to map the JSON response. Crucial fields include `supplier_name`, `amount`, `date`, and the `image_url`.
4. **Check for Vendor**: Add a 'QuickBooks Online' node. Select the 'Vendor' resource and 'Get All' operation. Use an n8n Expression to filter by name: `{{ $json["supplier_name"] }}`.
5. **Conditional Logic (IF)**: Add an 'IF' node to check if the Vendor list returned a result. If length is 0, route to the 'Create Vendor' node; otherwise, proceed to 'Create Bill'.
6. **Create Missing Vendor**: If the vendor is missing, use the 'QuickBooks Online' node (Action: Create Vendor) using the name extracted from Dext.
7. **Transform Dates/Currency**: Use n8n expressions like `{{ $today.format('yyyy-MM-dd') }}` to ensure the Dext date string matches QuickBooks' ISO-8601 requirement.
8. **Create Transaction**: Use a 'QuickBooks Online' node (Resource: Bill or Purchase). Map the Total Amount, Category (Account ID), and Date. **Crucially: Capture the resulting `Id` from the output.**
9. **Handle Attachments**: Use the 'HTTP Request' node to download the image from Dext's `image_url`. Change the 'Response Format' to 'File'.
10. **Link Attachment**: Add a 'QuickBooks Online' node (Resource: Attachable, Action: Create). Map the `ParentId` to the ID created in Step 8 and pass the binary file data.
11. **Error Handling**: Create an 'Error Trigger' node connected to a Slack node to notify the finance team if a sync fails due to a locked accounting period.
Data Mapping
| Dext Field | QuickBooks Field | n8n Transformation/Expression | Required |
| :--- | :--- | :--- | :--- |
| `supplier_name` | `VendorRef.DisplayName` | `{{ $json.supplier_name.trim() }}` | Yes |
| `total_amount` | `TotalAmt` | `{{ parseFloat($json.total) }}` | Yes |
| `date` | `TxnDate` | `{{ $json.date.split('T')[0] }}` | Yes |
| `currency` | `CurrencyRef.value` | `{{ $json.currency || 'USD' }}` | Yes |
| `category` | `Line.AccountRef.value` | `{{ $node["Map Accounts"].json.id }}` | Yes |
| `id` | `DocNumber` | `{{ "DEXT_" + $json.id }}` | No |
| `image_url` | `Attachable` | `Use Binary Property from HTTP Node` | No |
Gotchas & Failure Modes
* **SyncToken Errors**: If updating existing records, n8n must first fetch the latest `SyncToken` from QuickBooks or the update will be rejected.
* **Rate Limiting**: QuickBooks Online has a limit of 40 concurrent requests. For high-volume Dext accounts, use the 'Wait' node or 'Split In Batches' node in n8n to throttle processing.
* **Binary Data**: Ensure the 'HTTP Request' node used to fetch the receipt image from Dext has 'Always Output Data' enabled to prevent the workflow from halting if an image is missing.
* **Account Mapping**: Dext 'Categories' are strings, while QuickBooks 'Accounts' are IDs. You must maintain a mapping table (e.g., using an n8n Static Data or a Google Sheet) to translate 'Travel' to '56'.
Verification Checklist
- [ ] Trigger a test 'Publish' in Dext and verify n8n captures the webhook payload.
- [ ] Check n8n 'Execution History' to ensure the Vendor lookup logic correctly identifies existing vs new vendors.
- [ ] Confirm the QuickBooks 'Bill' or 'Expense' is created with the correct status (Unpaid/Paid).
- [ ] Open the transaction in QuickBooks and verify the PDF/Image is visible in the 'Attachments' section.
- [ ] Test a 'Duplicate' scenario (sending the same Dext ID twice) to ensure n8n logic prevents double-posting.
Ready to Automate?
Build this automation with n8n in minutes.