AutomationFlowsE-commerce › Recover Abandoned Shopify Carts with Email Follow-ups, Hubspot CRM & Google…

Recover Abandoned Shopify Carts with Email Follow-ups, Hubspot CRM & Google…

Original n8n title: Recover Abandoned Shopify Carts with Email Follow-ups, Hubspot CRM & Google Sheets Tracking

ByAvkash Kakdiya @itechnotion on n8n.io

The workflow triggers on a new checkout event from Shopify and extracts all relevant cart data. It filters carts based on value and age to isolate qualified abandoned checkouts. For each qualified cart, it sends a follow-up email, updates or creates the corresponding HubSpot…

Event trigger★★★★☆ complexity13 nodesGoogle SheetsShopify TriggerGmailHubSpotHTTP Request
E-commerce Trigger: Event Nodes: 13 Complexity: ★★★★☆ Added:

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

This workflow follows the Gmail → Google Sheets 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
{
  "id": "y0FQZ0yoOzRidyCR",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Shopify Pending Cart List",
  "tags": [
    {
      "id": "2V3HXFbv2wqNGm6s",
      "name": "Dev",
      "createdAt": "2025-06-17T05:42:41.949Z",
      "updatedAt": "2025-06-17T05:42:41.949Z"
    }
  ],
  "nodes": [
    {
      "id": "6871a2f7-9150-4c8f-920c-0b0ed8c5a782",
      "name": "Parse Cart Data",
      "type": "n8n-nodes-base.code",
      "position": [
        -64,
        -144
      ],
      "parameters": {
        "jsCode": "const inputData = $input.all();\nconst carts = [];\n\nfor (const item of inputData) {\n  const data = item.json;\n\n  const createdAt = new Date(data.created_at);\n  const now = new Date();\n  const hoursSinceCreated = (now - createdAt) / (1000 * 60 * 60);\n\n  carts.push({\n    id: data.id,\n    email: data.email,\n    firstName: data.shipping_address?.first_name || 'Customer',\n    lastName: data.shipping_address?.last_name || '',\n    cartTotal: parseFloat(data.total_price),\n    checkoutUrl: data.checkout_url || null, // Not in your sample, but safe to include\n    createdAt: data.created_at,\n    hoursSinceCreated: hoursSinceCreated,\n    lineItems: (data.line_items || []).map(item => ({\n      title: item.title,\n      quantity: item.quantity\n    }))\n  });\n}\n\nreturn carts.map(cart => ({ json: cart }));"
      },
      "typeVersion": 2
    },
    {
      "id": "daae44ba-d5d6-451e-a565-e66c997e065c",
      "name": "Filter Qualified Carts",
      "type": "n8n-nodes-base.if",
      "position": [
        160,
        -144
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.hoursSinceCreated }}",
              "rightValue": 12
            },
            {
              "id": "b2c3d4e5-f6a7-8b9c-0d1e-2f3a4b5c6d7e",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.cartTotal }}",
              "rightValue": 50
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "16dd9990-b86d-4a58-9f6e-c90899cdfcc0",
      "name": "Log to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1504,
        -160
      ],
      "parameters": {
        "columns": {
          "value": {
            "Id": "={{ $('Filter Qualified Carts').item.json.id }}",
            "item": "={{ $('Filter Qualified Carts').item.json.lineItems[0].title }}",
            "email": "={{ $('Filter Qualified Carts').item.json.email }}",
            "lastName": "={{ $('Filter Qualified Carts').item.json.lastName }}",
            "quantity": "={{ $('Filter Qualified Carts').item.json.lineItems[0].quantity }}",
            "cartTotal": "={{ $('Filter Qualified Carts').item.json.cartTotal }}",
            "createdAt": "={{ $('Filter Qualified Carts').item.json.createdAt }}",
            "firstName": "={{ $('Filter Qualified Carts').item.json.firstName }}",
            "hoursSinceCreated": "={{ $('Filter Qualified Carts').item.json.hoursSinceCreated }}"
          },
          "schema": [
            {
              "id": "Id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "firstName",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "firstName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "lastName",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "lastName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "cartTotal",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "cartTotal",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "createdAt",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "createdAt",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "hoursSinceCreated",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "hoursSinceCreated",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "item",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "item",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "quantity",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "quantity",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/10W6XFIKZAbQ-Ni-GSNMpMQQbj4y6geFKkgtw9f9KRvQ/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "10W6XFIKZAbQ-Ni-GSNMpMQQbj4y6geFKkgtw9f9KRvQ",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/10W6XFIKZAbQ-Ni-GSNMpMQQbj4y6geFKkgtw9f9KRvQ/edit?usp=drivesdk",
          "cachedResultName": "cart checkout update"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "0835f0e4-8353-4d88-82e6-e8d648d2ec35",
      "name": "Shopify Trigger",
      "type": "n8n-nodes-base.shopifyTrigger",
      "position": [
        -272,
        -144
      ],
      "parameters": {
        "topic": "checkouts/create",
        "authentication": "accessToken"
      },
      "credentials": {
        "shopifyAccessTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "1283399e-a6ed-4539-a597-4f3ce661db83",
      "name": "Send a message",
      "type": "n8n-nodes-base.gmail",
      "position": [
        384,
        -160
      ],
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "=Hi {{ $json.firstName }},\n\nWe noticed you didn\u2019t get a chance to complete your checkout, and your selected items are still waiting for you.\n\nTake another look whenever you\u2019re ready \u2014 your cart has been saved, so it\u2019ll be quick and easy to finish up.\n\nIf you have any questions or need help along the way, just reply to this email \u2014 we\u2019re always happy to assist.\n",
        "options": {},
        "subject": "You left something in your cart \ud83d\udc40",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "02f6b0e8-e6f0-495a-a62f-9a92933938b8",
      "name": "Create or update a contact",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        608,
        -160
      ],
      "parameters": {
        "email": "={{ $('Filter Qualified Carts').item.json.email }}",
        "options": {},
        "authentication": "appToken",
        "additionalFields": {
          "lastName": "={{ $('Filter Qualified Carts').item.json.lastName }}",
          "firstName": "={{ $('Filter Qualified Carts').item.json.firstName }}"
        }
      },
      "credentials": {
        "hubspotAppToken": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "333b31e4-7a61-4874-8cc5-90bb49f30d2b",
      "name": "Generates Note Data",
      "type": "n8n-nodes-base.set",
      "position": [
        832,
        -160
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "fc405999-2c9a-49f6-a4f8-59727a41a743",
              "name": "properties.hs_note_body",
              "type": "string",
              "value": "={{ $('Filter Qualified Carts').item.json.firstName }} {{ $('Filter Qualified Carts').item.json.lastName }} started a checkout on {{ $('Filter Qualified Carts').item.json.createdAt }}, about {{ $('Filter Qualified Carts').item.json.hoursSinceCreated }} hours ago. \nThey added {{ $('Filter Qualified Carts').item.json.lineItems[0].quantity }} item \u2014 \u201c{{ $('Filter Qualified Carts').item.json.lineItems[0].title }}\u201d \u2014 to their cart with a total value of {{ $('Filter Qualified Carts').item.json.cartTotal }}, but haven\u2019t completed the purchase yet.\n\nA follow-up email is sent regarding the same"
            },
            {
              "id": "0f572322-acbd-4602-8f8a-e17f8d9d5017",
              "name": "properties.hs_timestamp",
              "type": "string",
              "value": "={{ Date.now() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "5799649a-ad1e-453c-95c5-34e78ec33ff8",
      "name": "Create HubSpot Note",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1056,
        -160
      ],
      "parameters": {
        "url": "https://api.hubapi.com/crm/v3/objects/notes",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ $json }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "3eedc5d3-a0f1-4013-8c99-f291b9d1486b",
      "name": "Associate Note with Contact in HubSpot",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1280,
        -160
      ],
      "parameters": {
        "url": "=https://api.hubapi.com/crm/v3/objects/notes/{{ $json.id }}/associations/contacts/{{ $('Create or update a contact').item.json.vid }}/note_to_contact",
        "method": "PUT",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "99727956-61b3-4073-aa26-835b0d8c72c6",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -352,
        -384
      ],
      "parameters": {
        "color": 7,
        "width": 672,
        "height": 592,
        "content": "## Step 1: Capture & Filter Carts  \nCollects new checkout data from Shopify, extracts customer and cart details, and filters carts that are older than 12 hours and worth more than $50. Only qualified carts continue.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "efb4135f-875a-47b5-940d-55db67bc74f5",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        352,
        -384
      ],
      "parameters": {
        "color": 7,
        "width": 1056,
        "height": 592,
        "content": "## Step 2: Recovery Email & CRM Sync  \nSends a personalized reminder email, updates or creates the customer in HubSpot, generates a detailed activity note, and links it to their contact profile for the sales team.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "990072eb-a3f5-46a0-b0f1-7b2d4df6bd99",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1440,
        -384
      ],
      "parameters": {
        "color": 7,
        "width": 496,
        "height": 592,
        "content": "## Step 3: Log Recovery Data  \nSaves all cart and customer details to Google Sheets, including timestamps, item name, quantity, value, and cart age\u2014helping track recovery performance.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b07b24d7-cec6-4048-b3ef-7201f38d99b4",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -928,
        -368
      ],
      "parameters": {
        "width": 544,
        "height": 544,
        "content": "## Abandoned Cart Recovery & CRM Logging \u2013 Overview  \nThis workflow helps you follow up with customers who start checkout but don\u2019t complete it. It checks if their cart is older than 12 hours and worth more than $50. If it qualifies, the workflow sends a reminder email, updates the customer in HubSpot, adds a note with their cart details, and logs everything in Google Sheets for tracking.\n\n### How it works\n- Detects new Shopify checkout  \n- Filters high-value, older carts  \n- Sends a recovery email  \n- Updates customer + adds note in HubSpot  \n- Logs details to Google Sheets  \n\n### Setup steps\n1. Connect Shopify, Gmail, HubSpot, and Google Sheets  \n2. Add your HubSpot token  \n3. Select your Google Sheet  \n4. Adjust cart filter rules if needed  \n5. Test with a sample checkout  \n"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "9ea1dba0-f3ce-4fb7-b8bb-aa9422bd4935",
  "connections": {
    "Send a message": {
      "main": [
        [
          {
            "node": "Create or update a contact",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Cart Data": {
      "main": [
        [
          {
            "node": "Filter Qualified Carts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Shopify Trigger": {
      "main": [
        [
          {
            "node": "Parse Cart Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create HubSpot Note": {
      "main": [
        [
          {
            "node": "Associate Note with Contact in HubSpot",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generates Note Data": {
      "main": [
        [
          {
            "node": "Create HubSpot Note",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Google Sheets": {
      "main": [
        []
      ]
    },
    "Filter Qualified Carts": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create or update a contact": {
      "main": [
        [
          {
            "node": "Generates Note Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Associate Note with Contact in HubSpot": {
      "main": [
        [
          {
            "node": "Log to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

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

About this workflow

The workflow triggers on a new checkout event from Shopify and extracts all relevant cart data. It filters carts based on value and age to isolate qualified abandoned checkouts. For each qualified cart, it sends a follow-up email, updates or creates the corresponding HubSpot…

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

More E-commerce workflows → · Browse all categories →

Related workflows

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

E-commerce

This workflow automates the synchronization of product prices across Shopify and WooCommerce platforms to ensure retail consistency. It triggers when a price change is detected in either system, appli

Shopify Trigger, Woo Commerce Trigger, WooCommerce +3
E-commerce

This n8n workflow automatically sends WhatsApp notifications to customers when their Shopify orders are fulfilled. It extracts order details, validates customer phone numbers for WhatsApp compatibilit

HTTP Request, Shopify Trigger, Google Sheets
E-commerce

This workflow automates inventory management and predictive reordering for Shopify stores. It integrates Shopify, Google Sheets, and Slack to monitor inventory levels, calculate dynamic reorder points

Shopify, Google Sheets, Gmail +2
E-commerce

A webhook or timer triggers the workflow to automatically fetch inventory data from multiple platforms. Stock levels are compared across stores to identify discrepancies, and any inconsistencies are u

HTTP Request, Google Sheets, Gmail
E-commerce

E-commerce store owners and sales managers who want AI-powered insights from their Shopify data without manually crunching numbers every week.

Shopify, HTTP Request, Slack +2