This workflow corresponds to n8n.io template #8948 — we link there as the canonical source.
This workflow follows the Google Calendar → HTTP Request 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 →
{
"id": "IgdFJTPyiQgcyuZ0",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Invoice Reminders Calendar",
"tags": [],
"nodes": [
{
"id": "12db8aa7-301c-48e9-b2b8-c4d6c4952a97",
"name": "Workflow Description",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2400,
-96
],
"parameters": {
"width": 389,
"height": 592,
"content": "## \ud83d\udccb Stripe Invoice to Google Calendar Automation\n\nThis workflow automatically monitors Stripe invoices and creates Google Calendar reminders for invoices due within the next 7 days.\n\n### Key Features:\n- Daily scheduled execution at 8 AM\n- Fetches draft invoices from Stripe\n- Filters invoices due within 7 days\n- Creates calendar events only for new invoices\n- Prevents duplicate calendar entries\n\n### Prerequisites:\n- Stripe API credentials configured\n- Google Calendar OAuth2 credentials\n- Access to target Google Calendar\n\n### Use Case:\nPerfect for freelancers, agencies, or businesses that need automated invoice due date tracking and reminders."
},
"typeVersion": 1
},
{
"id": "c4e5fef2-e9a0-407e-9c33-a7d30025daba",
"name": "Schedule Setup",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1872,
-288
],
"parameters": {
"width": 300,
"height": 320,
"content": "## \u23f0 Daily Schedule Setup\n\nConfigured to run every day at 8:00 AM using cron expression `0 8 * * *`\n\n**Setup Instructions:**\n1. Adjust the cron expression if needed\n2. Consider your timezone settings\n3. Test with a shorter interval during setup\n\n**Cron Format:** `minute hour day month dayofweek`"
},
"typeVersion": 1
},
{
"id": "58ec67ec-fb91-4c04-9cb9-da017afe3065",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-1664,
64
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * *"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "8bfcbc60-3af3-4204-b631-d3adce6f7c3f",
"name": "Stripe Setup Guide",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2288,
-592
],
"parameters": {
"width": 300,
"height": 424,
"content": "## \ud83d\udcb3 Stripe API Configuration\n\n**Setup Steps:**\n1. Go to n8n Credentials\n2. Add new Stripe API credential\n3. Enter your Stripe Secret Key\n4. Test the connection\n\n**Query Parameters:**\n- `status=draft`: Only fetch draft invoices\n- `limit=100`: Maximum 100 invoices per request\n"
},
"typeVersion": 1
},
{
"id": "72b75afe-0fef-46a3-b999-da3ccf3b1691",
"name": "Get Stripe Invoices",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1472,
64
],
"parameters": {
"url": "https://api.stripe.com/v1/invoices",
"options": {},
"sendQuery": true,
"sendHeaders": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "status",
"value": "draft"
},
{
"name": "limit",
"value": "100"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/x-www-form-urlencoded"
}
]
},
"nodeCredentialType": "stripeApi"
},
"credentials": {
"stripeApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.1
},
{
"id": "f6695758-d333-446e-8379-81096965ad30",
"name": "Array Processing",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1536,
224
],
"parameters": {
"width": 280,
"height": 376,
"content": "## \ud83d\udccb Processing Invoice Array\n\nThe Stripe API returns invoices in a `data` array. This node splits the array so we can process each invoice individually.\n\n**What it does:**\n- Takes the `data` field from Stripe response\n- Creates separate items for each invoice\n- Enables individual processing downstream"
},
"typeVersion": 1
},
{
"id": "a6aade30-8cbf-44dc-96b4-ead84be48371",
"name": "Split Invoices",
"type": "n8n-nodes-base.itemLists",
"position": [
-1248,
64
],
"parameters": {
"options": {},
"fieldToSplitOut": "data"
},
"typeVersion": 3
},
{
"id": "0c63a347-c22e-45d3-a85d-8ce9c00a2569",
"name": "Date Filter Logic",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1184,
-384
],
"parameters": {
"width": 280,
"height": 416,
"content": "## \ud83d\udd0d Invoice Due Date Filter\n\nFilters invoices based on due date criteria:\n\n**Conditions (ALL must be true):**\n1. Invoice has a due date\n2. Due within next 7 days\n3. Due date is today or later\n\n**Logic:**\n- Converts dates to Unix timestamps\n- Uses JavaScript expressions for calculations\n- Only passes invoices meeting all criteria"
},
"typeVersion": 1
},
{
"id": "007ad07d-634c-4cc1-b8e0-ad6f1c77a6ca",
"name": "Filter Due Invoices",
"type": "n8n-nodes-base.if",
"position": [
-1040,
64
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "has-due-date",
"operator": {
"type": "number",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.due_date }}",
"rightValue": ""
},
{
"id": "due-within-7-days",
"operator": {
"type": "number",
"operation": "lte"
},
"leftValue": "={{ $json.due_date }}",
"rightValue": "={{ Math.floor((Date.now() + (7 * 24 * 60 * 60 * 1000)) / 1000) }}"
},
{
"id": "due-after-today",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.due_date }}",
"rightValue": "={{ Math.floor(Date.now() / 1000) }}"
}
]
}
},
"typeVersion": 2
},
{
"id": "3309ccc7-bdd4-4582-a584-6f702ca74f9f",
"name": "Calendar API Setup",
"type": "n8n-nodes-base.stickyNote",
"position": [
-880,
256
],
"parameters": {
"width": 300,
"height": 352,
"content": "## \ud83d\udcc5 Google Calendar Setup\n\n**Configuration Steps:**\n1. Create Google Calendar OAuth2 credentials\n2. Select your target calendar\n3. Set time range (next 30 days)\n\n**Purpose:**\nFetches existing calendar events to check for duplicate invoice reminders.\n\n\u26a0\ufe0f **Note:** Replace the calendar ID with your actual calendar email"
},
"typeVersion": 1
},
{
"id": "07d2cba4-0897-4735-8c1d-5a9c9cb11006",
"name": "Google Calendar Get Events",
"type": "n8n-nodes-base.googleCalendar",
"position": [
-832,
64
],
"parameters": {
"end": "={{ Math.floor((Date.now() + (30 * 24 * 60 * 60 * 1000)) / 1000) }}",
"start": "={{ Math.floor(Date.now() / 1000) }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"additionalFields": {}
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "30f03054-10a8-4683-9db8-158e1959f139",
"name": "Duplicate Prevention",
"type": "n8n-nodes-base.stickyNote",
"position": [
-736,
-368
],
"parameters": {
"width": 280,
"height": 384,
"content": "## \ud83d\udd04 Duplicate Detection\n\n**Logic:**\n1. Extracts invoice IDs from existing calendar events\n2. Looks for pattern `invoice_id:XXXXXX` in event descriptions\n3. Compares current invoice ID with existing ones\n\n**Fields Created:**\n- `existing_invoice_ids`: Array of found invoice IDs\n- `current_invoice_id`: Current invoice being processed"
},
"typeVersion": 1
},
{
"id": "8b12c8ec-4252-4490-9a49-cba0c75f5b0d",
"name": "Check Invoice Exists",
"type": "n8n-nodes-base.set",
"position": [
-624,
64
],
"parameters": {
"fields": {
"values": [
{
"name": "existing_invoice_ids",
"stringValue": "={{ $input.all().map(event => {\n const description = event.json.description || '';\n const match = description.match(/invoice_id:([^\\s\\n]+)/);\n return match ? match[1] : null;\n}).filter(id => id !== null) }}"
},
{
"name": "current_invoice_id",
"stringValue": "={{ $('Filter Due Invoices').item.json.id }}"
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "c70a542d-d544-469e-8fd3-d29324727a45",
"name": "New Invoice Check",
"type": "n8n-nodes-base.stickyNote",
"position": [
-432,
224
],
"parameters": {
"width": 280,
"height": 312,
"content": "## \u2705 New Invoice Validation\n\n**Conditions (OR logic):**\n1. Invoice ID not found in existing events\n2. Current invoice ID exists and is valid\n\n**Result:**\nOnly new invoices (not already in calendar) will proceed to create calendar events."
},
"typeVersion": 1
},
{
"id": "a9703708-0584-4daf-90b3-e23b5b27410a",
"name": "IF Not Exists",
"type": "n8n-nodes-base.if",
"position": [
-416,
64
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "invoice-not-exists",
"operator": {
"type": "boolean",
"operation": "equal"
},
"leftValue": "={{ !$json.existing_invoice_ids.includes($json.current_invoice_id) }}",
"rightValue": true
},
{
"id": "8a1ef7b4-b24f-47ed-a9c6-bc5c0bd379c5",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.current_invoice_id }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2
},
{
"id": "f7570c80-326a-4248-85ff-6730f80a1168",
"name": "Calendar Event Setup",
"type": "n8n-nodes-base.stickyNote",
"position": [
-256,
-352
],
"parameters": {
"width": 300,
"height": 384,
"content": "## \ud83d\udcc5 Create Calendar Reminder\n\n**Event Details:**\n- **Title:** \"Pending Invoice\"\n- **Start Time:** Invoice due date\n- **Duration:** 1 hour\n- **Description:** Includes invoice ID for tracking\n\n**Customization Ideas:**\n- Add customer name to title\n- Include invoice amount\n- Set custom reminder times\n- Add invoice URL to description"
},
"typeVersion": 1
},
{
"id": "f57610fa-52d1-48f5-9a21-ac533ffcb1ac",
"name": "Google Calendar Create Event",
"type": "n8n-nodes-base.googleCalendar",
"position": [
-208,
64
],
"parameters": {
"end": "={{ new Date(($('Filter Due Invoices').item.json.due_date * 1000) + (60 * 60 * 1000)).toISOString() }}",
"start": "={{ new Date($('Filter Due Invoices').item.json.due_date * 1000).toISOString() }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "user@example.com"
},
"additionalFields": {
"summary": "Pending Invoice Due",
"attendees": []
}
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "04d55a9b-fe45-4185-978c-18144d689b01",
"connections": {
"IF Not Exists": {
"main": [
[
{
"node": "Google Calendar Create Event",
"type": "main",
"index": 0
}
]
]
},
"Split Invoices": {
"main": [
[
{
"node": "Filter Due Invoices",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get Stripe Invoices",
"type": "main",
"index": 0
}
]
]
},
"Filter Due Invoices": {
"main": [
[
{
"node": "Google Calendar Get Events",
"type": "main",
"index": 0
}
]
]
},
"Get Stripe Invoices": {
"main": [
[
{
"node": "Split Invoices",
"type": "main",
"index": 0
}
]
]
},
"Check Invoice Exists": {
"main": [
[
{
"node": "IF Not Exists",
"type": "main",
"index": 0
}
]
]
},
"Google Calendar Get Events": {
"main": [
[
{
"node": "Check Invoice Exists",
"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.
googleCalendarOAuth2ApistripeApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Automatically track Stripe invoices and create Google Calendar reminders for upcoming due dates. This workflow ensures you never miss a payment deadline by running daily checks, filtering invoices due within the next 7 days, and adding them to your calendar with invoice details.…
Source: https://n8n.io/workflows/8948/ — 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.
Small business owners, finance teams, accountants, and bookkeepers who use Xero for invoicing and want to improve cash flow by automating payment reminders. If you're spending time manually following
This is the ultimate sales-to-cash automation. When a deal in Airtable is marked "Approved for Invoicing," this workflow intelligently syncs customer data across QuickBooks and Stripe (creating them i
How It Works Trigger: Watches for new emails in Gmail with PDF/image attachments. OCR: Sends the attachment to OCR.space API (https://ocr.space/OCRAPI) to extract invoice text. Parsing: Extracts key f
Automated Stripe Payment to QuickBooks Sales Receipt
Tired of the standard, boring invoices from QuickBooks Online? This workflow completely automates the process of creating beautiful, custom-branded PDF invoices and emailing them directly to your clie