This workflow corresponds to n8n.io template #11899 — we link there as the canonical source.
This workflow follows the Agent → Gmail recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "ObVFfph3OecSfR2D",
"name": "Automate revenue collection and tax submission across multiple sources",
"tags": [],
"nodes": [
{
"id": "827cbd50-730e-4ddf-93dc-fa68d0724ff9",
"name": "Workflow Configuration",
"type": "n8n-nodes-base.set",
"position": [
-224,
288
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "taxPeriodStart",
"type": "string",
"value": "={{ $now.minus({ months: 1 }).startOf('month').toISO() }}"
},
{
"id": "id-2",
"name": "taxPeriodEnd",
"type": "string",
"value": "={{ $now.minus({ months: 1 }).endOf('month').toISO() }}"
},
{
"id": "id-3",
"name": "submissionMethod",
"type": "string",
"value": "api"
},
{
"id": "id-4",
"name": "taxAgentEmail",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Tax Agent Email Address__>"
},
{
"id": "id-5",
"name": "governmentApiUrl",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Government Tax API Endpoint__>"
},
{
"id": "id-6",
"name": "bankFeedApiUrl",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Bank Feed API Endpoint__>"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "74d8059b-52fe-4b35-bc6a-c89a90803868",
"name": "Get Stripe Transactions",
"type": "n8n-nodes-base.stripe",
"position": [
0,
80
],
"parameters": {
"limit": 100,
"resource": "charge",
"operation": "getAll"
},
"typeVersion": 1
},
{
"id": "48dce256-d478-4814-a1c3-48b0087f57e9",
"name": "Get PayPal Transactions",
"type": "n8n-nodes-base.payPal",
"position": [
0,
272
],
"parameters": {
"resource": "payoutItem",
"payoutItemId": "<__PLACEHOLDER_VALUE__Payout Item ID__>"
},
"typeVersion": 1
},
{
"id": "475587a0-60f5-45c5-b7dc-e8c5c28d613d",
"name": "Get Shopify Orders",
"type": "n8n-nodes-base.shopify",
"position": [
0,
464
],
"parameters": {
"options": {
"createdAtMax": "={{ $('Workflow Configuration').first().json.taxPeriodEnd }}",
"createdAtMin": "={{ $('Workflow Configuration').first().json.taxPeriodStart }}"
},
"operation": "getAll",
"returnAll": true
},
"typeVersion": 1
},
{
"id": "ba27bdb1-ee18-4fd0-878b-8d19a0fc9db6",
"name": "Get Bank Feed Data",
"type": "n8n-nodes-base.httpRequest",
"position": [
0,
656
],
"parameters": {
"url": "={{ $('Workflow Configuration').first().json.bankFeedApiUrl }}",
"options": {},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "start_date",
"value": "={{ $('Workflow Configuration').first().json.taxPeriodStart }}"
},
{
"name": "end_date",
"value": "={{ $('Workflow Configuration').first().json.taxPeriodEnd }}"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "627e15cc-7a89-4d09-9f13-bfc21360c1ca",
"name": "Normalize Stripe Data",
"type": "n8n-nodes-base.set",
"position": [
208,
112
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "source",
"type": "string",
"value": "Stripe"
},
{
"id": "id-2",
"name": "transactionId",
"type": "string",
"value": "={{ $json.id }}"
},
{
"id": "id-3",
"name": "amount",
"type": "number",
"value": "={{ $json.amount / 100 }}"
},
{
"id": "id-4",
"name": "currency",
"type": "string",
"value": "={{ $json.currency }}"
},
{
"id": "id-5",
"name": "date",
"type": "string",
"value": "={{ new Date($json.created * 1000).toISOString() }}"
},
{
"id": "id-6",
"name": "description",
"type": "string",
"value": "={{ $json.description }}"
},
{
"id": "id-7",
"name": "customerEmail",
"type": "string",
"value": "={{ $json.billing_details?.email }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "69974097-d415-4b94-93bb-2ffa7796026e",
"name": "Normalize PayPal Data",
"type": "n8n-nodes-base.set",
"position": [
224,
272
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "source",
"type": "string",
"value": "PayPal"
},
{
"id": "id-2",
"name": "transactionId",
"type": "string",
"value": "={{ $json.payout_item_id }}"
},
{
"id": "id-3",
"name": "amount",
"type": "number",
"value": "={{ $json.payout_item.amount.value }}"
},
{
"id": "id-4",
"name": "currency",
"type": "string",
"value": "={{ $json.payout_item.amount.currency }}"
},
{
"id": "id-5",
"name": "date",
"type": "string",
"value": "={{ $json.time_processed }}"
},
{
"id": "id-6",
"name": "description",
"type": "string",
"value": "={{ $json.payout_item.transaction_note }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "7a796a3c-a049-48e7-b7b9-ce5cab1a9dd3",
"name": "Normalize Shopify Data",
"type": "n8n-nodes-base.set",
"position": [
224,
464
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "source",
"type": "string",
"value": "Shopify"
},
{
"id": "id-2",
"name": "transactionId",
"type": "string",
"value": "={{ $json.id }}"
},
{
"id": "id-3",
"name": "amount",
"type": "number",
"value": "={{ $json.total_price }}"
},
{
"id": "id-4",
"name": "currency",
"type": "string",
"value": "={{ $json.currency }}"
},
{
"id": "id-5",
"name": "date",
"type": "string",
"value": "={{ $json.created_at }}"
},
{
"id": "id-6",
"name": "description",
"type": "string",
"value": "={{ $json.name }}"
},
{
"id": "id-7",
"name": "customerEmail",
"type": "string",
"value": "={{ $json.email }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "9e2c41c2-5690-4081-8594-8832a3f4eef1",
"name": "Normalize Bank Data",
"type": "n8n-nodes-base.set",
"position": [
224,
656
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "source",
"type": "string",
"value": "Bank"
},
{
"id": "id-2",
"name": "transactionId",
"type": "string",
"value": "={{ $json.transaction_id }}"
},
{
"id": "id-3",
"name": "amount",
"type": "number",
"value": "={{ $json.amount }}"
},
{
"id": "id-4",
"name": "currency",
"type": "string",
"value": "={{ $json.currency }}"
},
{
"id": "id-5",
"name": "date",
"type": "string",
"value": "={{ $json.date }}"
},
{
"id": "id-6",
"name": "description",
"type": "string",
"value": "={{ $json.description }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "2a4f11e4-4d51-4c71-baf6-ff241c193e3d",
"name": "Merge All Revenue Sources",
"type": "n8n-nodes-base.aggregate",
"position": [
448,
288
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData",
"destinationFieldName": "allTransactions"
},
"typeVersion": 1
},
{
"id": "833c661f-0aff-4be4-834a-108c40f92725",
"name": "AI Income Categorizer",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
672,
288
],
"parameters": {
"text": "={{ 'Categorize these revenue transactions: ' + JSON.stringify($json.allTransactions) }}",
"options": {
"systemMessage": "You are a tax categorization assistant. Your task is to analyze revenue transactions and categorize each one according to standard income categories.\n\nFor each transaction, determine:\n1. incomeCategory: The type of income (e.g., \"Product Sales\", \"Service Revenue\", \"Subscription Revenue\", \"Interest Income\", \"Other Income\")\n2. taxable: Whether the income is taxable (true/false)\n3. taxRate: The applicable tax rate as a decimal (e.g., 0.10 for 10%)\n4. notes: Any relevant notes about the categorization\n\nReturn the categorized transactions in the exact structure defined by the output parser."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 3
},
{
"id": "9497a3e4-6beb-4aff-9032-a765685fc98a",
"name": "OpenAI Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
688,
512
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "07444727-4739-44ed-8312-b47e24da62d9",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
816,
512
],
"parameters": {
"schemaType": "manual",
"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"transactions\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"transactionId\": {\n \"type\": \"string\"\n },\n \"source\": {\n \"type\": \"string\"\n },\n \"amount\": {\n \"type\": \"number\"\n },\n \"currency\": {\n \"type\": \"string\"\n },\n \"date\": {\n \"type\": \"string\"\n },\n \"description\": {\n \"type\": \"string\"\n },\n \"incomeCategory\": {\n \"type\": \"string\"\n },\n \"taxable\": {\n \"type\": \"boolean\"\n },\n \"taxRate\": {\n \"type\": \"number\"\n },\n \"notes\": {\n \"type\": \"string\"\n }\n }\n }\n }\n }\n}"
},
"typeVersion": 1.3
},
{
"id": "d531269c-0591-4ba6-af34-e68613c12329",
"name": "Calculate Period Totals",
"type": "n8n-nodes-base.code",
"position": [
1024,
288
],
"parameters": {
"jsCode": "// Calculate Period Totals for Tax Filing\n// This code processes categorized income data and calculates totals by category\n\nconst items = $input.all();\n\n// Initialize totals object\nconst totals = {\n byCategory: {},\n totalRevenue: 0,\n totalTaxableAmount: 0,\n totalTax: 0,\n transactionCount: 0,\n periodStart: null,\n periodEnd: null\n};\n\n// Process each transaction\nfor (const item of items) {\n const data = item.json;\n \n // Extract relevant fields\n const category = data.category || 'Uncategorized';\n const amount = parseFloat(data.amount) || 0;\n const taxableAmount = parseFloat(data.taxableAmount) || amount;\n const taxRate = parseFloat(data.taxRate) || 0;\n const tax = taxableAmount * (taxRate / 100);\n const date = data.date || data.transactionDate;\n \n // Update category totals\n if (!totals.byCategory[category]) {\n totals.byCategory[category] = {\n revenue: 0,\n taxableAmount: 0,\n tax: 0,\n count: 0\n };\n }\n \n totals.byCategory[category].revenue += amount;\n totals.byCategory[category].taxableAmount += taxableAmount;\n totals.byCategory[category].tax += tax;\n totals.byCategory[category].count += 1;\n \n // Update overall totals\n totals.totalRevenue += amount;\n totals.totalTaxableAmount += taxableAmount;\n totals.totalTax += tax;\n totals.transactionCount += 1;\n \n // Track period dates\n if (date) {\n const transactionDate = new Date(date);\n if (!totals.periodStart || transactionDate < totals.periodStart) {\n totals.periodStart = transactionDate;\n }\n if (!totals.periodEnd || transactionDate > totals.periodEnd) {\n totals.periodEnd = transactionDate;\n }\n }\n}\n\n// Format dates\nif (totals.periodStart) {\n totals.periodStart = totals.periodStart.toISOString().split('T')[0];\n}\nif (totals.periodEnd) {\n totals.periodEnd = totals.periodEnd.toISOString().split('T')[0];\n}\n\n// Round all monetary values to 2 decimal places\ntotals.totalRevenue = Math.round(totals.totalRevenue * 100) / 100;\ntotals.totalTaxableAmount = Math.round(totals.totalTaxableAmount * 100) / 100;\ntotals.totalTax = Math.round(totals.totalTax * 100) / 100;\n\nfor (const category in totals.byCategory) {\n totals.byCategory[category].revenue = Math.round(totals.byCategory[category].revenue * 100) / 100;\n totals.byCategory[category].taxableAmount = Math.round(totals.byCategory[category].taxableAmount * 100) / 100;\n totals.byCategory[category].tax = Math.round(totals.byCategory[category].tax * 100) / 100;\n}\n\n// Create summary output\nconst summary = {\n summary: totals,\n categories: Object.keys(totals.byCategory).map(category => ({\n category: category,\n ...totals.byCategory[category]\n })),\n transactions: items.map(item => item.json)\n};\n\nreturn [summary];"
},
"typeVersion": 2
},
{
"id": "d739f8aa-6436-4d5d-9b54-b33c39eb5b4e",
"name": "Format as CSV",
"type": "n8n-nodes-base.code",
"position": [
1248,
192
],
"parameters": {
"jsCode": "// Convert categorized transaction data and totals into CSV format\nconst items = $input.all();\n\n// Define CSV headers\nconst headers = [\n 'Transaction ID',\n 'Source',\n 'Date',\n 'Amount',\n 'Currency',\n 'Category',\n 'Taxable',\n 'Tax Rate',\n 'Tax Amount',\n 'Description'\n];\n\n// Create CSV rows\nconst rows = items.map(item => {\n const data = item.json;\n return [\n data.transactionId || data.transaction_id || '',\n data.source || '',\n data.date || '',\n data.amount || '',\n data.currency || '',\n data.category || '',\n data.taxable || '',\n data.taxRate || data.tax_rate || '',\n data.taxAmount || data.tax_amount || '',\n data.description || ''\n ];\n});\n\n// Escape CSV fields (handle commas, quotes, newlines)\nconst escapeCSVField = (field) => {\n const fieldStr = String(field);\n if (fieldStr.includes(',') || fieldStr.includes('\"') || fieldStr.includes('\\n')) {\n return '\"' + fieldStr.replace(/\"/g, '\"\"') + '\"';\n }\n return fieldStr;\n};\n\n// Build CSV content\nconst csvRows = [\n headers.map(escapeCSVField).join(','),\n ...rows.map(row => row.map(escapeCSVField).join(','))\n];\n\nconst csvContent = csvRows.join('\\n');\n\n// Return CSV as output\nreturn [\n {\n json: {\n csv: csvContent,\n format: 'csv',\n rowCount: rows.length,\n generatedAt: new Date().toISOString()\n },\n binary: {\n data: {\n data: Buffer.from(csvContent).toString('base64'),\n mimeType: 'text/csv',\n fileName: `revenue_report_${new Date().toISOString().split('T')[0]}.csv`\n }\n }\n }\n];"
},
"typeVersion": 2
},
{
"id": "d22f7d8e-0094-4dfb-b29e-c2d28da87040",
"name": "Format as XML",
"type": "n8n-nodes-base.code",
"position": [
1696,
480
],
"parameters": {
"jsCode": "// Convert categorized transaction data and totals into XML format for government tax filing\nconst items = $input.all();\n\n// Helper function to escape XML special characters\nfunction escapeXml(unsafe) {\n if (unsafe === null || unsafe === undefined) return '';\n return String(unsafe)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n// Helper function to format date to ISO format\nfunction formatDate(date) {\n if (!date) return new Date().toISOString().split('T')[0];\n return new Date(date).toISOString().split('T')[0];\n}\n\n// Build XML structure\nlet xml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n';\nxml += '<TaxFilingReport>\\n';\nxml += ' <Header>\\n';\nxml += ` <SubmissionDate>${formatDate(new Date())}</SubmissionDate>\\n`;\nxml += ` <TaxPeriod>${items[0]?.json?.taxPeriod || 'QUARTERLY'}</TaxPeriod>\\n`;\nxml += ` <FiscalYear>${new Date().getFullYear()}</FiscalYear>\\n`;\nxml += ` <TaxpayerID>${items[0]?.json?.taxpayerId || 'TBD'}</TaxpayerID>\\n`;\nxml += ' </Header>\\n';\n\n// Add summary totals\nxml += ' <Summary>\\n';\nconst totals = items[0]?.json?.totals || {};\nxml += ` <TotalRevenue>${totals.totalRevenue || 0}</TotalRevenue>\\n`;\nxml += ` <TotalTaxableIncome>${totals.totalTaxableIncome || 0}</TotalTaxableIncome>\\n`;\nxml += ` <TotalDeductions>${totals.totalDeductions || 0}</TotalDeductions>\\n`;\nxml += ` <NetTaxableAmount>${totals.netTaxableAmount || 0}</NetTaxableAmount>\\n`;\nxml += ` <TransactionCount>${items.length}</TransactionCount>\\n`;\nxml += ' </Summary>\\n';\n\n// Add category breakdown\nxml += ' <CategoryBreakdown>\\n';\nconst categories = items[0]?.json?.categoryTotals || {};\nfor (const [category, amount] of Object.entries(categories)) {\n xml += ' <Category>\\n';\n xml += ` <Name>${escapeXml(category)}</Name>\\n`;\n xml += ` <Amount>${amount}</Amount>\\n`;\n xml += ' </Category>\\n';\n}\nxml += ' </CategoryBreakdown>\\n';\n\n// Add individual transactions\nxml += ' <Transactions>\\n';\nfor (const item of items) {\n const data = item.json;\n xml += ' <Transaction>\\n';\n xml += ` <TransactionID>${escapeXml(data.transactionId || data.id)}</TransactionID>\\n`;\n xml += ` <Date>${formatDate(data.date || data.transactionDate)}</Date>\\n`;\n xml += ` <Source>${escapeXml(data.source || 'UNKNOWN')}</Source>\\n`;\n xml += ` <Amount>${data.amount || 0}</Amount>\\n`;\n xml += ` <Currency>${escapeXml(data.currency || 'USD')}</Currency>\\n`;\n xml += ` <Category>${escapeXml(data.category || 'UNCATEGORIZED')}</Category>\\n`;\n xml += ` <Description>${escapeXml(data.description || '')}</Description>\\n`;\n xml += ` <TaxStatus>${escapeXml(data.taxStatus || 'TAXABLE')}</TaxStatus>\\n`;\n if (data.customerName) {\n xml += ` <CustomerName>${escapeXml(data.customerName)}</CustomerName>\\n`;\n }\n xml += ' </Transaction>\\n';\n}\nxml += ' </Transactions>\\n';\n\nxml += '</TaxFilingReport>';\n\n// Return the XML as output\nreturn [{\n json: {\n xml: xml,\n format: 'XML',\n generatedAt: new Date().toISOString(),\n recordCount: items.length\n }\n}];"
},
"typeVersion": 2
},
{
"id": "62bba3e6-8d63-4684-a961-d6b783aea349",
"name": "Check Submission Method",
"type": "n8n-nodes-base.if",
"position": [
1472,
192
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "id-1",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $('Workflow Configuration').first().json.submissionMethod }}",
"rightValue": "api"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "35e46f44-2e36-4fb6-927d-c4981615836b",
"name": "Submit to Government API",
"type": "n8n-nodes-base.httpRequest",
"position": [
1696,
96
],
"parameters": {
"url": "={{ $('Workflow Configuration').first().json.governmentApiUrl }}",
"body": "={{ $json.csvData }}",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "raw",
"sendHeaders": true,
"rawContentType": "text/csv",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "text/csv"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "46772d2d-fb8f-47bb-8943-ef32f2bed8ab",
"name": "Email to Tax Agent",
"type": "n8n-nodes-base.gmail",
"position": [
1696,
288
],
"parameters": {
"sendTo": "={{ $('Workflow Configuration').first().json.taxAgentEmail }}",
"message": "={{ 'Dear Tax Agent,<br><br>Please find attached the tax filing submission for the period ' + $('Workflow Configuration').first().json.taxPeriodStart + ' to ' + $('Workflow Configuration').first().json.taxPeriodEnd + '.<br><br>Revenue Summary:<br>' + JSON.stringify($('Calculate Period Totals').first().json, null, 2).replace(/\\n/g, '<br>') + '<br><br>The detailed CSV file is attached.<br><br>Best regards,<br>Automated Tax Filing System' }}",
"options": {
"attachmentsUi": {
"attachmentsBinary": [
{
"property": "csvData"
}
]
}
},
"subject": "={{ 'Tax Filing Submission - Period: ' + $('Workflow Configuration').first().json.taxPeriodStart + ' to ' + $('Workflow Configuration').first().json.taxPeriodEnd }}"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "82060b39-886f-4e46-96ad-5f837116f1eb",
"name": "Archive to Google Drive",
"type": "n8n-nodes-base.googleDrive",
"position": [
1920,
288
],
"parameters": {
"name": "={{ 'tax_filing_' + new Date().toISOString().split('T')[0] + '.csv' }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {
"simplifyOutput": true
},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultName": "/ (Root folder)"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "43b5a026-1918-4f2b-a76c-3271ba1fd3d4",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
1136,
-288
],
"parameters": {
"color": 5,
"width": 400,
"height": 208,
"content": "## Customization\nModify normalization rules per jurisdiction; add expense categories to AI prompt; \n\n## Benefits\nEliminates manual reconciliation; reduces tax filing time by 80%; improves accuracy; "
},
"typeVersion": 1
},
{
"id": "25215ef2-8cb0-41e3-8f17-706714474149",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
672,
-288
],
"parameters": {
"color": 4,
"width": 416,
"height": 208,
"content": "## Prerequisites\nStripe, PayPal, Shopify, or bank APIs; OpenAI account; Google Workspace; \n\n## Use Cases\nQuarterly tax preparation for e-commerce; multi-channel revenue reconciliation; "
},
"typeVersion": 1
},
{
"id": "219f5590-aeb3-44ac-b607-0ff38da38c07",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
272,
-288
],
"parameters": {
"width": 320,
"height": 208,
"content": "## Setup Steps\n1. Connect Stripe/PayPal/Shopify accounts with API keys to respective nodes.\n2. Configure bank feed authentication \n3. Set OpenAI credentials for AI Income Categorizer node.\n4. Link Google Drive and Gmail .\n"
},
"typeVersion": 1
},
{
"id": "fc759cae-6766-43e5-b517-e03f9bffb698",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-512,
-288
],
"parameters": {
"width": 752,
"height": 192,
"content": "## How It Works\nConsolidates daily revenue from Stripe, PayPal, Shopify, and bank feeds into a single system. The workflow automatically normalizes data across payment sources, uses AI to categorize income transactions, calculates reporting-period totals, and generates tax-compliant CSV and XML submissions. Designed for e-commerce businesses, SaaS companies, and multi-channel retailers managing complex revenue streams, it eliminates manual reconciliation, reduces filing errors, and speeds up financial reporting by automating the entire pipeline from data collection to government submission."
},
"typeVersion": 1
},
{
"id": "89107252-fe33-4736-aa8f-f364ec4a1f86",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
656,
-32
],
"parameters": {
"color": 7,
"width": 304,
"height": 880,
"content": "## AI-Powered Income Categorization\n**What:** Use all normalized streams and categorizes income using AI-powered transaction analysis.\n**Why:** Automates income classification and detects anomalies "
},
"typeVersion": 1
},
{
"id": "bc7e0768-29f3-4c48-930d-f68f583ba464",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
976,
-32
],
"parameters": {
"color": 7,
"width": 1104,
"height": 864,
"content": "## Tax Period Calculation and submission\n**What:** Computes period totals and tax period summaries with validation checks.\n**Why:** Ensures accuracy and compliance-ready figures for regulatory submission."
},
"typeVersion": 1
},
{
"id": "666e7b09-aefd-4026-a92b-3fd11ce34648",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
144,
-32
],
"parameters": {
"color": 7,
"width": 496,
"height": 864,
"content": "\n## Data Normalization\n**What:** Applies format-standardization and transformation rules to each data source independently.\n**Why:** Creates consistent data structure "
},
"typeVersion": 1
},
{
"id": "7ea72134-db7a-490c-9bad-91f93cdebb1e",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-512,
-32
],
"parameters": {
"color": 7,
"width": 640,
"height": 848,
"content": "## Multi-Source Data Collection\n**What:** Retrieves raw transaction data from four distinct payment sources \n**Why:** Ensures complete revenue visibility across all channels."
},
"typeVersion": 1
},
{
"id": "a6403c5a-d2fa-45ba-9e73-96d5ee5374fe",
"name": "Monthly revenue aggregation",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-448,
288
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 2
}
]
}
},
"typeVersion": 1.3
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "f383bd8c-1507-4a29-8db0-b5c054a9a569",
"connections": {
"OpenAI Model": {
"ai_languageModel": [
[
{
"node": "AI Income Categorizer",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Format as CSV": {
"main": [
[
{
"node": "Check Submission Method",
"type": "main",
"index": 0
}
]
]
},
"Format as XML": {
"main": [
[
{
"node": "Archive to Google Drive",
"type": "main",
"index": 0
}
]
]
},
"Email to Tax Agent": {
"main": [
[
{
"node": "Archive to Google Drive",
"type": "main",
"index": 0
}
]
]
},
"Get Bank Feed Data": {
"main": [
[
{
"node": "Normalize Bank Data",
"type": "main",
"index": 0
}
]
]
},
"Get Shopify Orders": {
"main": [
[
{
"node": "Normalize Shopify Data",
"type": "main",
"index": 0
}
]
]
},
"Normalize Bank Data": {
"main": [
[
{
"node": "Merge All Revenue Sources",
"type": "main",
"index": 0
}
]
]
},
"AI Income Categorizer": {
"main": [
[
{
"node": "Calculate Period Totals",
"type": "main",
"index": 0
}
]
]
},
"Normalize PayPal Data": {
"main": [
[
{
"node": "Merge All Revenue Sources",
"type": "main",
"index": 0
}
]
]
},
"Normalize Stripe Data": {
"main": [
[
{
"node": "Merge All Revenue Sources",
"type": "main",
"index": 0
}
]
]
},
"Normalize Shopify Data": {
"main": [
[
{
"node": "Merge All Revenue Sources",
"type": "main",
"index": 0
}
]
]
},
"Workflow Configuration": {
"main": [
[
{
"node": "Get Stripe Transactions",
"type": "main",
"index": 0
},
{
"node": "Get PayPal Transactions",
"type": "main",
"index": 0
},
{
"node": "Get Shopify Orders",
"type": "main",
"index": 0
},
{
"node": "Get Bank Feed Data",
"type": "main",
"index": 0
}
]
]
},
"Calculate Period Totals": {
"main": [
[
{
"node": "Format as CSV",
"type": "main",
"index": 0
},
{
"node": "Format as XML",
"type": "main",
"index": 0
}
]
]
},
"Check Submission Method": {
"main": [
[
{
"node": "Submit to Government API",
"type": "main",
"index": 0
}
],
[
{
"node": "Email to Tax Agent",
"type": "main",
"index": 0
}
]
]
},
"Get PayPal Transactions": {
"main": [
[
{
"node": "Normalize PayPal Data",
"type": "main",
"index": 0
}
]
]
},
"Get Stripe Transactions": {
"main": [
[
{
"node": "Normalize Stripe Data",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "AI Income Categorizer",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Submit to Government API": {
"main": [
[
{
"node": "Archive to Google Drive",
"type": "main",
"index": 0
}
]
]
},
"Merge All Revenue Sources": {
"main": [
[
{
"node": "AI Income Categorizer",
"type": "main",
"index": 0
}
]
]
},
"Monthly revenue aggregation": {
"main": [
[
{
"node": "Workflow Configuration",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2googleDriveOAuth2ApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Consolidates daily revenue from Stripe, PayPal, Shopify, and bank feeds into a single system. The workflow automatically normalizes data across payment sources, uses AI to categorize income transactions, calculates reporting-period totals, and generates tax-compliant CSV and XML…
Source: https://n8n.io/workflows/11899/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This n8n automation workflow automates the creation, scripting, production, and posting of YouTube videos. It leverages AI (OpenAI), image generation (PIAPI), video rendering (Shotstack), and platform
This workflow automates financial reconciliation by orchestrating multiple AI agents to detect mismatches, analyze root causes, and apply corrections across bank statements, invoices, and e-commerce p
AI powered workflow that scans HR news via RSS, checks which of your policies or contract templates might need updates, and sends a weekly internal newsletter as HTML.
This workflow automates monthly revenue aggregation from multiple financial sources, including Stripe, PayPal, Shopify, and bank feeds, while delivering intelligent tax forecasting through GPT-4–based
Automates monthly payroll processing and tax compliance by calculating employee payroll, applying accurate withholdings, generating comprehensive tax summaries, and producing compliance-ready document