n8n + WhatsApp: Auto Payment Reminders for Overdue Invoices
A 9-node n8n flow sends WhatsApp payment reminders by aging bucket, escalates copy at 30/45/60 days, injects the UPI link, and honours opt-outs. Built and tested June 2025.
Softechinfra Team
June 18, 202513 min read
0%
A 24-person Coimbatore textile-trading firm had ₹38 lakh stuck in overdue invoices across 142 buyers. Their accountant chased payments by phone, two hours a day, working off a stale Excel sheet. We replaced the chasing with a 9-node n8n workflow that sends WhatsApp reminders by aging bucket and stops the moment a buyer pays. After six weeks, days-sales-outstanding dropped from 71 to 49, and the accountant got her mornings back. This post is the exact build — nodes, copy, opt-out handling, and the UPI-link trick that moved the needle.
9
n8n Nodes End-to-End
71→49
Days Sales Outstanding
₹740/mo
Self-Hosted n8n (Hetzner)
3
Escalation Tiers
## The Answer in 60 Words
Run a daily n8n cron that reads unpaid invoices, sorts each into a 30/45/60-day aging bucket, and sends a WhatsApp template message with a UPI deep-link. Tone hardens as the invoice ages. A reply of "STOP" sets an opt-out flag and skips that buyer. Self-hosted n8n on a ₹740/month Hetzner box runs the whole thing for free beyond WhatsApp's per-conversation fee.
## Why This Matters Now (June 2025)
WhatsApp Business API re-priced to per-conversation billing in 2025, and "utility" template conversations — which payment reminders qualify as — cost roughly ₹0.30–₹0.55 each in India depending on your BSP. That is cheap enough that a daily reminder cadence is viable where SMS once was not. Meanwhile RBI's push on UPI means most Indian buyers will pay a ₹-amount-prefilled upi:// link in seconds. The combination — cheap messaging plus one-tap payment — is why dunning automation finally pays for itself for a 24-person firm.
A "dunning" sequence is the polite-to-firm series of reminders you send to collect an overdue invoice. The skill is in the escalation: friendly at day 30, direct at day 45, formal at day 60 — never robotic, never rude.
## What You'll Need (Prerequisites)
Self-hosted n8n v1.62 or later (we run it on a ₹740/month Hetzner CX22, tested June 2025)
A WhatsApp Business API number through a BSP — we used Meta Cloud API directly via the Graph API node
Three pre-approved WhatsApp message templates (Meta approval takes 1–24 hours)
An invoice data source: a Google Sheet, a Postgres table, or a Tally/Zoho Books export
A UPI VPA (virtual payment address) to build collect links against
One opt-out column in your data source (boolean), respected on every run
## The 9-Node Architecture
⏰
1. Cron Trigger
Fires once daily at 10:30 am IST. Mid-morning beats early-morning for read rates, and it dodges the lunch-hour drop.
📊
2. Read Invoices
Google Sheets or Postgres node pulls every row where status is unpaid AND opt_out is false. Nothing else gets touched.
🧮
3. Compute Aging
A Code node calculates days_overdue = today − due_date and tags each invoice 30, 45, or 60. Anything under 30 is skipped.
🔀
4. Switch by Bucket
A Switch node routes each invoice down one of three branches by its bucket tag, so each tier gets its own copy.
🔗
5. Build UPI Link
A Set node assembles a upi:// deep-link with the VPA, payee name, exact ₹ amount, and invoice number as the note.
💬
6. Send WhatsApp Template
An HTTP Request node hits the Meta Graph API with the right template per bucket, variables filled from the row.
📝
7. Log the Send
Write last_reminder_date and reminder_count back to the row. This is your idempotency guard against double-sends.
🛑
8. Opt-Out Webhook
A separate Webhook workflow listens for inbound "STOP" replies and flips opt_out to true for that number.
🚨
9. Escalation Alert
Any invoice that crosses 60 days posts to a Slack channel so a human takes over the relationship, not a bot.
As Hrishikesh, our CTO, frames it: the bot handles the boring 80% so a person can handle the awkward 20% with judgement. The Slack escalation in node 9 is the seam where that handoff happens.
## The DIY Walkthrough
1
Set up the data source with the right columns
Your sheet or table needs: invoice_no, buyer_name, buyer_phone (E.164, e.g. 919876543210), amount, due_date, status, opt_out, last_reminder_date, reminder_count. The last three are written by the flow, so start them empty.
2
Add the Cron trigger and the read node
Cron set to daily at 10:30. The read node filters server-side where possible: status = 'unpaid' and opt_out = false. Pulling only the rows you'll act on keeps the run fast and the API calls minimal.
3
Compute the aging bucket in a Code node
For each item, work out how many days the invoice is overdue and tag it. Skip anything under 30 days — chasing too early reads as pushy and burns goodwill.
Here's the Code node that does the bucketing. It also blocks a same-day double-send by checking last_reminder_date:
// n8n Code node — runs once per invoice item
const today = new Date();
const out = [];
for (const item of $input.all()) {
const inv = item.json;
const due = new Date(inv.due_date);
const daysOverdue = Math.floor((today - due) / 86400000);
// skip not-yet-due and recently-due invoices
if (daysOverdue < 30) continue;
// skip if already reminded today (idempotency guard)
if (inv.last_reminder_date === today.toISOString().slice(0, 10)) continue;
let bucket;
if (daysOverdue >= 60) bucket = 60;
else if (daysOverdue >= 45) bucket = 45;
else bucket = 30;
out.push({ json: { ...inv, daysOverdue, bucket } });
}
return out;
4
Build the UPI deep-link in a Set node
The link is the single detail that moves the needle most. A reminder with a one-tap pay link gets paid faster than one that says "please remit at your earliest convenience."
The UPI link format is a query string on the upi://pay scheme. Build it in a Set node expression:
// Set node — field "upi_link"
upi://pay?pa=yourfirm@hdfcbank
&pn=Your%20Firm%20Pvt%20Ltd
&am={{ $json.amount }}
&cu=INR
&tn=Invoice%20{{ $json.invoice_no }}
The am param prefills the exact amount, tn sets the transaction note to the invoice number so reconciliation is trivial, and cu=INR locks the currency. On most Android UPI apps this opens straight into the payment screen.
5
Wire the WhatsApp template send
Use an HTTP Request node to POST to the Meta Graph API messages endpoint. WhatsApp utility templates must be pre-approved by Meta — you cannot send free-form text outside the 24-hour customer window. Each bucket maps to its own approved template.
6
Log the send and write back
Set last_reminder_date to today and increment reminder_count. This is what stops the flow re-sending on the next run and gives you a clean audit trail of who was contacted when.
7
Build the opt-out webhook as a second workflow
Point your WhatsApp inbound webhook at an n8n Webhook node. If the message body, lowercased and trimmed, equals "stop", flip opt_out to true for that phone number. Reply once confirming they've been removed. This keeps you on the right side of WhatsApp policy and basic courtesy.
## The Escalation Copy (Tone Hardens With Age)
The copy is where most automated dunning fails — it stays flat and friendly until day 90, then suddenly threatens legal action. We tier it deliberately. Here is the structure we ship, written into the three approved templates:
| Bucket | Tone | Opening line (template body) | UPI link |
|---|---|---|---|
| 30 days | Friendly nudge | "Hi {{name}}, a quick reminder that invoice {{no}} for ₹{{amount}} was due on {{date}}." | Included |
| 45 days | Direct | "Hi {{name}}, invoice {{no}} (₹{{amount}}) is now 45 days overdue. Could you confirm a payment date?" | Included |
| 60 days | Formal | "Hi {{name}}, invoice {{no}} for ₹{{amount}} remains unpaid after 60 days. Please clear it this week or reply to discuss." | Included + Slack alert to owner |
Every message ends with the same opt-out line: "Reply STOP to pause reminders." That single line cut our complaint rate to zero across the buyer base. The 60-day branch also fires the Slack alert so the firm's owner — not the bot — picks up the phone.
Do not skip the 24-hour window rule. Outside a 24-hour window from the buyer's last message, you can only send pre-approved template messages. Free-form text will be silently rejected by Meta. Build all three reminders as templates from day one.
## A Cost Snapshot (Real ₹, June 2025)
Under ₹1,000 a month, running fully on infrastructure you control. For comparison, see our breakdown of WhatsApp Business API pricing traps for Indian SMBs — the per-conversation maths is where a lot of teams get surprised.
## Common Mistakes (When This Goes Wrong)
Symptom: "Buyers got the same reminder three times in one day." Cause: no idempotency guard. Fix: the last_reminder_date check in node 3 plus the write-back in node 6. Never run a dunning flow without a send-log.
Symptom: "Messages are being rejected by Meta." Cause: sending free-form text outside the 24-hour window. Fix: every reminder must be a pre-approved utility template. Submit them before you build the flow.
Symptom: "A buyer who already paid still got chased." Cause: payment status not synced back to the data source. Fix: reconcile payments daily — match the UPI transaction note (the invoice number) against open invoices and flip status to paid before the 10:30 run.
Symptom: "One angry buyer reported us." Cause: no opt-out path, or reminders starting too early. Fix: the STOP webhook plus the 30-day floor. Never chase an invoice that is only a week late.
## When Not to Build This
Skip the automation if you have fewer than ~15 open invoices at any time — a human with a phone is faster and warmer, and the WhatsApp template approval overhead is not worth it. Skip it too if your buyers are a handful of large enterprise accounts where every payment is a relationship managed by a named person; a bot reminder to a ₹40 lakh account reads as tone-deaf. This pattern shines for a long tail of small-to-mid invoices across many buyers — the exact shape of the Coimbatore firm's book.
## Real Example: The Coimbatore Textile Firm
The firm sold fabric to 142 small garment units across Tamil Nadu and Karnataka. Average invoice: ₹26,000. Their accountant spent two hours every morning calling overdue buyers off a spreadsheet she updated by hand. Half the calls went unanswered; the other half got "next week, sir."
We built the 9-node flow over a weekend and ran it for six weeks. Days-sales-outstanding fell from 71 to 49. The 30-day friendly nudge alone cleared 34% of the bucket within 72 hours — most buyers simply forgot, and a one-tap UPI link removed the friction. The accountant now reviews the Slack escalation list once a day and makes maybe four calls instead of forty. We have run the same pattern for our AI and automation clients in logistics and B2B services since — including the lead-and-collections pipeline we built for Radiant Finance, where the same reconcile-then-remind discipline cut chase time sharply.
"The first month, three buyers replied 'sorry, completely slipped my mind' and paid on the spot. That used to be a week of phone tag."
For a closely related build, see our n8n Razorpay failed-payment recovery workflow — that one targets cards that bounced at checkout, while this post targets invoices that went unpaid after delivery. Different problem, same n8n backbone. And if you want a buyer-facing bot rather than a one-way reminder, our n8n WhatsApp auto-reply workflow covers the two-way side.
## FAQ
### How much does this n8n payment-reminder flow cost to run per month?
Around ₹740/month for a self-hosted n8n on a Hetzner CX22, plus roughly ₹0.30–₹0.55 per WhatsApp utility conversation. At ~600 reminders a month that is under ₹1,000 total — versus about 40 hours of manual phone chasing it replaces.
### Can I send WhatsApp reminders without a Business API account?
No, not at scale. WhatsApp's personal and Business app block automated bulk sending. You need the WhatsApp Business API through a BSP or Meta Cloud API directly, with pre-approved templates. That is the only compliant path for automated reminders.
### Will buyers find automated payment reminders annoying?
Not if you tier the tone and offer an opt-out. Our Coimbatore build had zero complaints across 142 buyers. The keys are a 30-day floor (never chase a week-old invoice), a one-tap UPI link, and a "reply STOP" line on every message.
### How does the flow know a buyer has paid?
You reconcile payments back to the data source before each run. The UPI link sets the transaction note to the invoice number, so matching incoming UPI payments to open invoices is straightforward. Once an invoice is marked paid, the flow skips it.
### What happens after 60 days of no payment?
The 60-day branch sends a formal reminder and fires a Slack alert to the firm's owner. From there a human takes over the relationship. A bot is good at nudging; a person is better at the difficult conversation about a 60-day-old debt.
### Can I use Google Sheets instead of a database?
Yes. For under a few hundred invoices, a Google Sheet is fine and easier to audit by hand. Beyond that, a Postgres or MySQL table is faster and avoids the Sheets API rate limits. The n8n logic is identical either way.
### Is this compliant with WhatsApp's policies?
Yes, when you use approved utility templates, send only to opted-in buyers, and honour STOP requests immediately. Payment reminders for an existing business relationship fall under WhatsApp's "utility" category. Free-form marketing blasts do not — keep the two strictly separate.
Want Payment-Reminder Automation Built for Your Books?
We ship a working n8n + WhatsApp dunning flow for Indian SMBs in 7 working days, self-hosted on your infra. Typical project: ₹35k–₹70k. Suitable if you have a long tail of overdue invoices and someone chasing them by phone. No slides — just your aging report and our honest take.