{
  "id": "hnrLA7lWf3bSl7Dw",
  "name": "Automated Revenue Reconciliation & Tax Evidence Archive",
  "tags": [],
  "nodes": [
    {
      "id": "bbb0bbe0-fd8f-46cd-bd2f-c4826efcca19",
      "name": "Monthly Schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -448,
        192
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "months",
              "triggerAtHour": 2
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "6d08da53-983a-438c-b164-ff86ce7c1b47",
      "name": "Workflow Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        -224,
        192
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "stripeApiUrl",
              "type": "string",
              "value": "<__PLACEHOLDER_VALUE__Stripe API endpoint URL__>"
            },
            {
              "id": "id-2",
              "name": "paypalApiUrl",
              "type": "string",
              "value": "<__PLACEHOLDER_VALUE__PayPal API endpoint URL__>"
            },
            {
              "id": "id-3",
              "name": "bankApiUrl",
              "type": "string",
              "value": "<__PLACEHOLDER_VALUE__Bank API endpoint URL__>"
            },
            {
              "id": "id-4",
              "name": "archiveFolderId",
              "type": "string",
              "value": "<__PLACEHOLDER_VALUE__Google Drive folder ID for archive__>"
            },
            {
              "id": "id-5",
              "name": "taxAgentEmail",
              "type": "string",
              "value": "<__PLACEHOLDER_VALUE__Tax agent email address__>"
            },
            {
              "id": "id-6",
              "name": "reconciliationThreshold",
              "type": "number",
              "value": 0.01
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "ead117d5-1bee-4c3f-bd93-1810f7f9600a",
      "name": "Get Stripe Revenue",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        0,
        0
      ],
      "parameters": {
        "url": "={{ $('Workflow Configuration').first().json.stripeApiUrl }}",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "created[gte]",
              "value": "={{ $now.minus({ months: 1 }).startOf('month').toUnixInteger() }}"
            },
            {
              "name": "created[lt]",
              "value": "={{ $now.startOf('month').toUnixInteger() }}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "43052c70-6f3f-49b7-aa1a-22f8db32790d",
      "name": "Get PayPal Revenue",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        0,
        192
      ],
      "parameters": {
        "url": "={{ $('Workflow Configuration').first().json.paypalApiUrl }}",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "start_date",
              "value": "={{ $now.minus({ months: 1 }).startOf('month').toISO() }}"
            },
            {
              "name": "end_date",
              "value": "={{ $now.startOf('month').toISO() }}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "8efb034f-82d7-43db-aa89-96ca9bb14f63",
      "name": "Get Bank Statements",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        224,
        384
      ],
      "parameters": {
        "url": "={{ $('Workflow Configuration').first().json.bankApiUrl }}",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "from_date",
              "value": "={{ $now.minus({ months: 1 }).startOf('month').toISODate() }}"
            },
            {
              "name": "to_date",
              "value": "={{ $now.startOf('month').toISODate() }}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "ba8740a8-2dcb-4513-94e0-047e96cc0f26",
      "name": "Normalize Stripe Data",
      "type": "n8n-nodes-base.set",
      "position": [
        224,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "transactionId",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "id-2",
              "name": "amount",
              "type": "number",
              "value": "={{ $json.amount / 100 }}"
            },
            {
              "id": "id-3",
              "name": "currency",
              "type": "string",
              "value": "={{ $json.currency }}"
            },
            {
              "id": "id-4",
              "name": "date",
              "type": "string",
              "value": "={{ $json.created }}"
            },
            {
              "id": "id-5",
              "name": "source",
              "type": "string",
              "value": "Stripe"
            },
            {
              "id": "id-6",
              "name": "description",
              "type": "string",
              "value": "={{ $json.description }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "131da027-2258-4957-a297-c232325e4ea5",
      "name": "Normalize PayPal Data",
      "type": "n8n-nodes-base.set",
      "position": [
        224,
        192
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "transactionId",
              "type": "string",
              "value": "={{ $json.transaction_info.transaction_id }}"
            },
            {
              "id": "id-2",
              "name": "amount",
              "type": "number",
              "value": "={{ $json.transaction_info.transaction_amount.value }}"
            },
            {
              "id": "id-3",
              "name": "currency",
              "type": "string",
              "value": "={{ $json.transaction_info.transaction_amount.currency_code }}"
            },
            {
              "id": "id-4",
              "name": "date",
              "type": "string",
              "value": "={{ $json.transaction_info.transaction_initiation_date }}"
            },
            {
              "id": "id-5",
              "name": "source",
              "type": "string",
              "value": "PayPal"
            },
            {
              "id": "id-6",
              "name": "description",
              "type": "string",
              "value": "={{ $json.transaction_info.transaction_subject }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "ac495591-815b-4443-a661-be7aa94af167",
      "name": "Normalize Bank Data",
      "type": "n8n-nodes-base.set",
      "position": [
        448,
        384
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "transactionId",
              "type": "string",
              "value": "={{ $json.transaction_id }}"
            },
            {
              "id": "id-2",
              "name": "amount",
              "type": "number",
              "value": "={{ $json.amount }}"
            },
            {
              "id": "id-3",
              "name": "currency",
              "type": "string",
              "value": "={{ $json.currency }}"
            },
            {
              "id": "id-4",
              "name": "date",
              "type": "string",
              "value": "={{ $json.booking_date }}"
            },
            {
              "id": "id-5",
              "name": "source",
              "type": "string",
              "value": "Bank"
            },
            {
              "id": "id-6",
              "name": "description",
              "type": "string",
              "value": "={{ $json.remittance_information }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "6e01a2e2-2224-441c-983e-91ed044382ee",
      "name": "Combine Revenue Sources",
      "type": "n8n-nodes-base.merge",
      "position": [
        448,
        96
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "a2d97894-1d5d-48b0-a05d-26a2bf3db021",
      "name": "Reconcile Revenue vs Bank",
      "type": "n8n-nodes-base.code",
      "position": [
        672,
        192
      ],
      "parameters": {
        "jsCode": "// Reconcile revenue sources against bank statements\nconst items = $input.all();\n\n// Separate revenue sources from bank data\nconst revenueItems = [];\nconst bankItems = [];\n\nfor (const item of items) {\n  if (item.json.source === 'stripe' || item.json.source === 'paypal') {\n    revenueItems.push(item.json);\n  } else if (item.json.source === 'bank') {\n    bankItems.push(item.json);\n  }\n}\n\n// Calculate total revenue from payment processors\nconst totalRevenue = revenueItems.reduce((sum, item) => {\n  return sum + (parseFloat(item.amount) || 0);\n}, 0);\n\n// Calculate total deposits from bank\nconst totalBankDeposits = bankItems.reduce((sum, item) => {\n  return sum + (parseFloat(item.amount) || 0);\n}, 0);\n\n// Calculate difference\nconst difference = totalRevenue - totalBankDeposits;\nconst differencePercentage = totalBankDeposits > 0 \n  ? ((difference / totalBankDeposits) * 100).toFixed(2)\n  : 0;\n\n// Create reconciliation report\nconst reconciliation = {\n  totalRevenue: totalRevenue.toFixed(2),\n  totalBankDeposits: totalBankDeposits.toFixed(2),\n  difference: difference.toFixed(2),\n  differencePercentage: differencePercentage,\n  hasMismatch: Math.abs(difference) > 0.01, // Allow for small rounding differences\n  revenueCount: revenueItems.length,\n  bankTransactionCount: bankItems.length,\n  reconciliationDate: new Date().toISOString(),\n  revenueBreakdown: {\n    stripe: revenueItems.filter(i => i.source === 'stripe').reduce((sum, i) => sum + parseFloat(i.amount || 0), 0).toFixed(2),\n    paypal: revenueItems.filter(i => i.source === 'paypal').reduce((sum, i) => sum + parseFloat(i.amount || 0), 0).toFixed(2)\n  },\n  allTransactions: [...revenueItems, ...bankItems]\n};\n\nreturn [{ json: reconciliation }];"
      },
      "typeVersion": 2
    },
    {
      "id": "dfdd2e11-c8f1-4504-b13e-d7137c59b2a1",
      "name": "Check for Mismatches",
      "type": "n8n-nodes-base.if",
      "position": [
        896,
        192
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "id-1",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $('Reconcile Revenue vs Bank').item.json.hasMismatches }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "858def70-5a67-4b79-8c2a-e3528082f850",
      "name": "Flag Mismatches",
      "type": "n8n-nodes-base.set",
      "position": [
        1120,
        128
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "mismatchFlag",
              "type": "string",
              "value": "ATTENTION REQUIRED"
            },
            {
              "id": "id-2",
              "name": "reviewRequired",
              "type": "boolean",
              "value": true
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "c907f41d-c860-4d1a-8708-d26a62dc4786",
      "name": "Aggregate Monthly Data",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1344,
        192
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "c64b6ad1-cc8e-4dc7-bc93-7598b0379e8e",
      "name": "Generate Audit Report",
      "type": "n8n-nodes-base.code",
      "position": [
        1568,
        192
      ],
      "parameters": {
        "jsCode": "// Generate comprehensive audit-proof monthly revenue report\nconst items = $input.all();\n\n// Extract date range from workflow configuration\nconst currentDate = new Date();\nconst reportMonth = currentDate.toLocaleString('default', { month: 'long', year: 'numeric' });\n\n// Aggregate data from all items\nlet totalStripeRevenue = 0;\nlet totalPayPalRevenue = 0;\nlet totalBankDeposits = 0;\nlet transactions = [];\nlet mismatches = [];\n\nfor (const item of items) {\n  const data = item.json;\n  \n  // Collect transaction details\n  if (data.source) {\n    transactions.push({\n      date: data.date || data.transaction_date,\n      source: data.source,\n      amount: data.amount,\n      description: data.description || data.memo,\n      transactionId: data.transaction_id || data.id\n    });\n  }\n  \n  // Aggregate revenue by source\n  if (data.source === 'Stripe') {\n    totalStripeRevenue += parseFloat(data.amount || 0);\n  } else if (data.source === 'PayPal') {\n    totalPayPalRevenue += parseFloat(data.amount || 0);\n  } else if (data.source === 'Bank') {\n    totalBankDeposits += parseFloat(data.amount || 0);\n  }\n  \n  // Collect mismatches\n  if (data.mismatch_flag || data.reconciliation_status === 'mismatch') {\n    mismatches.push({\n      date: data.date,\n      expectedAmount: data.expected_amount,\n      actualAmount: data.actual_amount,\n      difference: data.difference,\n      notes: data.notes\n    });\n  }\n}\n\n// Calculate totals and variance\nconst totalRevenue = totalStripeRevenue + totalPayPalRevenue;\nconst variance = totalBankDeposits - totalRevenue;\nconst variancePercentage = totalRevenue > 0 ? ((variance / totalRevenue) * 100).toFixed(2) : 0;\n\n// Generate report structure\nconst report = {\n  reportMetadata: {\n    title: `Monthly Revenue Reconciliation Report - ${reportMonth}`,\n    generatedDate: currentDate.toISOString(),\n    reportPeriod: reportMonth,\n    reportType: 'Tax Audit Evidence'\n  },\n  executiveSummary: {\n    totalStripeRevenue: totalStripeRevenue.toFixed(2),\n    totalPayPalRevenue: totalPayPalRevenue.toFixed(2),\n    totalRevenue: totalRevenue.toFixed(2),\n    totalBankDeposits: totalBankDeposits.toFixed(2),\n    variance: variance.toFixed(2),\n    variancePercentage: `${variancePercentage}%`,\n    reconciliationStatus: Math.abs(variance) < 1 ? 'RECONCILED' : 'VARIANCE DETECTED',\n    totalTransactions: transactions.length,\n    mismatchCount: mismatches.length\n  },\n  revenueBreakdown: {\n    stripe: {\n      total: totalStripeRevenue.toFixed(2),\n      percentage: totalRevenue > 0 ? ((totalStripeRevenue / totalRevenue) * 100).toFixed(2) + '%' : '0%'\n    },\n    paypal: {\n      total: totalPayPalRevenue.toFixed(2),\n      percentage: totalRevenue > 0 ? ((totalPayPalRevenue / totalRevenue) * 100).toFixed(2) + '%' : '0%'\n    }\n  },\n  transactions: transactions.sort((a, b) => new Date(a.date) - new Date(b.date)),\n  mismatches: mismatches,\n  reconciliationNotes: {\n    methodology: 'Automated reconciliation comparing payment processor revenue against bank deposits',\n    toleranceThreshold: '$1.00',\n    dataSource: 'Stripe API, PayPal API, Bank Statements',\n    verificationStatus: mismatches.length === 0 ? 'All transactions verified' : `${mismatches.length} discrepancies require review`\n  },\n  auditTrail: {\n    workflowExecutionId: $execution.id,\n    executionDate: currentDate.toISOString(),\n    dataIntegrity: 'Verified',\n    complianceStandard: 'Tax Authority Requirements'\n  }\n};\n\n// Generate PDF-ready HTML content\nconst htmlReport = `\n<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Revenue Reconciliation Report - ${reportMonth}</title>\n  <style>\n    body { font-family: Arial, sans-serif; margin: 40px; color: #333; }\n    h1 { color: #2c3e50; border-bottom: 3px solid #3498db; padding-bottom: 10px; }\n    h2 { color: #34495e; margin-top: 30px; border-bottom: 1px solid #bdc3c7; padding-bottom: 5px; }\n    .summary-box { background: #ecf0f1; padding: 20px; border-radius: 5px; margin: 20px 0; }\n    .status-ok { color: #27ae60; font-weight: bold; }\n    .status-warning { color: #e74c3c; font-weight: bold; }\n    table { width: 100%; border-collapse: collapse; margin: 20px 0; }\n    th { background: #34495e; color: white; padding: 12px; text-align: left; }\n    td { padding: 10px; border-bottom: 1px solid #ddd; }\n    tr:hover { background: #f5f5f5; }\n    .amount { text-align: right; font-family: monospace; }\n    .footer { margin-top: 50px; font-size: 12px; color: #7f8c8d; border-top: 1px solid #bdc3c7; padding-top: 20px; }\n  </style>\n</head>\n<body>\n  <h1>${report.reportMetadata.title}</h1>\n  <p><strong>Generated:</strong> ${new Date(report.reportMetadata.generatedDate).toLocaleString()}</p>\n  <p><strong>Report Type:</strong> ${report.reportMetadata.reportType}</p>\n  \n  <div class=\"summary-box\">\n    <h2>Executive Summary</h2>\n    <table>\n      <tr><td><strong>Total Stripe Revenue:</strong></td><td class=\"amount\">$${report.executiveSummary.totalStripeRevenue}</td></tr>\n      <tr><td><strong>Total PayPal Revenue:</strong></td><td class=\"amount\">$${report.executiveSummary.totalPayPalRevenue}</td></tr>\n      <tr><td><strong>Total Revenue:</strong></td><td class=\"amount\">$${report.executiveSummary.totalRevenue}</td></tr>\n      <tr><td><strong>Total Bank Deposits:</strong></td><td class=\"amount\">$${report.executiveSummary.totalBankDeposits}</td></tr>\n      <tr><td><strong>Variance:</strong></td><td class=\"amount ${Math.abs(variance) < 1 ? 'status-ok' : 'status-warning'}\">$${report.executiveSummary.variance} (${report.executiveSummary.variancePercentage})</td></tr>\n      <tr><td><strong>Status:</strong></td><td class=\"${Math.abs(variance) < 1 ? 'status-ok' : 'status-warning'}\">${report.executiveSummary.reconciliationStatus}</td></tr>\n      <tr><td><strong>Total Transactions:</strong></td><td>${report.executiveSummary.totalTransactions}</td></tr>\n      <tr><td><strong>Mismatches:</strong></td><td class=\"${mismatches.length === 0 ? 'status-ok' : 'status-warning'}\">${report.executiveSummary.mismatchCount}</td></tr>\n    </table>\n  </div>\n  \n  <h2>Revenue Breakdown by Source</h2>\n  <table>\n    <tr><th>Source</th><th>Amount</th><th>Percentage</th></tr>\n    <tr><td>Stripe</td><td class=\"amount\">$${report.revenueBreakdown.stripe.total}</td><td class=\"amount\">${report.revenueBreakdown.stripe.percentage}</td></tr>\n    <tr><td>PayPal</td><td class=\"amount\">$${report.revenueBreakdown.paypal.total}</td><td class=\"amount\">${report.revenueBreakdown.paypal.percentage}</td></tr>\n  </table>\n  \n  <h2>Transaction Details</h2>\n  <table>\n    <tr><th>Date</th><th>Source</th><th>Transaction ID</th><th>Description</th><th>Amount</th></tr>\n    ${transactions.map(t => `\n      <tr>\n        <td>${new Date(t.date).toLocaleDateString()}</td>\n        <td>${t.source}</td>\n        <td>${t.transactionId}</td>\n        <td>${t.description}</td>\n        <td class=\"amount\">$${parseFloat(t.amount).toFixed(2)}</td>\n      </tr>\n    `).join('')}\n  </table>\n  \n  ${mismatches.length > 0 ? `\n    <h2>Discrepancies Requiring Review</h2>\n    <table>\n      <tr><th>Date</th><th>Expected</th><th>Actual</th><th>Difference</th><th>Notes</th></tr>\n      ${mismatches.map(m => `\n        <tr>\n          <td>${new Date(m.date).toLocaleDateString()}</td>\n          <td class=\"amount\">$${parseFloat(m.expectedAmount).toFixed(2)}</td>\n          <td class=\"amount\">$${parseFloat(m.actualAmount).toFixed(2)}</td>\n          <td class=\"amount status-warning\">$${parseFloat(m.difference).toFixed(2)}</td>\n          <td>${m.notes}</td>\n        </tr>\n      `).join('')}\n    </table>\n  ` : '<p class=\"status-ok\">No discrepancies detected. All transactions reconciled successfully.</p>'}\n  \n  <h2>Reconciliation Methodology</h2>\n  <p>${report.reconciliationNotes.methodology}</p>\n  <p><strong>Tolerance Threshold:</strong> ${report.reconciliationNotes.toleranceThreshold}</p>\n  <p><strong>Data Sources:</strong> ${report.reconciliationNotes.dataSource}</p>\n  <p><strong>Verification Status:</strong> ${report.reconciliationNotes.verificationStatus}</p>\n  \n  <div class=\"footer\">\n    <h2>Audit Trail</h2>\n    <p><strong>Workflow Execution ID:</strong> ${report.auditTrail.workflowExecutionId}</p>\n    <p><strong>Execution Date:</strong> ${new Date(report.auditTrail.executionDate).toLocaleString()}</p>\n    <p><strong>Data Integrity:</strong> ${report.auditTrail.dataIntegrity}</p>\n    <p><strong>Compliance Standard:</strong> ${report.auditTrail.complianceStandard}</p>\n    <p><em>This report was automatically generated by an audited workflow process and contains verified financial data suitable for tax authority submission.</em></p>\n  </div>\n</body>\n</html>\n`;\n\n// Return both JSON and HTML formats\nreturn [\n  {\n    json: {\n      report: report,\n      htmlReport: htmlReport,\n      fileName: `Revenue_Reconciliation_${reportMonth.replace(' ', '_')}_${currentDate.toISOString().split('T')[0]}.html`,\n      pdfReady: true,\n      summary: {\n        totalRevenue: totalRevenue,\n        totalBankDeposits: totalBankDeposits,\n        variance: variance,\n        status: Math.abs(variance) < 1 ? 'RECONCILED' : 'VARIANCE_DETECTED',\n        mismatchCount: mismatches.length\n      }\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "511a0aa7-79b0-4a62-a21c-daee9e7796f3",
      "name": "Upload to Archive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1792,
        192
      ],
      "parameters": {
        "name": "={{ 'Revenue_Report_' + $now.minus({ months: 1 }).toFormat('yyyy-MM') + '.pdf' }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Workflow Configuration').first().json.archiveFolderId }}"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "f11ee402-4b02-49d6-869f-fbcd9a151fd0",
      "name": "Notify Tax Agent",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2016,
        192
      ],
      "parameters": {
        "sendTo": "={{ $('Workflow Configuration').first().json.taxAgentEmail }}",
        "message": "=<h2>Monthly Revenue Report</h2>\n\n<p>Dear Tax Agent,</p>\n\n<p>The automated revenue reconciliation for {{ $now.minus({ months: 1 }).toFormat('MMMM yyyy') }} has been completed.</p>\n\n<h3>Report Summary:</h3>\n<ul>\n  <li><strong>Total Revenue:</strong> {{ $('Aggregate Monthly Data').first().json.totalRevenue }}</li>\n  <li><strong>Stripe Revenue:</strong> {{ $('Aggregate Monthly Data').first().json.stripeRevenue }}</li>\n  <li><strong>PayPal Revenue:</strong> {{ $('Aggregate Monthly Data').first().json.paypalRevenue }}</li>\n  <li><strong>Bank Deposits:</strong> {{ $('Aggregate Monthly Data').first().json.bankDeposits }}</li>\n</ul>\n\n{{ $('Flag Mismatches').all().length > 0 ? '<h3 style=\"color: #ff6b6b;\">\u26a0\ufe0f Mismatches Detected:</h3><p>There are ' + $('Flag Mismatches').all().length + ' discrepancies that require review. Please check the detailed report.</p>' : '<p style=\"color: #51cf66;\">\u2713 All revenue sources reconciled successfully with no discrepancies.</p>' }}\n\n<h3>Archived Report:</h3>\n<p>The complete audit report has been uploaded to Google Drive:</p>\n<p><a href=\"{{ $('Upload to Archive').first().json.webViewLink }}\">View Report</a></p>\n\n<p>Best regards,<br>Automated Revenue Reconciliation System</p>",
        "options": {},
        "subject": "={{ 'Monthly Revenue Report Ready - ' + $now.minus({ months: 1 }).toFormat('MMMM yyyy') }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "22bc4a46-41f2-409a-8376-1f7b8081f26f",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        896,
        -416
      ],
      "parameters": {
        "color": 5,
        "width": 720,
        "height": 288,
        "content": "## Prerequisites\nStripe, PayPal, and bank statement accounts; API credentials for each source \n## Use Cases\nAccounting firms automating client revenue verification; multi-channel e-commerce businesses  \n## Customization\nAdd additional payment sources (Square, Shopify), adjust normalization rules for regional formats \n## Benefits\nEliminates manual reconciliation, detects discrepancies automatically "
      },
      "typeVersion": 1
    },
    {
      "id": "ebd4913f-814c-4fdd-bc36-41f3b187f965",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        384,
        -352
      ],
      "parameters": {
        "width": 464,
        "height": 208,
        "content": "## Setup Steps\n1. Configure Stripe, PayPal.\n2. Set up normalization rules for date, currency, and transaction ID mappings.\n3. Connect Google Drive for report archiving and Gmail for agent notifications.\n4. Define mismatch thresholds and reconciliation tolerance parameters."
      },
      "typeVersion": 1
    },
    {
      "id": "f04bccea-bc33-465f-a9cf-c83c55420662",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -448,
        -352
      ],
      "parameters": {
        "width": 800,
        "height": 224,
        "content": "## How It Works\nThis workflow automates monthly revenue reconciliation across Stripe, PayPal, and bank statements by standardizing data formats, detecting discrepancies, and producing audit-ready reports. It concurrently retrieves revenue data from multiple sources, normalizes datasets into consistent structures, consolidates records, and reconciles transactions against bank statements with intelligent mismatch detection. The system aggregates monthly totals, generates detailed audit reports with clearly flagged discrepancies, archives finalized outputs to Google Drive, and notifies tax agents. Designed for accounting firms, finance teams, and businesses, it enables automated revenue verification, multi-channel reconciliation, discrepancy identification, and compliance audit documentation without manual record matching or error-prone spreadsheet workflows."
      },
      "typeVersion": 1
    },
    {
      "id": "71f605f8-f4e9-4bc5-bd86-13f1e375cff0",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1504,
        -96
      ],
      "parameters": {
        "color": 7,
        "width": 656,
        "height": 688,
        "content": "## Generate Audit Report & Notification\nWhat: Compiles flagged mismatches, monthly aggregates into audit documentation.\nWhy: Provides compliance evidence, supports tax filing \n"
      },
      "typeVersion": 1
    },
    {
      "id": "99a328fb-27cb-4781-a415-bc349e543a1b",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        -96
      ],
      "parameters": {
        "color": 7,
        "width": 1120,
        "height": 704,
        "content": "## Reconcile & Flag Mismatches\nWhat: Compares aggregated revenue against bank statement totals and identifies discrepancies.\nWhy: Detects timing differences, missing transactions, and potential fraud  "
      },
      "typeVersion": 1
    },
    {
      "id": "1595a83a-4df7-46b6-91bc-7bde3fe23798",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -496,
        -96
      ],
      "parameters": {
        "color": 7,
        "width": 848,
        "height": 672,
        "content": "## Fetch Multi-Source Data\nWhat: Retrieves revenue records from Stripe, PayPal, and bank statements in parallel.\nWhy: Captures complete revenue picture across all payment and settlement channels."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "df95ae9d-7021-4834-b49d-efc9c1ca3243",
  "connections": {
    "Flag Mismatches": {
      "main": [
        [
          {
            "node": "Aggregate Monthly Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Monthly Schedule": {
      "main": [
        [
          {
            "node": "Workflow Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload to Archive": {
      "main": [
        [
          {
            "node": "Notify Tax Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get PayPal Revenue": {
      "main": [
        [
          {
            "node": "Normalize PayPal Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Stripe Revenue": {
      "main": [
        [
          {
            "node": "Normalize Stripe Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Bank Statements": {
      "main": [
        [
          {
            "node": "Normalize Bank Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Bank Data": {
      "main": [
        [
          {
            "node": "Reconcile Revenue vs Bank",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check for Mismatches": {
      "main": [
        [
          {
            "node": "Flag Mismatches",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Aggregate Monthly Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Audit Report": {
      "main": [
        [
          {
            "node": "Upload to Archive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize PayPal Data": {
      "main": [
        [
          {
            "node": "Combine Revenue Sources",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Normalize Stripe Data": {
      "main": [
        [
          {
            "node": "Combine Revenue Sources",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Monthly Data": {
      "main": [
        [
          {
            "node": "Generate Audit Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workflow Configuration": {
      "main": [
        [
          {
            "node": "Get Stripe Revenue",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get PayPal Revenue",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Bank Statements",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine Revenue Sources": {
      "main": [
        [
          {
            "node": "Reconcile Revenue vs Bank",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reconcile Revenue vs Bank": {
      "main": [
        [
          {
            "node": "Check for Mismatches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}