← All E-commerce

Paypal email verification with BillionVerify

PayPal is one of the world's most widely used online payment platforms, processing transactions for individuals, freelancers, and businesses of all sizes. Connecting BillionVerify to your PayPal workflow lets you validate buyer and sender email addresses before they are added to your contact lists or CRM.

Why verify before the send

PayPal transactions surface a large volume of email addresses β€” buyers, senders, and refund requestors β€” that flow into marketing lists and CRMs. Invalid, disposable, or catch-all addresses in that pool inflate bounce rates and erode sender reputation. BillionVerify filters them out before they cause problems.

Ready-to-use n8n workflow

Import this workflow into n8n β€” it verifies every address with BillionVerify before Paypal sends, so only deliverable contacts are emailed. Install the BillionVerify community node first, then add your API key. Adapted from this n8n template

verify-emails-in-paypal.json
{
  "name": "Consolidate Stripe, PayPal, Shopify and bank revenue and prepare tax filings with OpenAI + BillionVerify",
  "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": {
          "id": "mv2ECvRtbAK63G2g",
          "name": "OpenAi account"
        }
      },
      "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, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\"/g, '&quot;')\n    .replace(/'/g, '&apos;');\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
      ],
      "webhookId": "103d107e-b3c2-4f50-b9a8-84fbb984c6e0",
      "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": {
          "id": "u1N5nBDvQ0AWhNnV",
          "name": "Gmail account"
        }
      },
      "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": {
          "id": "ALHOS4YihnICuh2c",
          "name": "Google Drive account"
        }
      },
      "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
    },
    {
      "parameters": {
        "operation": "verify",
        "email": "={{ $('Workflow Configuration').first().json.taxAgentEmail }}",
        "additionalOptions": {}
      },
      "type": "n8n-nodes-billionverify.billionVerify",
      "typeVersion": 1,
      "position": [
        1336,
        288
      ],
      "name": "Verify Email (BillionVerify)",
      "credentials": {
        "billionVerifyApi": {
          "id": "",
          "name": "BillionVerify account"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "is-deliverable",
              "leftValue": "={{ $json.is_deliverable }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ]
        }
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        1516,
        288
      ],
      "name": "IF deliverable"
    }
  ],
  "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": "Verify Email (BillionVerify)",
            "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
          }
        ]
      ]
    },
    "Verify Email (BillionVerify)": {
      "main": [
        [
          {
            "node": "IF deliverable",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF deliverable": {
      "main": [
        [
          {
            "node": "Email to Tax Agent",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}

Workflow templates with Paypal

Ready-to-use workflows that verify emails before Paypal sends.

How it works

  1. 1

    Use the BillionVerify n8n community node or Integrately to connect your PayPal account with BillionVerify.

  2. 2

    Trigger the workflow on incoming PayPal payments or IPN notifications.

  3. 3

    Extract the payer email and send it to BillionVerify for verification.

  4. 4

    Route addresses marked valid to your CRM, email platform, or follow-up sequence.

  5. 5

    Quarantine or discard invalid, disposable, and role-based addresses to keep your lists clean.

When to use this

Buyer List Enrichment and Hygiene

When a PayPal payment comes in, verify the payer's email before adding it to your newsletter or CRM. Filtering out disposable inboxes at this stage keeps your marketing list healthy and your campaigns from bouncing.

Refund and Support Email Validation

Before routing a refund request or support ticket to an agent, confirm the customer's email is reachable. This prevents wasted effort on communications that can never be delivered.

Post-Transaction Upsell Campaigns

Export PayPal transaction emails for upsell or retention campaigns. Running them through BillionVerify first removes invalid and inactive addresses, improving deliverability and open rates.

FAQ

Why would I need to verify emails from PayPal transactions?

PayPal email addresses feed into marketing lists and CRMs. Without verification, disposable and invalid addresses inflate bounce rates, hurting your sender reputation and reducing campaign effectiveness.

Does BillionVerify work in real time with PayPal triggers?

Yes. Using n8n or Integrately, BillionVerify can verify each email as soon as a PayPal event fires, typically completing the check in under a second via the REST API.

Can I clean an existing list of PayPal customer emails in bulk?

Absolutely. Export your PayPal transaction history, upload the email column, and run batch verification through BillionVerify's API to clean historical data before any campaign.

Verify emails in Paypal

Create a free account, grab your API key, and stop bounces before they happen.

Get started free