This workflow corresponds to n8n.io template #11874 — 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 →
{
"id": "lnqTOTUmd1cb2r7f",
"name": "\ud83d\udcb2AgentGatePay - Seller Resource API [TEMPLATE]",
"tags": [],
"nodes": [
{
"id": "2a5eb6b5-b01e-43fb-adef-7cc5aa35c92c",
"name": "\ud83d\udce1 GET /resource/{id}",
"type": "n8n-nodes-base.webhook",
"notes": "PUBLIC ENDPOINT\n\n\u2705 NO EDITS NEEDED\n\nCopy webhook URL after activating!",
"position": [
592,
208
],
"parameters": {
"path": "resource/:resourceId",
"options": {
"rawBody": false
},
"responseMode": "responseNode"
},
"typeVersion": 1.1
},
{
"id": "66292d2e-2752-48da-b970-bbb96cc87a5a",
"name": "1\ufe0f\u20e3 Parse Request",
"type": "n8n-nodes-base.code",
"notes": "\ud83d\udd27 EDIT THIS NODE!\n\nReplace 2 values:\n1. wallet_address\n2. api_key",
"position": [
800,
208
],
"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\n// \ud83d\udccb SELLER CONFIGURATION (EDIT THESE 2 VALUES!)\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\n\nconst SELLER_CONFIG = {\n merchant: {\n name: \"DataBot Pro\",\n company: \"MarketInsights AI Ltd.\",\n email: \"user@example.com\",\n \n // YOUR BASE WALLET ADDRESS (where you receive USDC)\n wallet_address: \"YOUR_WALLET_ADDRESS\",\n \n // YOUR AGENTGATEPAY API KEY\n api_key: \"YOUR AGENTGATEPAY API KEY\"\n },\n \n payment: {\n token: \"USDC\",\n chain: \"base\"\n },\n \n catalog: {\n \"saas-competitors-2025\": {\n id: \"saas-competitors-2025\",\n title: \"Top 5 SaaS Competitors Analysis 2025\",\n price_usd: 0.01,\n preview: \"Salesforce (19.8%), HubSpot (8.5%), Zendesk (6.2%)...\"\n }\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\n// VALIDATION (DO NOT EDIT)\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\n\nconst errors = [];\n\nif (SELLER_CONFIG.merchant.wallet_address === \"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbB\") {\n errors.push(\"\u274c wallet_address not configured\");\n}\n\nif (SELLER_CONFIG.merchant.api_key === \"YOUR_AGENTPAY_API_KEY\") {\n errors.push(\"\u274c api_key not configured\");\n}\n\nif (errors.length > 0) {\n return [{\n json: {\n route: \"error_config\",\n http_response: {\n statusCode: 500,\n message: \"Seller configuration incomplete\",\n errors: errors\n }\n }\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\n// PARSE REQUEST (DO NOT EDIT)\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\n\nconst request = $input.first().json;\nconst resource_id = request.params?.resourceId || request.query?.resourceId;\nconst headers = request.headers || {};\n\nconst payment_tx_hash = headers['x-payment'] || headers['X-Payment'];\nconst agent_id = headers['x-agent-id'] || headers['X-Agent-Id'];\n\nconst resource = SELLER_CONFIG.catalog[resource_id];\n\nif (!resource) {\n return [{\n json: {\n route: \"error_404\",\n http_response: {\n statusCode: 404,\n message: \"Resource not found\",\n resource_id: resource_id,\n available: Object.keys(SELLER_CONFIG.catalog)\n }\n }\n }];\n}\n\nreturn [{\n json: {\n config: SELLER_CONFIG,\n resource: resource,\n request: {\n resource_id: resource_id,\n agent_id: agent_id,\n payment_tx_hash: payment_tx_hash,\n has_payment: !!payment_tx_hash\n },\n route: payment_tx_hash ? \"verify_payment\" : \"return_402\"\n }\n}];"
},
"typeVersion": 2
},
{
"id": "256e6d34-a4d0-4d0b-9b0a-427b29a9ddb6",
"name": "2\ufe0f\u20e3 Has Payment?",
"type": "n8n-nodes-base.if",
"notes": "\u2705 NO EDITS NEEDED",
"position": [
992,
208
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "has-payment",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.route }}",
"rightValue": "verify_payment"
}
]
}
},
"typeVersion": 2
},
{
"id": "aa1acd74-3c89-4efc-96a3-e5a335a0f868",
"name": "3\ufe0f\u20e3 Generate 402",
"type": "n8n-nodes-base.code",
"notes": "\u2705 NO EDITS NEEDED",
"position": [
1200,
32
],
"parameters": {
"jsCode": "const data = $input.first().json;\nconst config = data.config;\nconst resource = data.resource;\n\nconst token_decimals = config.payment.token === \"DAI\" ? 18 : 6;\nconst amount = Math.floor(resource.price_usd * Math.pow(10, token_decimals));\nconst nonce = `nonce_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n\nconst response_402 = {\n statusCode: 402,\n message: \"Payment Required\",\n protocol: \"x402\",\n \n payTo: config.merchant.wallet_address,\n amount: amount.toString(),\n token: config.payment.token,\n chain: config.payment.chain,\n priceUsd: resource.price_usd.toString(),\n nonce: nonce,\n \n resource: {\n id: resource.id,\n title: resource.title,\n preview: resource.preview\n },\n \n merchant: {\n name: config.merchant.name,\n email: config.merchant.email\n },\n \n instructions: [\n `1. Send ${amount} ${config.payment.token} to ${config.merchant.wallet_address}`,\n `2. Wait for confirmation`,\n `3. Retry with header: x-payment: {tx_hash}`\n ]\n};\n\nreturn [{\n json: {\n http_response: response_402\n }\n}];"
},
"typeVersion": 2
},
{
"id": "cb658f93-2039-4182-bec1-ac3214991bc7",
"name": "4\ufe0f\u20e3 Send 402",
"type": "n8n-nodes-base.respondToWebhook",
"notes": "\u2705 NO EDITS NEEDED",
"position": [
1408,
32
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json.http_response) }}"
},
"typeVersion": 1
},
{
"id": "69e40d79-e0c8-473f-8fc4-87d20ad63071",
"name": "5\ufe0f\u20e3 Verify Payment",
"type": "n8n-nodes-base.httpRequest",
"notes": "\u2705 NO EDITS NEEDED",
"position": [
1200,
304
],
"parameters": {
"url": "=https://api.agentgatepay.com/v1/payments/verify/{{ $('1\ufe0f\u20e3 Parse Request').first().json.request.payment_tx_hash }}",
"options": {},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "x-api-key",
"value": "={{ $('1\ufe0f\u20e3 Parse Request').first().json.config.merchant.api_key }}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "9a0c0569-a791-4d26-bcaf-2712eb0d575c",
"name": "6\ufe0f\u20e3 Validate Payment",
"type": "n8n-nodes-base.code",
"notes": "\ud83e\uddea TEST MODE ACTIVE!\n\nBypasses AgentGatePay verification.\nALWAYS returns validation_passed.\n\n\u26a0\ufe0f REMOVE BEFORE PRODUCTION!",
"position": [
1408,
304
],
"parameters": {
"jsCode": "const request_data = $('1\ufe0f\u20e3 Parse Request').first().json;\n const verification = $input.first().json;\n const config = request_data.config;\n const resource = request_data.resource;\n\n// Check if verification succeeded\n if (!verification.verified) {\n return [{\n json: {\n route: \"validation_failed\",\n http_response: {\n statusCode: 400,\n error: \"Payment verification failed\",\n verified: verification.verified,\n details: verification.error || \"Payment not found\"\n }\n }\n }];\n }\n\n const recipient_ok = verification.to_address.toLowerCase() === config.merchant.wallet_address.toLowerCase();\n if (!recipient_ok) {\n return [{\n json: {\n route: \"validation_failed\",\n http_response: {\n statusCode: 400,\n error: \"Wrong recipient\",\n expected: config.merchant.wallet_address,\n received: verification.to_address\n }\n }\n }];\n }\n\n const amount_ok = Math.abs(verification.amount_usd - resource.price_usd) < 0.01;\n if (!amount_ok) {\n return [{\n json: {\n route: \"validation_failed\",\n http_response: {\n statusCode: 400,\n error: \"Wrong amount\",\n expected_usd: resource.price_usd,\n received_usd: verification.amount_usd\n }\n }\n }];\n }\n\n return [{\n json: {\n ...request_data,\n verification: verification,\n route: \"validation_passed\"\n }\n }];"
},
"typeVersion": 2
},
{
"id": "65e9dc23-b80b-4c7a-b64f-0720fff0273d",
"name": "6B\ufe0f\u20e3 Route: Valid?",
"type": "n8n-nodes-base.if",
"notes": "\u2705 NEW v3.2:\nRoutes valid payments to resource delivery",
"position": [
1616,
304
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "validation-passed",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.route }}",
"rightValue": "validation_passed"
}
]
}
},
"typeVersion": 2
},
{
"id": "8fca90fb-f0c5-49c5-8b9f-ec4053acb844",
"name": "7\ufe0f\u20e3 Deliver Resource",
"type": "n8n-nodes-base.code",
"notes": "\u2705 v3.2:\nCreates full resource response",
"position": [
1808,
128
],
"parameters": {
"jsCode": "const data = $input.first().json;\nconst resource = data.resource;\nconst verification = data.verification;\n\nconst full_data = {\n success: true,\n resource_id: resource.id,\n title: resource.title,\n price_paid_usd: verification.amountUsd,\n \n data: {\n competitors: [\n {\n rank: 1,\n name: \"Salesforce\",\n market_share: \"19.8%\",\n revenue_2024: \"$34.9B\"\n },\n {\n rank: 2,\n name: \"HubSpot\",\n market_share: \"8.5%\",\n revenue_2024: \"$2.2B\"\n },\n {\n rank: 3,\n name: \"Zendesk\",\n market_share: \"6.2%\",\n revenue_2024: \"$1.7B\"\n },\n {\n rank: 4,\n name: \"Freshworks\",\n market_share: \"4.1%\",\n revenue_2024: \"$596M\"\n },\n {\n rank: 5,\n name: \"Zoho CRM\",\n market_share: \"3.8%\",\n revenue_2024: \"$1.1B\"\n }\n ],\n market_analysis: {\n total_market_size_2024: \"$69.8B\",\n cagr: \"13.3%\",\n key_trends: [\n \"AI-powered insights\",\n \"Mobile-first experiences\",\n \"Unified customer data platforms\"\n ]\n }\n },\n \n payment: {\n tx_hash: verification.txHash,\n verified: true,\n paid_by: verification.sender,\n amount_usd: verification.amountUsd\n },\n \n delivered_at: new Date().toISOString()\n};\n\nreturn [{\n json: {\n http_response: full_data\n }\n}];"
},
"typeVersion": 2
},
{
"id": "d2cba580-13ed-4815-afee-e77e296c985d",
"name": "8\ufe0f\u20e3 Send 200 OK",
"type": "n8n-nodes-base.respondToWebhook",
"notes": "\u2705 Sends success response with body",
"position": [
1984,
128
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json.http_response) }}"
},
"typeVersion": 1
},
{
"id": "bdd63871-3b5c-49e3-b05c-1fda12928fd0",
"name": "9\ufe0f\u20e3 Send Error",
"type": "n8n-nodes-base.respondToWebhook",
"notes": "\u2705 Sends error response with body",
"position": [
1824,
464
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json.http_response) }}"
},
"typeVersion": 1
},
{
"id": "b2d0e1f0-b135-49d5-9426-136260246560",
"name": "START HERE",
"type": "n8n-nodes-base.stickyNote",
"position": [
16,
16
],
"parameters": {
"color": 4,
"width": 500,
"height": 620,
"content": "# Seller Resource API\n\n**What it does:** Webhook that sells digital resources to AI agents. Verifies payments via AgentGatePay before delivering content.\n\n**Quick setup (3 min):**\n1. Edit Node 1: Add your wallet address and AgentGatePay API key\n2. Choose payment: coin and network\n3. Activate workflow (toggle top-right)\n4. Copy webhook URL from Node \"\ud83d\udce1 GET /resource/{id}\"\n5. Share URL with buyer agents\n\n**Payment flow:**\n- Request without payment \u2192 Returns 402 with payment details\n- Request with tx_hash \u2192 Verifies via Gateway \u2192 Delivers resource\n\n**Revenue:** You get 99.5% \u00b7 AgentGatePay takes 0.5% commission\n\n**Customize:** Node 1 for price/resources \u00b7 Node 7 for resource data\n\nFor more info:\nhttps://github.com/AgentGatePay/agentgatepay-examples/tree/main/n8n"
},
"typeVersion": 1
},
{
"id": "a3d381df-82d8-4298-9f0b-3e63a893cf5a",
"name": "Sticky Note 1",
"type": "n8n-nodes-base.stickyNote",
"position": [
544,
80
],
"parameters": {
"color": 7,
"width": 600,
"height": 300,
"content": "## Request Processing\n\nWebhook receives GET request, parses your merchant config and headers, checks if buyer included a payment tx_hash, then routes accordingly."
},
"typeVersion": 1
},
{
"id": "0cde0860-3d4f-4f29-bcda-5a7a1ade6827",
"name": "Sticky Note 2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1168,
160
],
"parameters": {
"color": 7,
"width": 480,
"height": 300,
"content": "## Payment Verification\n\nAsks AgentGatePay to verify the tx_hash. Checks if payment went to your wallet and matches the resource price. Routes to delivery or error."
},
"typeVersion": 1
},
{
"id": "62d614d0-0cf3-44f1-abf5-f0cbc40bb284",
"name": "Sticky Note 3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1168,
-80
],
"parameters": {
"color": 7,
"width": 1040,
"height": 348,
"content": "## Response Handling\n\nGenerates 402 response when no payment, or delivers the paid resource with 200 OK. Handles errors like wrong amount or invalid tx_hash."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "41504858-cec4-4200-b183-d54c15ee6a30",
"connections": {
"2\ufe0f\u20e3 Has Payment?": {
"main": [
[
{
"node": "5\ufe0f\u20e3 Verify Payment",
"type": "main",
"index": 0
}
],
[
{
"node": "3\ufe0f\u20e3 Generate 402",
"type": "main",
"index": 0
}
]
]
},
"3\ufe0f\u20e3 Generate 402": {
"main": [
[
{
"node": "4\ufe0f\u20e3 Send 402",
"type": "main",
"index": 0
}
]
]
},
"1\ufe0f\u20e3 Parse Request": {
"main": [
[
{
"node": "2\ufe0f\u20e3 Has Payment?",
"type": "main",
"index": 0
},
{
"node": "9\ufe0f\u20e3 Send Error",
"type": "main",
"index": 0
}
]
]
},
"5\ufe0f\u20e3 Verify Payment": {
"main": [
[
{
"node": "6\ufe0f\u20e3 Validate Payment",
"type": "main",
"index": 0
}
]
]
},
"6B\ufe0f\u20e3 Route: Valid?": {
"main": [
[
{
"node": "7\ufe0f\u20e3 Deliver Resource",
"type": "main",
"index": 0
}
],
[
{
"node": "9\ufe0f\u20e3 Send Error",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udce1 GET /resource/{id}": {
"main": [
[
{
"node": "1\ufe0f\u20e3 Parse Request",
"type": "main",
"index": 0
}
]
]
},
"6\ufe0f\u20e3 Validate Payment": {
"main": [
[
{
"node": "6B\ufe0f\u20e3 Route: Valid?",
"type": "main",
"index": 0
}
]
]
},
"7\ufe0f\u20e3 Deliver Resource": {
"main": [
[
{
"node": "8\ufe0f\u20e3 Send 200 OK",
"type": "main",
"index": 0
}
]
]
}
}
}
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/11874/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Jigsaw API key for image processing, I use this as a gatekeeper/second pair of eyes. LINK to their website https://jigsawstack.com/ SECOND A postgress DATABASE (I use Supabase) LlamaCloud for the pars
Whatsapp Multi Agent System optimized copy 2.0. Uses airtable, httpRequest, errorTrigger. Webhook trigger; 44 nodes.
Invoice Agent. Uses httpRequest, emailSend. Webhook trigger; 29 nodes.
Reputation Engine — SEO QA Agent. Uses httpRequest. Webhook trigger; 28 nodes.
This workflow handles incoming voice calls or audio messages, transcribes them using Whisper (OpenAI) or ElevenLabs, extracts booking intent and preferred time slots using AI, checks availability on C