{
  "name": "x402",
  "nodes": [
    {
      "parameters": {
        "path": "92c5ca23-99a7-437d-85da-84aef8bd2a25",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -500,
        -50
      ],
      "id": "bf854266-4250-4491-af67-ff8fc3b63ac6",
      "name": "Webhook"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "2ff83590-61f3-41d8-8500-a96103c3844c",
              "leftValue": "={{ $json.headers['x-payment'] }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -280,
        -50
      ],
      "id": "82409682-6932-4714-9f7c-27c60a692245",
      "name": "Check for presence of X-HEADER"
    },
    {
      "parameters": {
        "jsCode": "try {\n    // Decode the x-payment header from base64\n    const xPaymentHeader = $input.first().json.headers['x-payment'];\n    const decodedXPayment = Buffer.from(xPaymentHeader, 'base64').toString('utf-8');\n\n    // Parse the decoded value into a JSON object\n    const decodedXPaymentJson = JSON.parse(decodedXPayment);\n\n    // Add the parsed JSON object to the input\n    $input.first().json.decodedXPayment = decodedXPaymentJson;\n\n    return $input.all();\n} catch (error) {\n    // Return an error object if the token format is invalid\n    return { error: \"invalid token format\" };\n}"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -60,
        -125
      ],
      "id": "efb6f824-6679-4ad4-9b05-c20ef27a706d",
      "name": "Decode & Validate X-Payment"
    },
    {
      "parameters": {
        "operation": "simulate",
        "contractMethodId": "b63aaaa1-059d-4c38-928a-33ad17d66827",
        "params": "={\n  \"from\": \"{{ $json.decodedXPayment.payload.authorization.from }}\",\n  \"to\": \"{{ $json.decodedXPayment.payload.authorization.to }}\",\n  \"value\": \"{{ $json.decodedXPayment.payload.authorization.value }}\",\n  \"validAfter\": \"{{ $json.decodedXPayment.payload.authorization.validAfter }}\",\n  \"validBefore\": \"{{ $json.decodedXPayment.payload.authorization.validBefore }}\",\n  \"nonce\": \"{{ $json.decodedXPayment.payload.authorization.nonce }}\",\n  \"signature\": \"{{ $json.decodedXPayment.payload.signature }}\"\n} "
      },
      "type": "n8n-nodes-1shot.oneShot",
      "typeVersion": 1,
      "position": [
        380,
        -175
      ],
      "id": "6cad76b8-1a56-4028-92f4-a6fb696e1647",
      "name": "Simulate Payment"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "81c67679-e256-4fd2-bed7-8f4272c2392b",
              "leftValue": "={{ $json.success.toString() }}",
              "rightValue": "true",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        600,
        -175
      ],
      "id": "a2f18d76-8bea-4d1c-9287-6c0a7594d6da",
      "name": "On Successful Payment Simulation"
    },
    {
      "parameters": {
        "contractMethodId": "b63aaaa1-059d-4c38-928a-33ad17d66827",
        "params": "={\n\"to\": \"{{ $('Ensure Well Formatted Payment Payload').item.json.decodedXPayment.payload.authorization.to }}\",\n\"from\": \"{{ $('Ensure Well Formatted Payment Payload').item.json.decodedXPayment.payload.authorization.from }}\",\n\"value\": \"{{ $('Ensure Well Formatted Payment Payload').item.json.decodedXPayment.payload.authorization.value }}\",\n\"validAfter\": \"{{ $('Ensure Well Formatted Payment Payload').item.json.decodedXPayment.payload.authorization.validAfter }}\",\n\"validBefore\": \"{{ $('Ensure Well Formatted Payment Payload').item.json.decodedXPayment.payload.authorization.validBefore }}\",\n\"nonce\": \"{{ $('Ensure Well Formatted Payment Payload').item.json.decodedXPayment.payload.authorization.nonce }}\",\n\"signature\": \"{{ $('Ensure Well Formatted Payment Payload').item.json.decodedXPayment.payload.signature }}\"\n}",
        "additionalFields": {}
      },
      "type": "n8n-nodes-1shot.oneShotSynch",
      "typeVersion": 1,
      "position": [
        820,
        -250
      ],
      "id": "1f182441-25da-41cc-913d-8e724866d7d3",
      "name": "1Shot API Submit & Wait"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "6666e1f6-5e99-49d4-9f9a-a5a35cde4f74",
              "leftValue": "={{ $json.decodedXPayment.payload.signature }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        160,
        -120
      ],
      "id": "cfa44cb3-de5c-4ef2-9950-cca2d2bdcfbc",
      "name": "Ensure Well Formatted Payment Payload"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\n  \"x402Version\": \"1\",\n  \"error\": \"X-PAYMENT header has incorrect format\"\n}",
        "options": {
          "responseCode": 402
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.3,
      "position": [
        380,
        50
      ],
      "id": "605abcb3-2acc-4db4-a87a-efae930a015d",
      "name": "Response: Missing or Invalid Payment Headers"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\n  \"x402Version\": \"1\",\n  \"error\": \"X-PAYMENT header did not verify\"\n}",
        "options": {
          "responseCode": 402
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.3,
      "position": [
        1040,
        -75
      ],
      "id": "8790cc26-6626-47fe-ae0f-8142b3fde734",
      "name": "Response: Payment Invalid"
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "\"Payment Received!\" ",
        "options": {
          "responseCode": 200
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.3,
      "position": [
        1040,
        -300
      ],
      "id": "5b29d382-d7dc-484c-b700-3de0c5935c8a",
      "name": "Response: 200 - Payment Successful"
    },
    {
      "parameters": {
        "content": "## x402 Payment Endpoint \n\nThis workflow fragment can be used to monetize any workflow you can build in n8n by accepting stablecoin payments via an API call.\n\nLearn more about the [x402 payment](https://www.x402.org/) protocol. \n\nWatch the [YouTube tutorial](https://youtu.be/m3ThthLtj3g) video.",
        "height": 220,
        "width": 360
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -600,
        -320
      ],
      "id": "ff4b8de5-6be4-4cce-abc6-05e3902eb535",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "content": "## Any ERC-20 on any EVM\n\nWith the 1Shot API node, you can accept any ERC-20 with the appropriate transferWithAuthorization methods.",
        "width": 360
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        420,
        -400
      ],
      "id": "7edff090-85d5-48e6-9d86-203bbf3cea11",
      "name": "Sticky Note1"
    },
    {
      "parameters": {
        "content": "## Put your workflow down here \n\nOnce the payment transaction has been confirmed, replace the `Response: 200 - Payment Successful` block with your workflow which responds to the user with the appropriate premium content. ",
        "height": 200,
        "width": 320
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1300,
        -360
      ],
      "id": "9b46463f-be85-47e2-a05c-96a696f1965f",
      "name": "Sticky Note2"
    },
    {
      "parameters": {
        "content": "## Example Curl Command\n\nYou can test the webhook endpoint with a command like this (be sure to use a properly formatted x-payment header payload): \n\n```sh\n# swap out the URL here for you webhook URL endpoint\ncurl -X GET \\\n  https://n8n.1shotapi.dev/webhook-test/92c5ca23-99a7-437d-85da-84aef8bd2a25 \\\n  -H \"x-payment: YOUR-BASE64-ENCODED-PAYMENT-PAYLOAD\" \\\n  -H \"User-Agent: CustomUserAgent/1.0\" \\\n  -H \"Accept: application/json\"\n```",
        "height": 280,
        "width": 840
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -980,
        140
      ],
      "id": "4e74105c-cf34-45bb-a805-9e3dec1b2435",
      "name": "Sticky Note3"
    },
    {
      "parameters": {
        "content": "## Ensure Required Payment Details\n\nUse this block to add/check for payment detail requirements like minimum payment amount. "
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        80,
        -300
      ],
      "id": "ea9adf09-d52c-4ef5-a468-db1dc3247270",
      "name": "Sticky Note4"
    },
    {
      "id": "c6075adc-908e-5e39-82ad-393a542ff903",
      "name": "Publication · Overview and setup",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -1780,
        -400
      ],
      "parameters": {
        "content": "# x402\n\n## Purpose and structure\nThis folder contains the **x402** workflow. Its executable nodes use `code`, `if`, `oneShot`, `oneShotSynch`, `respondToWebhook`, `webhook`. The table and connection map below are derived from the JSON, not an inferred guarantee of behavior.\n\n## Setup\nImport inactive. Configure your own credentials and replace REPLACE_WITH_* values. Review external destinations and Code nodes before running.\n\n## Entry points\nWebhook\n\n## Verification\nSanitized source candidate; not runtime-tested. This overview is generated from node metadata. Read the folder README for the connection map, credential types, and license.\n\n## Attribution\nhttps://github.com/1Shot-API/n8n-nodes-1shot/blob/099288d799a12a856e15f3f680ef0fd990e7cb43/x402.json\nMIT; preserve source notices.",
        "width": 700,
        "height": 800,
        "color": 1
      }
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Check for presence of X-HEADER",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check for presence of X-HEADER": {
      "main": [
        [
          {
            "node": "Decode & Validate X-Payment",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Response: Missing or Invalid Payment Headers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Decode & Validate X-Payment": {
      "main": [
        [
          {
            "node": "Ensure Well Formatted Payment Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simulate Payment": {
      "main": [
        [
          {
            "node": "On Successful Payment Simulation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On Successful Payment Simulation": {
      "main": [
        [
          {
            "node": "1Shot API Submit & Wait",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Response: Payment Invalid",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1Shot API Submit & Wait": {
      "main": [
        [
          {
            "node": "Response: 200 - Payment Successful",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Response: Payment Invalid",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ensure Well Formatted Payment Payload": {
      "main": [
        [
          {
            "node": "Simulate Payment",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Response: Missing or Invalid Payment Headers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  }
}
