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.
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 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 only a little 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.
What You'll Need (Prerequisites)
- Self-hosted n8n v1.62 or later (we run it on a 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
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
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;
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.
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.
The whole flow runs on infrastructure you control. For the messaging side, 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.
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.
Related reading
FAQ
How much does this n8n payment-reminder flow cost to run per month?
You pay for a self-hosted n8n on a Hetzner CX22, plus a fee per WhatsApp utility conversation. At ~600 reminders a month it replaces about 40 hours of manual phone chasing.
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. 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.
Book a 20-min Call
