AutomationFlowsAI & RAG › Gmail Refund Requests → Shopify & Sheets

Gmail Refund Requests → Shopify & Sheets

Original n8n title: Process Refund Requests From Gmail Using Shopify and Google Sheets

ByAvkash Kakdiya @itechnotion on n8n.io

This workflow monitors incoming Gmail messages for refund requests and uses AI to extract the order ID and reason. It then retrieves order details from Shopify to evaluate refund eligibility. Based on the order status, it automatically approves or routes the request for manual…

Event trigger★★★★☆ complexityAI-powered15 nodesGmail TriggerGroq ChatGmailGoogle SheetsShopifyAgent
AI & RAG Trigger: Event Nodes: 15 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Agent → Gmail recipe pattern — see all workflows that pair these two integrations.

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
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "54fa0439-a717-4a2c-8bdf-352d61d836ef",
      "name": "Gmail Trigger",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        2864,
        -160
      ],
      "parameters": {
        "filters": {
          "q": "=subject:\"Refund Request\"",
          "readStatus": "unread"
        },
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "05ac2dd6-1b0f-4dbc-9b86-5dc2b7069218",
      "name": "Groq Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGroq",
      "position": [
        3168,
        64
      ],
      "parameters": {
        "model": "llama-3.3-70b-versatile",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "f056b065-acc7-4491-9856-0d29a85ffe61",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        3888,
        -160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "516738b9-b280-45cc-becb-7a5d182c3f7f",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.Status }}",
              "rightValue": "Delivered"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "c67589fa-d373-4df6-8cee-4e8e7c11a819",
      "name": "Code in JavaScript",
      "type": "n8n-nodes-base.code",
      "position": [
        3360,
        -160
      ],
      "parameters": {
        "jsCode": "// Get the output string from the AI Agent\nconst aiRawOutput = items[0].json.output;\n\n// Parse the string into a real JSON object\nconst cleanData = JSON.parse(aiRawOutput);\n\n// Return the data in a way n8n understands\nreturn [\n  {\n    json: {\n      order_id: cleanData.order_id,\n      reason: cleanData.reason,\n      original_summary: cleanData.reason // Optional: just in case you want a backup\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "150e6302-f8f8-49ab-9136-fa9194e2e303",
      "name": "Send a message to customer",
      "type": "n8n-nodes-base.gmail",
      "position": [
        4272,
        -256
      ],
      "parameters": {
        "sendTo": "={{ $('Gmail Trigger').item.json.From }}",
        "message": "=\"Hi there,    Good news! We have reviewed your request for Order #{{ $('Code in JavaScript').item.json.order_id }} and your refund has been approved. You should see the credit in your account within 5-7 business days.\"",
        "options": {},
        "subject": "=Refund Approved: Order #{{ $('Code in JavaScript').item.json.order_id }}"
      },
      "typeVersion": 2.2
    },
    {
      "id": "e5192a70-224f-46c0-a239-185b12e388e0",
      "name": "Send a message to the team",
      "type": "n8n-nodes-base.gmail",
      "position": [
        4176,
        -48
      ],
      "parameters": {
        "sendTo": "<TEAM_EMAIL>",
        "message": "=\"A refund request was received but could not be auto-approved.   Order ID: {{ $('Code in JavaScript').item.json.order_id }}  Reason: {{ $('Code in JavaScript').item.json.reason }}  Current Sheet Status:{{ $('Get row(s) in sheet').item.json.Status }} \"",
        "options": {},
        "subject": "=ACTION REQUIRED: Manual Refund Review (Order {{ $('Code in JavaScript').item.json.order_id }})"
      },
      "typeVersion": 2.2
    },
    {
      "id": "ae637d4a-ed87-4f92-a3dc-9b00fa0c64c0",
      "name": "Send a message to customer for \"Pending\" Status",
      "type": "n8n-nodes-base.gmail",
      "position": [
        4368,
        -48
      ],
      "parameters": {
        "sendTo": "={{ $('Gmail Trigger').item.json.From }}",
        "message": "=\"Hi, we've received your refund request. Because your order is currently marked as{{ $('Get row(s) in sheet').item.json.Status }}, a member of our team needs to review this manually. We will get back to you shortly.\"",
        "options": {},
        "subject": "=Update on your Refund Request: Order #{{ $('Code in JavaScript').item.json.order_id }}"
      },
      "typeVersion": 2.2
    },
    {
      "id": "2c323e52-6be1-4666-a4dc-891537e1a833",
      "name": "Logs to Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        4560,
        -160
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $now }}",
            "Notes": "=Original Status: {{ $('Get row(s) in sheet').item.json.Status }}",
            "Reason": "={{ $('Code in JavaScript').item.json.reason }}",
            "Outcome": "={{ $('If').item.json.Status  === 'Delivered' ? 'Auto-Approved' : 'Pending Manual Review ' }}",
            "Order ID": "={{ $('Code in JavaScript').item.json.order_id }}",
            "Customer Email": "={{ $('Gmail Trigger').item.json.From }}"
          },
          "schema": [
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Order ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Order ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Customer Email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Customer Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Reason",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Reason",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Outcome",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Outcome",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notes",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Notes",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1726448121,
          "cachedResultUrl": "",
          "cachedResultName": "Refund_Logs"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1fH2EVCTuUI-AreFpc5fHxUrt5gdl6xSO5O4Tu5OzttY",
          "cachedResultUrl": "",
          "cachedResultName": "Customer Orders"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "89516d69-f7ef-43de-ab52-207c1e836661",
      "name": "Get an order",
      "type": "n8n-nodes-base.shopify",
      "position": [
        3664,
        -160
      ],
      "parameters": {
        "options": {},
        "orderId": "={{ $json.order_id }}",
        "operation": "get",
        "authentication": "accessToken"
      },
      "typeVersion": 1
    },
    {
      "id": "8b6c737e-ac4e-44cf-8b90-c24a89de8f98",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2224,
        -512
      ],
      "parameters": {
        "width": 592,
        "height": 704,
        "content": "# Automated Refund Request Handler\n\n### How it works\nThis workflow automates refund handling from incoming Gmail messages. It detects emails with \u201cRefund Request\u201d, extracts the Order ID and reason using AI, and fetches real-time order data from Shopify. Based on the order status, it decides whether the refund can be auto-approved or requires manual review. Customers are notified automatically, and every action is logged into Google Sheets for tracking and analytics.\n\n### Setup steps\n1. Connect Gmail OAuth2 (set to production in Google Cloud).\n2. Add Groq API key for AI processing.\n3. Connect Shopify using an access token with read_orders permission.\n4. Connect Google Sheets OAuth2 for logging.\n5. Ensure your sheet contains columns: Date, Order ID, Customer Email, Reason, Outcome, Notes.\n\n### Customization tips\n- Add a date filter to allow refunds only within a specific time window.\n- Replace Gmail alerts with Slack or Discord for faster team response.\n- Extend logic to check payment status before approving refunds."
      },
      "typeVersion": 1
    },
    {
      "id": "3df540c0-efae-4d74-bb0f-dd80b9535600",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2832,
        -512
      ],
      "parameters": {
        "color": 7,
        "width": 688,
        "height": 704,
        "content": "## Step 1: Intake & AI Extraction\nTriggers on refund emails.\nExtracts order ID and reason using AI."
      },
      "typeVersion": 1
    },
    {
      "id": "cdc16763-46e7-491c-8ebf-96ef3ecc79d6",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3536,
        -512
      ],
      "parameters": {
        "color": 7,
        "width": 304,
        "height": 704,
        "content": "## Step 2: Shopify Validation\nFetches order details from Shopify.\nUsed to verify refund eligibility."
      },
      "typeVersion": 1
    },
    {
      "id": "18c043e7-32d8-480e-938b-0d34103e14d8",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3856,
        -512
      ],
      "parameters": {
        "color": 7,
        "width": 272,
        "height": 704,
        "content": "## Step 3: Decision Logic\nChecks if order is delivered.\nRoutes to auto-approve or manual review."
      },
      "typeVersion": 1
    },
    {
      "id": "85d6489c-bd60-482e-901b-a5349982e15d",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4144,
        -512
      ],
      "parameters": {
        "color": 7,
        "width": 608,
        "height": 704,
        "content": "## Step 4: Notifications & Logging\nSends customer/team emails.\nLogs outcome into Google Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "813eba65-4e60-4c13-af1a-3c5c5beee814",
      "name": "AI Agent2",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        3056,
        -160
      ],
      "parameters": {
        "text": "=Extract the Order ID and the Reason for the refund from the email details provided below. \n\nInstructions:\n- Look for the Order ID (usually a 4-digit number like 1001).\n- Summarize the reason for the refund in 5 words or less.\n- Respond ONLY with a clean JSON object. No extra text, no \"Here is your data\", just JSON.\n\nDesired Format:\n{\n  \"order_id\": \"value\",\n  \"reason\": \"value\"\n}\n\nEmail Data:\nSubject: {{ $json.Subject }}\nSnippet: {{ $json.snippet }}",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 3
    }
  ],
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Send a message to customer",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send a message to the team",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent2": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get an order": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail Trigger": {
      "main": [
        [
          {
            "node": "AI Agent2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Groq Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent2",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Get an order",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send a message to customer": {
      "main": [
        [
          {
            "node": "Logs to Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send a message to the team": {
      "main": [
        [
          {
            "node": "Send a message to customer for \"Pending\" Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send a message to customer for \"Pending\" Status": {
      "main": [
        [
          {
            "node": "Logs to Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

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

About this workflow

This workflow monitors incoming Gmail messages for refund requests and uses AI to extract the order ID and reason. It then retrieves order details from Shopify to evaluate refund eligibility. Based on the order status, it automatically approves or routes the request for manual…

Source: https://n8n.io/workflows/14524/ — 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 workflow automatically organizes your Gmail inbox using AI. It reads every incoming email, classifies it into Work, Personal, Financial or Newsletter, applies the correct Gmail label, logs the em

Gmail, Groq Chat, Agent +3
AI & RAG

hashtag. Uses gmailTrigger, googleSheets, gmail, agent. Event-driven trigger; 8 nodes.

Gmail Trigger, Google Sheets, Gmail +3
AI & RAG

ITfest. Uses telegramTrigger, telegram, textClassifier, agent. Event-driven trigger; 70 nodes.

Telegram Trigger, Telegram, Text Classifier +6
AI & RAG

Turn a simple email workflow into a LinkedIn content machine. Generate post ideas, draft full posts, and auto-publish to LinkedIn all controlled by replying to emails.

Agent, Google Gemini Chat, Gmail +3
AI & RAG

This workflow is for hotel managers, travel agencies, and hospitality teams who receive booking requests via email. It eliminates the need for manual data entry by automatically parsing emails and att

Google Sheets, Gmail, Agent +4