This workflow corresponds to n8n.io template #16709 — 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": "WBCve3h1YahbsDnP",
"name": "Send fee-due reminders to coaching center students via WhatsApp",
"tags": [],
"nodes": [
{
"id": "3930a520-32c1-4130-959f-97698dfc53b4",
"name": "Workflow overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-32,
-352
],
"parameters": {
"color": 7,
"width": 480,
"height": 1272,
"content": "## Send fee-due reminders to coaching center students via WhatsApp\n\n## Who's it for\nCoaching centers, tuition classes, and training institutes that chase fee defaulters manually every month. Replaces that manual follow-up with an automated WhatsApp reminder sent a few days before each student's fee is due.\n\n## How it works\nOnce a day, this workflow checks Supabase for students whose fee due date is exactly 3 days away and who haven't already been reminded for that due date. For each one, it sends a pre-approved WhatsApp template with the student's name, amount due, and due date, then marks that reminder as sent so it isn't repeated.\n\nThis is a v1 focused purely on reminders, it does not include a payment link or auto-track payment status. Staff confirm payment manually once received. A future version can add a payment link and automatic reconciliation.\n\n## How to set up\n1. Create a Supabase project and run the schema in the blue sticky note below.\n2. Add your Supabase credentials in n8n.\n3. Add your Meta WhatsApp Business Cloud API credentials using a permanent system user token.\n4. Create and get approval for a simple text WhatsApp template (e.g. \"Hi {{1}}, your fee of {{2}} is due on {{3}}. Please pay at your earliest convenience.\") and set its name in the Send Template node.\n5. Activate the workflow.\n\n## Requirements\n- Supabase project (free tier works)\n- Meta WhatsApp Business Cloud API access with a phone number ID and an approved text template\n- Student fee records already logged in the `student_fees` table\n\n## How to customize\n- Change how many days before the due date the reminder is sent.\n- Add a second reminder for overdue fees that goes out after the due date passes.\n- Add a Razorpay payment link to the message once you're ready to automate collection."
},
"typeVersion": 1
},
{
"id": "436d3a42-34ef-464b-a8ec-16ff1967a1dc",
"name": "Schema reference",
"type": "n8n-nodes-base.stickyNote",
"position": [
-32,
944
],
"parameters": {
"color": 4,
"width": 444,
"height": 388,
"content": "### Supabase schema needed\n\n```sql\ncreate table student_fees (\n id uuid primary key default gen_random_uuid(),\n student_name text not null,\n student_phone text not null,\n amount_due numeric not null,\n due_date date not null,\n reminder_sent boolean default false,\n status text default 'pending',\n created_at timestamptz default now()\n);\n```"
},
"typeVersion": 1
},
{
"id": "ff074120-b3b7-4b95-b3f5-2e3bbca68cf7",
"name": "Step 1 note",
"type": "n8n-nodes-base.stickyNote",
"position": [
544,
592
],
"parameters": {
"color": 0,
"width": 260,
"height": 196,
"content": "### Step 1\nRuns once a day. Adjust the time of day to whenever works best for your center."
},
"typeVersion": 1
},
{
"id": "81b3a7da-f931-4a4d-9db4-6c3817ebc663",
"name": "Step 2 note",
"type": "n8n-nodes-base.stickyNote",
"position": [
864,
592
],
"parameters": {
"color": 0,
"width": 280,
"height": 200,
"content": "### Step 2\nQueries Supabase for fee records that haven't been reminded yet and are still pending."
},
"typeVersion": 1
},
{
"id": "5e39e133-e294-458e-9563-7a1dc9702a3e",
"name": "Step 3 note",
"type": "n8n-nodes-base.stickyNote",
"position": [
1248,
608
],
"parameters": {
"color": 0,
"width": 260,
"height": 164,
"content": "### Step 3\nFilters to only fees due in exactly 3 days from today."
},
"typeVersion": 1
},
{
"id": "4c57fcf7-980e-48cf-bdc6-a5bd048c3282",
"name": "Step 4 note",
"type": "n8n-nodes-base.stickyNote",
"position": [
1776,
624
],
"parameters": {
"color": 0,
"width": 280,
"height": 168,
"content": "### Step 4\nSends the approved WhatsApp template with the student's name, amount due, and due date."
},
"typeVersion": 1
},
{
"id": "a42e41f3-d4d2-4393-8800-bd17b689ab52",
"name": "Step 5 note",
"type": "n8n-nodes-base.stickyNote",
"position": [
2192,
624
],
"parameters": {
"color": 0,
"width": 260,
"height": 164,
"content": "### Step 5\nMarks the reminder as sent so it's not sent again on the next run."
},
"typeVersion": 1
},
{
"id": "0a067de2-f5c2-4db1-9881-19909822c35b",
"name": "Send WhatsApp fee reminder",
"type": "n8n-nodes-base.whatsApp",
"position": [
1888,
416
],
"parameters": {
"template": "REPLACE_WITH_YOUR_APPROVED_TEMPLATE_NAME",
"components": {
"component": [
{}
]
},
"phoneNumberId": "REPLACE_WITH_YOUR_PHONE_NUMBER_ID",
"recipientPhoneNumber": "={{ $json.student_phone }}"
},
"credentials": {
"whatsAppApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "bd13e9e7-4381-42d2-81a4-1aa38665a445",
"name": "Every day at (9-am)",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
608,
432
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 9
}
]
}
},
"typeVersion": 1.3
},
{
"id": "cfc629ca-8a80-4f3c-b71d-823feb5c9cd8",
"name": "Get pending fee records",
"type": "n8n-nodes-base.supabase",
"position": [
960,
432
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "reminder_sent",
"keyValue": "false",
"condition": "eq"
},
{
"keyName": "status",
"keyValue": "pending",
"condition": "eq"
}
]
},
"tableId": "student_fees",
"operation": "getAll",
"returnAll": true
},
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "4cd2bb21-c7ea-4779-8344-6b56832f9c62",
"name": "Due (3 days)",
"type": "n8n-nodes-base.filter",
"position": [
1296,
432
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b5c94d14-d457-4efe-8bf7-cdefc34ccb0c",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ new Date($json.due_date).toDateString() }}",
"rightValue": "={{ new Date(Date.now() + 3 * 24 * 60 * 60 * 1000).toDateString() }}"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "b0ce1551-154c-4450-8fbc-78d90b575040",
"name": "Loop Over Fee Reminders",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1568,
432
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "7a3dc32b-08c6-4e77-8a89-97bc9e2a5ed8",
"name": "Mark reminder as sent",
"type": "n8n-nodes-base.supabase",
"position": [
2256,
416
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "id",
"keyValue": "={{ $('Loop Over Fee Reminders').item.json.id }}",
"condition": "eq"
}
]
},
"tableId": "student_fees",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "reminder_sent",
"fieldValue": "true"
}
]
},
"operation": "update"
},
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
}
],
"active": true,
"settings": {
"binaryMode": "separate",
"callerPolicy": "workflowsFromSameOwner",
"timeSavedMode": "fixed",
"availableInMCP": false,
"executionOrder": "v1",
"executionTimeout": -1
},
"versionId": "aa38c86a-b63a-478b-b641-0962637a9eda",
"nodeGroups": [],
"connections": {
"Due (3 days)": {
"main": [
[
{
"node": "Loop Over Fee Reminders",
"type": "main",
"index": 0
}
]
]
},
"Every day at (9-am)": {
"main": [
[
{
"node": "Get pending fee records",
"type": "main",
"index": 0
}
]
]
},
"Mark reminder as sent": {
"main": [
[
{
"node": "Loop Over Fee Reminders",
"type": "main",
"index": 0
}
]
]
},
"Get pending fee records": {
"main": [
[
{
"node": "Due (3 days)",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Fee Reminders": {
"main": [
[
{
"node": "Send WhatsApp fee reminder",
"type": "main",
"index": 0
}
]
]
},
"Send WhatsApp fee reminder": {
"main": [
[
{
"node": "Mark reminder as sent",
"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.
supabaseApiwhatsAppApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow runs daily to fetch pending student fee records from Supabase, filters fees due in three days, and sends WhatsApp Business template reminders via the Meta WhatsApp Cloud API, then updates Supabase to mark each reminder as sent. Runs every day at 9:00 AM on a…
Source: https://n8n.io/workflows/16709/ — 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.
This workflow runs daily to pull gym members from Supabase, calculate membership expiry and check-in activity, and send WhatsApp messages for renewal reminders, trainer inactivity alerts, and check-in
This workflow runs every 15 minutes to find unprocessed clinic appointments in Supabase that are more than 30 minutes past their scheduled time and sends a WhatsApp Business template message to the pa
Wait Schedule. Uses spotify, supabase, compareDatasets, noOp. Scheduled trigger; 54 nodes.
This workflow is designed for **customer support teams, e-commerce founders, and operations managers** who want to handle thousands of customer queries seamlessly. Instead of building a brand-new chat
Regua-De-Cobrancas. Uses httpRequest, emailSend, whatsApp, twilio. Scheduled trigger; 25 nodes.