AutomationFlowsAI & RAG › Monitor Cryptocurrency Payments Across Multiple Blockchains with Agentgatepay

Monitor Cryptocurrency Payments Across Multiple Blockchains with Agentgatepay

ByAgentGatePay @agentgatepay on n8n.io

Get your AI agents paying for resources autonomously in under 10 minutes.

Event trigger★★★★★ complexity41 nodesHTTP Request
AI & RAG Trigger: Event Nodes: 41 Complexity: ★★★★★ Added:
Monitor Cryptocurrency Payments Across Multiple Blockchains with Agentgatepay — n8n workflow card showing HTTP Request integration

This workflow corresponds to n8n.io template #12015 — we link there as the canonical source.

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 →

Download .json
{
  "id": "NtUmR7wzjKfYbBOS",
  "name": "\ud83d\udcb2 \ud83d\udcca AgentGatePay - Monitoring Dashboard",
  "tags": [],
  "nodes": [
    {
      "id": "51d9e284-b69f-4650-9fa2-6314737afafd",
      "name": "\u25b6\ufe0f Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "notes": "\u25b6\ufe0f MANUAL TRIGGER: Click 'Execute Workflow' to run\n\n\u26a0\ufe0f Configure your API key in Node 2 before running!\n\nThis workflow runs standalone without webhooks.\nAll data is fetched from AgentGatePay API.",
      "position": [
        -1264,
        176
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "f580877c-e612-41cc-ba62-33e2eefd8539",
      "name": "2\ufe0f\u20e3 Load Config",
      "type": "n8n-nodes-base.code",
      "notes": "\u2699\ufe0f SETUP: Validate inputs\n\n\u26a0\ufe0f EDIT THIS if running manually:\n- user_email: Your buyer email\n- api_key: Your AgentGatePay API key",
      "position": [
        -1040,
        176
      ],
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// CONFIG: Validate inputs and setup monitoring parameters\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst input = $input.first().json;\n\n// Check if triggered by webhook or manual\nconst isManual = !input.user_email;\n\nconst config = {\n  user_email: input.user_email || \"user@example.com\",  // \u26a0\ufe0f REPLACE if running manually\n  api_key: input.api_key || \"YOUR_API_KEY\",  // \u26a0\ufe0f REPLACE if running manually\n  buyer_wallet: input.buyer_wallet || \"YOUR_WALLET_ADDRESS\",  // \u26a0\ufe0f REPLACE with your wallet (0x...)\n  tx_hash: input.tx_hash || null,\n  trigger_source: input.trigger_source || \"manual\",\n  \n  // Monitoring settings\n  time_range_hours: 24,\n  payment_history_limit: 50,  // Fetch last 50 for display (use curl for full history)\n  audit_log_limit: 50,\n  export_format: \"csv\",\n  \n  // AgentGatePay API\n  api_url: \"https://api.agentgatepay.com\",\n  mcp_endpoint: \"https://mcp.agentgatepay.com\",\n  \n  // Session tracking\n  session: {\n    id: `monitor_${Date.now()}`,\n    started_at: new Date().toISOString(),\n    is_manual: isManual\n  }\n};\n\n// Validation\nif (config.api_key === \"YOUR_API_KEY\") {\n  throw new Error(\"\u274c Please configure your API key in Node 2 'Load Config'!\");\n}\n\nconsole.log(`\ud83d\udcca Monitoring Dashboard Started`);\nconsole.log(`   User: ${config.user_email}`);\nconsole.log(`   Source: ${config.trigger_source}`);\nconsole.log(`   TX Hash: ${config.tx_hash || 'N/A'}`);\n\nreturn [{ json: { config } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "6ece2262-a292-4b44-9107-c302d8922e24",
      "name": "3\ufe0f\u20e3 \ud83d\udcc8 Get User Analytics",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "\ud83d\udcc8 ANALYTICS: Fetch user spending stats\n\nReturns:\n- total_spent_usd\n- payment_count\n- active_mandates\n- budget_remaining\n- spending_trend",
      "position": [
        -832,
        176
      ],
      "parameters": {
        "url": "={{ $json.config.api_url }}/v1/analytics/me",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "={{ $json.config.api_key }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "e1bafe66-a6e4-459d-bd80-8e9d9e8bc91d",
      "name": "4\ufe0f\u20e3 \ud83d\udcb3 Get Payment History",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "\ud83d\udcb3 PAYMENTS: Fetch recent payment history\n\nShows last 10 payments with:\n- tx_hash\n- amount_usd\n- status\n- timestamp\n- receiver",
      "position": [
        -608,
        176
      ],
      "parameters": {
        "url": "={{ $('2\ufe0f\u20e3 Load Config').first().json.config.mcp_endpoint }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"jsonrpc\": \"2.0\",\n  \"id\": 1,\n  \"method\": \"tools/call\",\n  \"params\": {\n    \"name\": \"agentpay_get_payment_history\",\n    \"arguments\": {\n      \"limit\": {{ $('2\ufe0f\u20e3 Load Config').first().json.config.payment_history_limit }}\n    }\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "x-api-key",
              "value": "={{ $('2\ufe0f\u20e3 Load Config').first().json.config.api_key }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "b0e7f80b-cc9b-4976-93e9-597b39c27955",
      "name": "5\ufe0f\u20e3 \ud83d\udccb Get Audit Logs (24h)",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "\ud83d\udccb AUDIT: Fetch payment events by wallet\n\nFiltered by:\n- client_id (wallet address)\n- event_type: x402_payment_settled\n- Last 24 hours\n- Max 50 events\n\nShows: blockchain payments from this wallet",
      "position": [
        -384,
        176
      ],
      "parameters": {
        "url": "={{ $('2\ufe0f\u20e3 Load Config').first().json.config.api_url }}/audit/logs?client_id={{ $('2\ufe0f\u20e3 Load Config').first().json.config.buyer_wallet }}&event_type=x402_payment_settled&hours={{ $('2\ufe0f\u20e3 Load Config').first().json.config.time_range_hours }}&limit={{ $('2\ufe0f\u20e3 Load Config').first().json.config.audit_log_limit }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "={{ $('2\ufe0f\u20e3 Load Config').first().json.config.api_key }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "f9b85f1e-93c9-4e3b-b216-5340ad1c8990",
      "name": "6\ufe0f\u20e3 \ud83d\udd11 Get Active Mandates",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "\ud83d\udd11 MANDATES: Fetch all issued mandates\n\nShows:\n- mandate_id\n- budget_usd\n- budget_remaining\n- ttl_hours\n- scope\n- status",
      "position": [
        -160,
        176
      ],
      "parameters": {
        "url": "={{ $('2\ufe0f\u20e3 Load Config').first().json.config.api_url }}/audit/logs?client_id={{ $('2\ufe0f\u20e3 Load Config').first().json.config.user_email }}&event_type=mandate_issued",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "={{ $('2\ufe0f\u20e3 Load Config').first().json.config.api_key }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "fdac1867-7530-45fc-9fe4-57dad4a03ca1",
      "name": "7\ufe0f\u20e3 \ud83d\udd0d Prepare Verification",
      "type": "n8n-nodes-base.code",
      "notes": "\ud83d\udd0d PREPARE: Check if we have tx_hash to verify",
      "position": [
        48,
        176
      ],
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// VERIFICATION: Verify last payment on blockchain\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst config = $('2\ufe0f\u20e3 Load Config').first().json.config;\nconst tx_hash = config.tx_hash;\n\nif (!tx_hash) {\n  console.log('\u26a0\ufe0f  No tx_hash provided - skipping verification');\n  return [{ json: { \n    verified: false, \n    reason: \"No transaction hash provided\",\n    config: config\n  }}];\n}\n\nconsole.log(`\ud83d\udd0d Verifying payment: ${tx_hash}`);\n\nreturn [{ json: { \n  tx_hash: tx_hash,\n  config: config,\n  should_verify: true\n}}];"
      },
      "typeVersion": 2
    },
    {
      "id": "4fa77ac5-21c4-4bbc-af94-b706b61435ef",
      "name": "7B\ufe0f\u20e3 Has TX Hash?",
      "type": "n8n-nodes-base.if",
      "notes": "\ud83d\udd00 ROUTER: Only verify if tx_hash exists",
      "position": [
        272,
        176
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "should-verify",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.should_verify }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "22fa056e-43cc-4bc1-8af9-070df4f8183a",
      "name": "8\ufe0f\u20e3 \u2705 Verify on Blockchain",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "\u2705 BLOCKCHAIN: Verify payment on-chain\n\nChecks:\n- Transaction exists\n- Correct amount\n- Correct recipient\n- Block confirmation",
      "position": [
        496,
        80
      ],
      "parameters": {
        "url": "={{ $('2\ufe0f\u20e3 Load Config').first().json.config.api_url }}/v1/payments/verify/{{ $json.tx_hash }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "={{ $('2\ufe0f\u20e3 Load Config').first().json.config.api_key }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "b6529d72-e14e-4f99-ab90-583f3ce3975a",
      "name": "8B\ufe0f\u20e3 Skip Verification",
      "type": "n8n-nodes-base.code",
      "notes": "\u23ed\ufe0f  SKIP: No tx_hash to verify",
      "position": [
        496,
        288
      ],
      "parameters": {
        "jsCode": "return [{ json: { \n  verified: false,\n  reason: \"No transaction to verify\",\n  message: \"Skipped verification - no tx_hash provided\"\n}}];"
      },
      "typeVersion": 2
    },
    {
      "id": "3d0ec196-1e34-4b77-bb6f-7fed3bf6fc3e",
      "name": "9\ufe0f\u20e3 Merge Verification",
      "type": "n8n-nodes-base.merge",
      "notes": "\ud83d\udd00 MERGE: Combine verified/skipped paths",
      "position": [
        720,
        176
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combinationMode": "mergeByPosition"
      },
      "typeVersion": 2.1
    },
    {
      "id": "e7f766f0-f856-4a61-9303-ec03f4fd581a",
      "name": "\ud83d\udd1f \ud83d\udcca Calculate Statistics",
      "type": "n8n-nodes-base.code",
      "notes": "\ud83d\udcca STATISTICS: Calculate trends and metrics\n\nCalculates:\n- Spending trends\n- Budget utilization %\n- Recent activity (24h)\n- Mandate status\n- Event breakdown",
      "position": [
        928,
        176
      ],
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// STATISTICS: Calculate spending trends and alerts\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst config = $('2\ufe0f\u20e3 Load Config').first().json.config;\nconst analytics = $('3\ufe0f\u20e3 \ud83d\udcc8 Get User Analytics').first().json;\nconst payment_history_response = $('4\ufe0f\u20e3 \ud83d\udcb3 Get Payment History').first().json;\nconst audit_logs_response = $('5\ufe0f\u20e3 \ud83d\udccb Get Audit Logs (24h)').first().json;\nconst mandates_response = $('6\ufe0f\u20e3 \ud83d\udd11 Get Active Mandates').first().json;\nconst verification = $input.first().json;\n\nconsole.log('\ud83d\udcca Calculating statistics...');\n\n// Parse payment history (MCP response)\nlet payments = [];\nif (payment_history_response.result && payment_history_response.result.content) {\n  try {\n    const content = payment_history_response.result.content[0].text;\n    const parsed = JSON.parse(content);\n    payments = parsed.payments || [];\n  } catch (e) {\n    console.log('\u26a0\ufe0f  Could not parse payment history');\n  }\n}\n\n// Parse audit logs\nconst logs = audit_logs_response.logs || [];\n\n// Parse mandates\nconst mandates = mandates_response.logs || [];\n\n// \u2705 FIX: Use correct API field names and calculate average AFTER getting values\n// API returns: total_spent_usd, transaction_count (NOT payment_count)\nconst total_spent = analytics.total_spent_usd || 0;\nconst payment_count = analytics.transaction_count || 0;  // \u2705 FIXED: was analytics.payment_count\nconst average_payment = payment_count > 0 ? (total_spent / payment_count) : 0;  // \u2705 Calculate after\n\nconst stats = {\n  // Spending stats - FIXED field names to match API response\n  total_spent: total_spent,\n  payment_count: payment_count,\n  average_payment: average_payment,\n\n  // Recent activity\n  payments_last_24h: payments.filter(p => {\n    const paymentTime = new Date(p.timestamp || p.created_at);\n    const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);\n    return paymentTime > oneDayAgo;\n  }).length,\n\n  spent_last_24h: payments.filter(p => {\n    const paymentTime = new Date(p.timestamp || p.created_at);\n    const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);\n    return paymentTime > oneDayAgo;\n  }).reduce((sum, p) => sum + parseFloat(p.amount_usd || 0), 0),\n\n  // Mandate stats\n  active_mandates: mandates.filter(m => {\n    const details = typeof m.details === 'string' ? JSON.parse(m.details) : m.details;\n    return details.status === 'active' || details.status === 'issued';\n  }).length,\n\n  total_budget: mandates.reduce((sum, m) => {\n    const details = typeof m.details === 'string' ? JSON.parse(m.details) : m.details;\n    return sum + parseFloat(details.budget_usd || 0);\n  }, 0),\n\n  budget_remaining: mandates.reduce((sum, m) => {\n    const details = typeof m.details === 'string' ? JSON.parse(m.details) : m.details;\n    return sum + parseFloat(details.budget_remaining || 0);\n  }, 0),\n\n  // Audit log stats\n  total_events_24h: logs.length,\n  payment_events: logs.filter(l => l.event_type && l.event_type.includes('payment')).length,\n  mandate_events: logs.filter(l => l.event_type && l.event_type.includes('mandate')).length,\n  aif_events: logs.filter(l => l.event_type && l.event_type.includes('aif')).length,\n\n  // Most recent payment\n  last_payment: payments.length > 0 ? payments[0] : null,\n\n  // Verification status\n  last_payment_verified: verification.verified || false\n};\n\n// Calculate budget utilization\nstats.budget_utilization_pct = stats.total_budget > 0\n  ? ((stats.total_budget - stats.budget_remaining) / stats.total_budget * 100).toFixed(2)\n  : 0;\n\n// Spending trend (compare last 24h to average)\nstats.spending_trend = stats.payment_count > 0\n  ? (stats.spent_last_24h > stats.average_payment ? 'increasing' : 'stable')\n  : 'no_activity';\n\nconsole.log(`   Total Spent: $${stats.total_spent}`);\nconsole.log(`   Payments (24h): ${stats.payments_last_24h}`);\nconsole.log(`   Budget Remaining: $${stats.budget_remaining}`);\nconsole.log(`   Budget Utilization: ${stats.budget_utilization_pct}%`);\n\nreturn [{ json: { config, analytics, stats, payments, logs, mandates, verification } }];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "37d17b89-9df7-473d-9a55-2710f48d69b7",
      "name": "1\ufe0f\u20e31\ufe0f\u20e3 \ud83d\udea8 Check Alerts",
      "type": "n8n-nodes-base.code",
      "notes": "\ud83d\udea8 ALERTS: Check for warnings\n\nChecks:\n- Budget < 10% remaining\n- Mandate expires < 24h\n- Failed payments\n- High spending rate\n- No activity in 24h",
      "position": [
        1152,
        176
      ],
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// ALERTS: Check for warnings and important notifications\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst data = $input.first().json;\nconst { stats, mandates, payments } = data;\n\nconst alerts = [];\n\n// Alert 1: Low budget warning\nif (stats.budget_remaining > 0 && stats.budget_utilization_pct > 90) {\n  alerts.push({\n    severity: 'high',\n    type: 'budget_low',\n    message: `\u26a0\ufe0f  BUDGET WARNING: Only $${stats.budget_remaining.toFixed(2)} remaining (${stats.budget_utilization_pct}% used)`,\n    action: 'Issue new mandate or reduce spending'\n  });\n} else if (stats.budget_remaining > 0 && stats.budget_utilization_pct > 75) {\n  alerts.push({\n    severity: 'medium',\n    type: 'budget_warning',\n    message: `\u2139\ufe0f  Budget Notice: $${stats.budget_remaining.toFixed(2)} remaining (${stats.budget_utilization_pct}% used)`,\n    action: 'Monitor spending'\n  });\n}\n\n// Alert 2: Mandate expiration warning\nmandates.forEach(m => {\n  const details = typeof m.details === 'string' ? JSON.parse(m.details) : m.details;\n  if (details.ttl_remaining_hours && details.ttl_remaining_hours < 24) {\n    alerts.push({\n      severity: 'high',\n      type: 'mandate_expiring',\n      message: `\u23f0 MANDATE EXPIRING: ${details.mandate_id} expires in ${details.ttl_remaining_hours} hours`,\n      action: 'Renew mandate before expiration'\n    });\n  }\n});\n\n// Alert 3: No recent activity\nif (stats.payments_last_24h === 0 && stats.payment_count > 0) {\n  alerts.push({\n    severity: 'low',\n    type: 'no_activity',\n    message: '\u2139\ufe0f  No payments in last 24 hours',\n    action: 'Normal - no action needed'\n  });\n}\n\n// Alert 4: Failed payments\nconst failed_payments = payments.filter(p => p.status === 'failed');\nif (failed_payments.length > 0) {\n  alerts.push({\n    severity: 'high',\n    type: 'payment_failures',\n    message: `\u274c FAILED PAYMENTS: ${failed_payments.length} payment(s) failed`,\n    action: 'Review failed transactions',\n    failed_txs: failed_payments.map(p => p.tx_hash)\n  });\n}\n\n// Alert 5: High spending rate\nif (stats.spent_last_24h > stats.average_payment * 10 && stats.payment_count > 10) {\n  alerts.push({\n    severity: 'medium',\n    type: 'high_spending',\n    message: `\ud83d\udcc8 High Spending: $${stats.spent_last_24h.toFixed(2)} spent in 24h (10x average)`,\n    action: 'Verify spending is intentional'\n  });\n}\n\n// Alert 6: Verification failure\nif (data.verification && !data.verification.verified && data.config.tx_hash) {\n  alerts.push({\n    severity: 'medium',\n    type: 'verification_failed',\n    message: `\u26a0\ufe0f  Payment verification issue: ${data.verification.reason || 'Unknown'}`,\n    action: 'Check transaction on blockchain explorer'\n  });\n}\n\nconsole.log(`\ud83d\udea8 Alerts: ${alerts.length} alert(s)`);\nalerts.forEach((a, i) => {\n  console.log(`   ${i+1}. [${a.severity.toUpperCase()}] ${a.message}`);\n});\n\nreturn [{ json: { ...data, alerts } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "d346a783-2709-43ff-a8f5-be4122426660",
      "name": "1\ufe0f\u20e32\ufe0f\u20e3 \ud83d\udcf1 Format Dashboard",
      "type": "n8n-nodes-base.code",
      "notes": "\ud83d\udcf1 DASHBOARD: Format metrics for display\n\nCreates:\n- Key metrics cards\n- Alert summary\n- Quick stats\n- Links to full dashboard\n- Export options",
      "position": [
        1376,
        176
      ],
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// DASHBOARD DATA: Format metrics for hybrid display\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst data = $input.first().json;\nconst { config, analytics, stats, alerts } = data;\n\n// Create dashboard-ready data structure\nconst dashboard = {\n  // Header\n  title: \"\ud83d\udcca Buyer Monitoring Dashboard\",\n  user: config.user_email,\n  generated_at: new Date().toISOString(),\n  session_id: config.session.id,\n  \n  // Key metrics (shown in N8N)\n  metrics: {\n    total_spent: {\n      value: `$${stats.total_spent.toFixed(2)}`,\n      label: \"Total Spent\",\n      icon: \"\ud83d\udcb0\"\n    },\n    payment_count: {\n      value: stats.payment_count,\n      label: \"Total Payments\",\n      icon: \"\ud83d\udcb3\"\n    },\n    budget_remaining: {\n      value: `$${stats.budget_remaining.toFixed(2)}`,\n      label: \"Budget Remaining\",\n      icon: \"\ud83d\udd11\",\n      percentage: `${stats.budget_utilization_pct}% used`\n    },\n    active_mandates: {\n      value: stats.active_mandates,\n      label: \"Active Mandates\",\n      icon: \"\ud83c\udfab\"\n    },\n    payments_24h: {\n      value: stats.payments_last_24h,\n      label: \"Payments (24h)\",\n      icon: \"\ud83d\udcc8\",\n      amount: `$${stats.spent_last_24h.toFixed(2)}`\n    },\n    events_24h: {\n      value: stats.total_events_24h,\n      label: \"Events Logged (24h)\",\n      icon: \"\ud83d\udccb\"\n    }\n  },\n  \n  // Alerts summary\n  alerts_summary: {\n    count: alerts.length,\n    high: alerts.filter(a => a.severity === 'high').length,\n    medium: alerts.filter(a => a.severity === 'medium').length,\n    low: alerts.filter(a => a.severity === 'low').length,\n    items: alerts\n  },\n  \n  // Quick stats\n  quick_stats: {\n    average_payment: `$${stats.average_payment.toFixed(2)}`,\n    spending_trend: stats.spending_trend,\n    budget_utilization: `${stats.budget_utilization_pct}%`,\n    last_payment_verified: stats.last_payment_verified ? '\u2705 Verified' : '\u23f3 Pending'\n  },\n  \n  // Links\n  links: {\n    user_analytics: `${config.api_url}/v1/analytics/me`,\n    audit_logs: `${config.api_url}/audit/logs?client_id=${config.user_email}`,\n    payment_history: `${config.api_url}/v1/payments/list`\n  },\n  \n  // Export options\n  export: {\n    csv_available: true,\n    json_available: true,\n    pdf_available: false\n  }\n};\n\nconsole.log('\ud83d\udcca Dashboard data prepared');\nconsole.log(`   Metrics: ${Object.keys(dashboard.metrics).length}`);\nconsole.log(`   Alerts: ${dashboard.alerts_summary.count}`);\n\nreturn [{ json: { ...data, dashboard } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "0a268443-15a8-4d1e-9acf-ba99eabe6173",
      "name": "1\ufe0f\u20e33\ufe0f\u20e3 \ud83d\udcc4 Generate CSV Export",
      "type": "n8n-nodes-base.code",
      "notes": "\ud83d\udcc4 EXPORT: Generate CSV report\n\nIncludes:\n- Summary metrics\n- Alerts\n- Payment history (last 10)\n- Active mandates\n- Event summary\n\nCopy csv_export field to save",
      "position": [
        1600,
        176
      ],
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// CSV EXPORT: Generate downloadable CSV report\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst data = $input.first().json;\nconst { config, stats, payments, logs, mandates, alerts } = data;\n\n// CSV Header\nlet csv = \"AgentGatePay Buyer Monitoring Report\\n\";\ncsv += `Generated: ${new Date().toISOString()}\\n`;\ncsv += `User: ${config.user_email}\\n`;\ncsv += `\\n`;\n\n// Summary section\ncsv += \"SUMMARY\\n\";\ncsv += \"Metric,Value\\n\";\ncsv += `Total Spent,$${stats.total_spent}\\n`;\ncsv += `Payment Count,${stats.payment_count}\\n`;\ncsv += `Average Payment,$${stats.average_payment}\\n`;\ncsv += `Budget Remaining,$${stats.budget_remaining}\\n`;\ncsv += `Budget Utilization,${stats.budget_utilization_pct}%\\n`;\ncsv += `Active Mandates,${stats.active_mandates}\\n`;\ncsv += `Payments (24h),${stats.payments_last_24h}\\n`;\ncsv += `Spent (24h),$${stats.spent_last_24h}\\n`;\ncsv += `\\n`;\n\n// Alerts section\nif (alerts.length > 0) {\n  csv += \"ALERTS\\n\";\n  csv += \"Severity,Type,Message,Action\\n\";\n  alerts.forEach(a => {\n    csv += `${a.severity},${a.type},\"${a.message}\",\"${a.action}\"\\n`;\n  });\n  csv += `\\n`;\n}\n\n// Payment history - MERCHANT PAYMENTS\ncsv += \"MERCHANT PAYMENTS (Last 20)\\n\";\ncsv += \"Timestamp,TX Hash,Amount USD,Status,Merchant Address\\n\";\nconst merchant_logs = logs.filter(log => log.event_type === 'x402_payment_settled');\nmerchant_logs.slice(0, 20).forEach(log => {\n  const details = log.details;\n  csv += `${new Date(details.timestamp * 1000).toISOString()},${details.tx_hash},$${details.amount_usd},${details.status || 'completed'},${details.receiver_address}\\n`;\n});\ncsv += `\\n`;\n\n// COMMISSION PAYMENTS\ncsv += \"COMMISSION PAYMENTS (Last 20)\\n\";\ncsv += \"Timestamp,TX Hash,Amount USD,Status,Gateway Address\\n\";\nconst commission_logs = logs.filter(log => log.event_type === 'x402_payment_settled' && log.details.commission_tx_hash);\ncommission_logs.slice(0, 20).forEach(log => {\n  const details = log.details;\n  csv += `${new Date(details.timestamp * 1000).toISOString()},${details.commission_tx_hash},$${details.commission_amount_usd || 0},${details.status || 'completed'},${details.commission_address}\\n`;\n});\ncsv += `\\n`;\n\n// Mandate summary\nif (mandates.length > 0) {\n  csv += \"ACTIVE MANDATES\\n\";\n  csv += \"Mandate ID,Budget USD,Remaining USD,TTL Hours,Status\\n\";\n  mandates.forEach(m => {\n    const details = typeof m.details === 'string' ? JSON.parse(m.details) : m.details;\n    csv += `${details.mandate_id || 'N/A'},$${details.budget_usd || 0},$${details.budget_remaining || 0},${details.ttl_remaining_hours || 'N/A'},${details.status || 'N/A'}\\n`;\n  });\n  csv += `\\n`;\n}\n\n// Event summary\ncsv += \"EVENT SUMMARY (24h)\\n\";\ncsv += \"Category,Count\\n\";\ncsv += `Total Events,${stats.total_events_24h}\\n`;\ncsv += `Payment Events,${stats.payment_events}\\n`;\ncsv += `Mandate Events,${stats.mandate_events}\\n`;\ncsv += `AIF Security Events,${stats.aif_events}\\n`;\n\nconsole.log('\ud83d\udcc4 CSV export generated');\nconsole.log(`   Size: ${csv.length} characters`);\n\nreturn [{ json: { ...data, csv_export: csv } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "9256806d-83ef-44c9-8480-e950a9a3b08f",
      "name": "1\ufe0f\u20e34\ufe0f\u20e3 \ud83d\udccb Final Report",
      "type": "n8n-nodes-base.code",
      "notes": "\ud83d\udccb FINAL REPORT: Complete formatted output\n\nIncludes:\n- Key metrics summary\n- Alerts and warnings\n- Spending analysis\n- Recent payments\n- Active mandates\n- Event activity\n- Dashboard links (hybrid)\n- Export options\n\n\u2705 This is the final output!",
      "position": [
        1808,
        176
      ],
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// FINAL REPORT: Beautiful formatted output with CORRECT calculations\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst data = $input.first().json;\nconst { config, stats, alerts, logs, mandates } = data;\n\n// \u2705 FIX: Extract ALL payment events from audit logs\nconst payment_logs = logs.filter(log =>\n  log.event_type === 'x402_payment_settled' ||\n  log.event_type === 'x402_commission_collected'\n);\n\n// \u2705 FIX: Extract commission data EMBEDDED within payment_settled events\n// Commission info is in same event as merchant payment, not separate events\nconst commission_payments = logs\n  .filter(log => log.event_type === 'x402_payment_settled' && log.details.commission_tx_hash)\n  .map(log => ({\n    timestamp: new Date(log.details.timestamp * 1000).toISOString(),\n    amount_usd: log.details.commission_amount_usd || 0,\n    status: log.details.status || 'completed',\n    tx_hash: log.details.commission_tx_hash,\n    type: 'commission',\n    receiver: log.details.commission_address,\n    payer: log.details.payer_address || log.details.sender_address,\n    explorer: log.details.commission_explorer_url || `https://basescan.org/tx/${log.details.commission_tx_hash}`\n  }));\n\nconst merchant_payments = logs\n  .filter(log => log.event_type === 'x402_payment_settled' && log.details.merchant_tx_hash)\n  .map(log => ({\n    timestamp: new Date(log.details.timestamp * 1000).toISOString(),\n    amount_usd: log.details.merchant_amount_usd || log.details.amount_usd,\n    status: log.details.status || 'completed',\n    tx_hash: log.details.merchant_tx_hash || log.details.tx_hash,\n    type: 'merchant',\n    receiver: log.details.merchant_address || log.details.receiver_address,\n    payer: log.details.payer_address || log.details.sender_address,\n    explorer: log.details.merchant_explorer_url || log.details.explorer_url || `https://basescan.org/tx/${log.details.merchant_tx_hash || log.details.tx_hash}`\n  }));\n\n// Calculate REAL total spent (commission / 0.005 to get original amount)\n// If commission is $0.00995 and rate is 0.5%, original payment was $0.00995 / 0.005 = $1.99\nconst commission_rate = 0.005; // 0.5%\nconst total_commission = commission_payments.reduce((sum, p) => sum + p.amount_usd, 0);\nconst total_merchant = merchant_payments.reduce((sum, p) => sum + p.amount_usd, 0);\n\n// Total spent = commission + merchant payments (or commission / rate if merchant data missing)\nlet total_spent;\nif (merchant_payments.length > 0) {\n  total_spent = total_commission + total_merchant;\n} else {\n  // Calculate from commission only\n  total_spent = total_commission / commission_rate;\n}\n\nconst payment_count = Math.max(commission_payments.length, merchant_payments.length);\nconst average_payment = payment_count > 0 ? total_spent / payment_count : 0;\n\n// Calculate last 24h activity\nconst oneDayAgo = Date.now() - 24 * 60 * 60 * 1000;\nconst recent_commissions = commission_payments.filter(p => new Date(p.timestamp).getTime() > oneDayAgo);\nconst recent_merchants = merchant_payments.filter(p => new Date(p.timestamp).getTime() > oneDayAgo);\nconst payments_24h_count = Math.max(recent_commissions.length, recent_merchants.length);\nconst spent_24h = (recent_commissions.reduce((sum, p) => sum + p.amount_usd, 0) +\n                   recent_merchants.reduce((sum, p) => sum + p.amount_usd, 0)) ||\n                   (recent_commissions.reduce((sum, p) => sum + p.amount_usd, 0) / commission_rate);\n\n// \u2705 FIX: Calculate CORRECT budget remaining\n// Get total budget from mandates\nconst total_budget = mandates && mandates.length > 0\n  ? mandates.reduce((sum, m) => {\n      const details = typeof m.details === 'string' ? JSON.parse(m.details) : m.details;\n      return sum + (parseFloat(details.budget_usd) || 0);\n    }, 0)\n  : 100; // Default if no mandates\n\nconst budget_remaining = total_budget - total_spent;\nconst budget_utilization_pct = total_budget > 0 ? ((total_spent / total_budget) * 100).toFixed(2) : 0;\n\n// Combine payments for display (grouped by transaction)\nconst all_payments = [];\nconst processed_timestamps = new Set();\n\ncommission_payments.forEach(comm => {\n  const merch = merchant_payments.find(m =>\n    Math.abs(new Date(m.timestamp).getTime() - new Date(comm.timestamp).getTime()) < 5000\n  );\n\n  if (!processed_timestamps.has(comm.timestamp)) {\n    all_payments.push({\n      timestamp: comm.timestamp,\n      total_amount: merch ? comm.amount_usd + merch.amount_usd : comm.amount_usd / commission_rate,\n      commission: comm.amount_usd,\n      merchant_amount: merch ? merch.amount_usd : (comm.amount_usd / commission_rate) - comm.amount_usd,\n      commission_tx: comm.tx_hash,\n      merchant_tx: merch ? merch.tx_hash : 'N/A',\n      status: comm.status,\n      merchant_address: merch ? merch.receiver : 'N/A'\n    });\n    processed_timestamps.add(comm.timestamp);\n  }\n});\n\n// Build dashboard object with CORRECT values\nconst dashboard = {\n  metrics: {\n    total_spent: {\n      value: `$${total_spent.toFixed(2)}`,\n      label: \"Total Spent\",\n      icon: \"\ud83d\udcb0\"\n    },\n    payment_count: {\n      value: payment_count,\n      label: \"Total Payments\",\n      icon: \"\ud83d\udcb3\"\n    },\n    budget_remaining: {\n      value: `$${budget_remaining.toFixed(2)}`,\n      label: \"Budget Remaining\",\n      icon: \"\ud83d\udd11\",\n      percentage: `${budget_utilization_pct}% used`\n    },\n    active_mandates: {\n      value: stats.active_mandates,\n      label: \"Active Mandates\",\n      icon: \"\ud83c\udfab\"\n    },\n    payments_24h: {\n      value: payments_24h_count,\n      label: \"Payments (24h)\",\n      icon: \"\ud83d\udcc8\",\n      amount: `$${spent_24h.toFixed(2)}`\n    },\n    events_24h: {\n      value: stats.total_events_24h,\n      label: \"Events Logged (24h)\",\n      icon: \"\ud83d\udccb\"\n    }\n  },\n  alerts_summary: {\n    count: alerts.length,\n    high: alerts.filter(a => a.severity === 'high').length,\n    medium: alerts.filter(a => a.severity === 'medium').length,\n    low: alerts.filter(a => a.severity === 'low').length,\n    items: alerts\n  },\n  quick_stats: {\n    average_payment: `$${average_payment.toFixed(2)}`,\n    spending_trend: spent_24h > average_payment ? 'increasing' : 'stable',\n    budget_utilization: `${budget_utilization_pct}%`,\n    last_payment_verified: \"\u2705 Verified\"\n  },\n  links: {\n    user_analytics: `${config.api_url}/v1/analytics/me`,\n    audit_logs: `${config.api_url}/audit/logs?client_id=${config.buyer_wallet || config.user_email}`,\n    payment_history: `${config.api_url}/v1/payments/list`\n  }\n};\n\n// Update stats with CORRECT values\nstats.total_spent = total_spent;\nstats.payment_count = payment_count;\nstats.average_payment = average_payment;\nstats.payments_last_24h = payments_24h_count;\nstats.spent_last_24h = spent_24h;\nstats.budget_remaining = budget_remaining;\nstats.budget_utilization_pct = budget_utilization_pct;\nstats.spending_trend = dashboard.quick_stats.spending_trend;\n\n// Build formatted report (ORIGINAL FORMAT)\nconst report = {\n  // Header\n  \"\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\": \"\",\n  \"\ud83c\udfaf AGENTGATEPAY BUYER MONITORING DASHBOARD\": \"\",\n  \"\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550_\": \"\",\n\n  user: config.user_email,\n  generated: new Date().toISOString(),\n  session_id: config.session?.id || 'N/A',\n  trigger_source: config.trigger_source || 'manual',\n\n  \"\\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\": \"\",\n  \"\ud83d\udcca KEY METRICS\": \"\",\n  \"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501_\": \"\",\n\n  metrics: dashboard.metrics,\n\n  \"\\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501__\": \"\",\n  \"\ud83d\udea8 ALERTS & WARNINGS\": \"\",\n  \"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501___\": \"\",\n\n  alerts_count: `${alerts.length} alert(s) - ${dashboard.alerts_summary.high} high, ${dashboard.alerts_summary.medium} medium, ${dashboard.alerts_summary.low} low`,\n  alerts: alerts.length > 0 ? alerts : [{ message: \"\u2705 No alerts - all systems normal\" }],\n\n  \"\\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501____\": \"\",\n  \"\ud83d\udcc8 SPENDING ANALYSIS\": \"\",\n  \"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501_____\": \"\",\n\n  spending_analysis: {\n    total_spent: `$${stats.total_spent.toFixed(2)} USD`,\n    payments_count: stats.payment_count,\n    average_payment: `$${stats.average_payment.toFixed(2)} USD`,\n    last_24h: `${stats.payments_last_24h} payments ($${stats.spent_last_24h.toFixed(2)} USD)`,\n    trend: stats.spending_trend,\n    budget_utilization: `${stats.budget_utilization_pct}% used`,\n    budget_remaining: `$${stats.budget_remaining.toFixed(2)} USD`\n  },\n\n  \"\\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501______\": \"\",\n  \"\ud83d\udcb3 PAYMENTS TO MERCHANTS/AGENTS (Last 20)\": \"\",\n  \"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501_______\": \"\",\n\n  merchant_payments: merchant_payments.slice(0, 20).map(p => ({\n    timestamp: p.timestamp,\n    amount_paid: `$${p.amount_usd.toFixed(4)} USD`,\n    merchant_address: p.receiver,\n    tx_hash: p.tx_hash,\n    status: p.status,\n    explorer: p.explorer || `https://basescan.org/tx/${p.tx_hash}`\n  })),\n\n  \"\\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501________\": \"\",\n  \"\ud83d\udcb0 GATEWAY COMMISSION PAYMENTS (Last 20)\": \"\",\n  \"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501_________\": \"\",\n\n  commission_payments_list: commission_payments.slice(0, 20).map(p => ({\n    timestamp: p.timestamp,\n    commission: `$${p.amount_usd.toFixed(4)} USD (0.5%)`,\n    gateway_address: p.receiver,\n    tx_hash: p.tx_hash,\n    status: p.status,\n    explorer: p.explorer || `https://basescan.org/tx/${p.tx_hash}`\n  })),\n\n  \"\\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501________\": \"\",\n  \"\ud83d\udd11 ACTIVE MANDATES\": \"\",\n  \"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501_________\": \"\",\n\n  mandates_summary: mandates && mandates.length > 0 ? mandates.map(m => {\n    const details = typeof m.details === 'string' ? JSON.parse(m.details) : m.details;\n\n    // \u2705 FIX: Calculate TTL and remaining budget correctly\n    let ttl_hours = details.ttl_remaining_hours;\n    if (!ttl_hours && details.expires_at) {\n      const now = Math.floor(Date.now() / 1000);\n      const expires = details.expires_at;\n      ttl_hours = Math.max(0, Math.floor((expires - now) / 3600));\n    }\n\n    // Calculate this mandate's remaining budget\n    const mandate_budget = parseFloat(details.budget_usd) || 0;\n    const mandate_spent = total_spent; // Simplified - assumes one mandate\n    const mandate_remaining = mandate_budget - mandate_spent;\n\n    return {\n      mandate_id: details.mandate_id,\n      budget: `$${mandate_budget.toFixed(2)} USD ($${mandate_remaining.toFixed(2)} USD remaining)`,\n      ttl: ttl_hours ? `${ttl_hours} hours` : 'expired',\n      status: details.status\n    };\n  }) : [{ message: \"No active mandates\" }],\n\n  \"\\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501__________\": \"\",\n  \"\ud83d\udcca EVENT ACTIVITY (24h)\": \"\",\n  \"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501___________\": \"\",\n\n  event_activity: {\n    total_events: stats.total_events_24h,\n    payment_events: stats.payment_events,\n    commission_events: commission_payments.length,\n    mandate_events: stats.mandate_events,\n    aif_security_events: stats.aif_events\n  },\n\n  \"\\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501____________\": \"\",\n  \"\ud83d\udd0d SEARCH YOUR LOGS - COPY & PASTE CURL COMMANDS\": \"\",\n  \"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501_____________\": \"\",\n\n  search_commands: {\n    \"\ud83d\udcc5 Last 24 hours\": `curl '${config.api_url}/audit/logs?client_id=${config.buyer_wallet || config.user_email}&hours=24' -H 'x-api-key: ${config.api_key}'`,\n\n    \"\ud83d\udcc5 Last 7 days\": `curl '${config.api_url}/audit/logs?client_id=${config.buyer_wallet || config.user_email}&hours=168' -H 'x-api-key: ${config.api_key}'`,\n\n    \"\ud83d\udcb3 Payment events\": `curl '${config.api_url}/audit/logs?client_id=${config.buyer_wallet || config.user_email}&event_type=x402_payment_settled' -H 'x-api-key: ${config.api_key}'`,\n\n    \"\ud83d\udcb0 Commission events\": `curl '${config.api_url}/audit/logs?client_id=${config.buyer_wallet || config.user_email}&event_type=x402_commission_collected' -H 'x-api-key: ${config.api_key}'`,\n\n    \"\ud83d\udd11 Mandate events\": `curl '${config.api_url}/audit/logs?client_id=${config.buyer_wallet || config.user_email}&event_type=mandate_issued' -H 'x-api-key: ${config.api_key}'`,\n\n    \"\ud83d\udcca Analytics\": `curl '${config.api_url}/v1/analytics/me' -H 'x-api-key: ${config.api_key}'`\n  },\n\n  \"\\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501______________\": \"\",\n  \"\ud83d\udd17 API ENDPOINTS\": \"\",\n  \"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501_______________\": \"\",\n\n  api_endpoints: {\n    \"\ud83d\udcca User Analytics\": dashboard.links.user_analytics,\n    \"\ud83d\udccb Audit Logs\": dashboard.links.audit_logs,\n    \"\ud83d\udcb3 Payment History\": dashboard.links.payment_history,\n    \"\ud83d\udca1 How to use\": \"Add header: x-api-key: \" + config.api_key\n  },\n\n  \"\\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501________________\": \"\",\n  \"\ud83d\udce5 EXPORT OPTIONS\": \"\",\n  \"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501_________________\": \"\",\n\n  export_options: {\n    \"\ud83d\udcc4 CSV Export\": \"See 'csv_export' field in raw_data\",\n    \"\ud83d\udce6 JSON Export\": \"This complete JSON output\",\n    \"\ud83d\udcca How to View\": \"Use curl commands above to fetch your data\"\n  },\n\n  \"\\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550__________________\": \"\",\n  \"\u2705 MONITORING COMPLETE\": \"\",\n  \"\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550___________________\": \"\",\n\n  summary: `Monitored ${stats.payment_count} payments, $${stats.total_spent.toFixed(2)} USD spent (incl. $${total_commission.toFixed(4)} commission), ${alerts.length} alert(s), ${stats.active_mandates} active mandate(s)`,\n\n  next_steps: alerts.length > 0\n    ? \"\u26a0\ufe0f  Review alerts above and take recommended actions\"\n    : \"\u2705 All systems normal - no action required\"\n};\n\nconsole.log('\u2705 Final report generated');\nconsole.log(`   Total Spent: $${stats.total_spent.toFixed(2)} USD`);\nconsole.log(`   Commission: $${total_commission.toFixed(4)} USD`);\nconsole.log(`   To Merchants: $${total_merchant > 0 ? total_merchant.toFixed(4) : (total_spent - total_commission).toFixed(4)} USD`);\nconsole.log(`   Payments: ${stats.payment_count}`);\nconsole.log(`   Budget Remaining: $${stats.budget_remaining.toFixed(2)} USD`);\n\n// Remove duplicate dashboard from raw_data (already shown in report metrics)\ndelete data.dashboard;\n\nreturn [{ json: { report, raw_data: data } }];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "8b215841-6522-41fd-953c-0e3bf9c6c11f",
      "name": "START HERE",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1840,
        16
      ],
      "parameters": {
        "color": 4,
        "width": 500,
        "height": 640,
        "content": "# Buyer Monitoring Dashboard\n\n**What it does:** Shows your spending, payment history, mandates, and alerts.\n\n**Quick start:**\n1. Edit Node 2: Add your wallet address, email and API key\n2. Click Execute Workflow\n3. Check Node 14 for the full report\n\n**What you'll see:**\n- Total spent and payment count\n- Budget remaining from active mandates\n- Recent payments (last 50)\n- Alerts (low budget, failed payments, etc.)\n- Transaction verification status\n\n**Run it:** Manually anytime, or trigger from payment workflows for auto-monitoring\n\n**Export:** Node 13 has CSV data you can copy and save"
      },
      "typeVersion": 1
    },
    {
      "id": "884c3663-dc9a-443a-a486-57f5ab80968c",
      "name": "Sticky Note 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1312,
        16
      ],
      "parameters": {
        "color": 7,
        "width": 1280,
        "height": 424,
        "content": "## Data Collection\n\nFetches analytics, payment history, audit logs, and active mandates from AgentGatePay API. All data filtered by your wallet address."
      },
      "typeVersion": 1
    },
    {
      "id": "043b6ca6-3821-4d50-a9e3-d0c8d65a270f",
      "name": "Sticky Note 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 860,
        "height": 440,
        "content": "## Blockchain Verification\n\nIf you provide a tx_hash, verifies the payment on-chain. Otherwise skips and merges empty result. Helps confirm your latest transaction went through."
      },
      "typeVersion": 1
    },
    {
      "id": "fc1d6874-d725-4042-9a5d-82c5211540b3",
      "name": "Sticky Note 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 404,
        "height": 440,
        "content": "## Analysis & Alerts\n\nCalculates spending trends, budget utilization, and checks for issues. Alerts trigger when budget drops below 10% or mandates expire soon."
      },
      "typeVersion": 1
    },
    {
      "id": "3b6bdb16-9d3f-46d9-bfc4-4436fd4e4aa2",
      "name": "Sticky Note 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1296,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 680,
        "height": 440,
        "content": "## Output Generation\n\nFormats dashboard with key metrics, generates CSV export for spreadsheets, and creates the final report. Node 14 is your main output."
      },
      "typeVersion": 1
    },
    {
      "id": "7a70ac2e-0512-406f-993c-aab97e252e3e",
      "name": "3\ufe0f\u20e3 \ud83d\udcb0 Get Merchant Revenue",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "\ud83d\udcb0 REVENUE: Fetch merchant revenue stats\n\nReturns:\n- total_usd\n- count\n- average_usd\n- by_chain\n- by_token",
      "position": [
        -848,
        1040
      ],
      "parameters": {
        "url": "={{ $json.config.api_url }}/v1/merchant/revenue?wallet={{ $json.config.merchant_wallet }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "={{ $json.config.api_key }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "6168ab41-1222-41bf-9180-2e3258b82ccd",
      "name": "4\ufe0f\u20e3 \ud83d\udcb3 Get Payment List",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "\ud83d\udcb3 PAYMENTS: Fetch payments TO this merchant\n\nShows last 10 payments received:\n- tx_hash\n- amount_usd\n- status\n- timestamp\n- sender",
      "position": [
        -624,
        1040
      ],
      "parameters": {
        "url": "={{ $('2\ufe0f\u20e3 Load Config1').first().json.config.api_url }}/v1/payments/list?wallet={{ $('2\ufe0f\u20e3 Load Config1').first().json.config.merchant_wallet }}&limit={{ $('2\ufe0f\u20e3 Load Config1').first().json.config.payment_history_limit }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "={{ $('2\ufe0f\u20e3 Load Config1').first().json.config.api_key }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "7b552971-de04-43a2-b4cd-6702fe777ff6",
      "name": "5\ufe0f\u20e3 \ud83d\udd17 Get Webhooks",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "\ud83d\udd17 WEBHOOKS: Fetch configured webhooks\n\nShows:\n- webhook_id\n- url\n- events\n- status\n- delivery_count\n- failure_count",
      "position": [
        -400,
        1040
      ],
      "parameters": {
        "url": "={{ $('2\ufe0f\u20e3 Load Config1').first().json.config.api_url }}/v1/webhooks/list",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "={{ $('2\ufe0f\u20e3 Load Config1').first().json.config.api_key }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "14e2d4c3-8e9d-4899-9f50-bb18c719cefe",
      "name": "6\ufe0f\u20e3 \ud83d\udccb Get Audit Logs (24h)",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "\ud83d\udccb AUDIT: Fetch payment events (24h)\n\nFiltered by:\n- event_type: x402_payment_settled\n- Last 24 hours\n- Max 50 events\n\nShows: payments received",
      "position": [
        -176,
        1040
      ],
      "parameters": {
        "url": "={{ $('2\ufe0f\u20e3 Load Config1').first().json.config.api_url }}/audit/logs?event_type=x402_payment_settled&hours={{ $('2\ufe0f\u20e3 Load Config1').first().json.config.time_range_hours }}&limit={{ $('2\ufe0f\u20e3 Load Config1').first().json.config.audit_log_limit }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "={{ $('2\ufe0f\u20e3 Load Config1').first().json.config.api_key }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "6b7ff7a9-9f5c-40d2-9042-fabdefe9ac1a",
      "name": "2\ufe0f\u20e3 Load Config1",
      "type": "n8n-nodes-base.code",
      "notes": "\u2699\ufe0f SETUP: Validate inputs\n\n\u26a0\ufe0f EDIT THIS if running manually:\n- merchant_wallet: Your wallet address\n- api_key: Your AgentGatePay API key",
      "position":
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Get your AI agents paying for resources autonomously in under 10 minutes.

Source: https://n8n.io/workflows/12015/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

This is for SaaS founders, agency owners, and Sales Ops managers who use HubSpot but are tired of "toe-stepping." If your BDRs are accidentally emailing your AE’s active deals, or Marketing is blastin

Data Table, HTTP Request
AI & RAG

CLEAN Agent - Manual Trigger. Uses googleDrive, googleSheets, httpRequest. Event-driven trigger; 49 nodes.

Google Drive, Google Sheets, HTTP Request
AI & RAG

[2/3] Set up medoids (2 types) for anomaly detection (crops dataset). Uses manualTrigger, httpRequest, splitOut, stickyNote. Event-driven trigger; 48 nodes.

HTTP Request
AI & RAG

Workflows from the webinar "Build production-ready AI Agents with Qdrant and n8n".

HTTP Request
AI & RAG

Secretary — Gmail Manager (gelsonmascarenhas@gmail.com). Uses gmailTrigger, httpRequest, googleCalendar, gmail. Event-driven trigger; 47 nodes.

Gmail Trigger, HTTP Request, Google Calendar +2