A rental business that collects every day, without anyone chasing anyone.
Two apps were written by hand — the one the driver holds, the one the ops desk works in. Everything that happens between them is fourteen self-hosted n8n workflows: the money, the messages, the escalations and the locks.
Rent is due daily. Nobody can phone a thousand people daily.
Go2Green rents electric two- and three-wheelers to gig delivery workers in Bengaluru — food, grocery, meat, last-mile parcel. The economics only work if rent lands every single day, from a population that is paid daily, banks on UPI, and switches platforms constantly.
Weekly bank mandates were the obvious answer and the wrong one: per-debit mandate friction, NPCI daily limits, and a failed debit that tells you nothing until the money is already a week gone. So the money model became a prepaid wallet — the driver loads it, and an internal ledger debits the day’s rent at a fixed hour. No bank transaction per day, no mandate to fail.
Which moves the entire problem into operations. A wallet that debits daily needs somebody watching balances, sending reminders before the debit and receipts after, routing KYC, escalating non-payers through a grace period, and — at the end of that ladder — immobilizing a vehicle safely and reversibly. At a thousand drivers that is not a job. It is a scheduler.
Write the app. Don’t write the back office.
Two things a human touches were built properly, in code: a React Native driver app and a Next.js admin console over Postgres with row-level security. Those are product surfaces, and product surfaces earn their handwritten code.
The rest — the cron jobs, the retries, the WhatsApp templates, the “if balance falls below X then” ladders, the webhook reconciliation — is the part of every fintech that quietly becomes forty thousand lines of untested glue nobody wants to own. That went to n8n, self-hosted beside the database.
What a human touches
- Driver app — React Native, six languages, self-onboarding.
- Admin console — Next.js, RBAC across five roles.
- The wallet ledger itself — integer paise, immutable rows.
- Postgres + RLS, object storage, the audit schema.
What happens on its own
- The daily debit run, and every receipt after it.
- Low-balance and dunning ladders, WhatsApp and email.
- KYC routing — Cashfree Secure ID into the review queue.
- Cashfree webhook intake and nightly reconciliation.
- The immobilization approval chain and its release.
The line between the two is deliberate and enforced: n8n never computes a balance. It calls a Postgres function that does, inside a transaction. Workflows decide when, and who to tell. The database decides what is true.
Four things wake the system up. Everything else is a consequence.
No screenshots: the system is live and holds a client’s driver, KYC and payment records. This is the orchestration it runs.
Not because it was quicker. Because of where it runs and what it exports.
Automation platforms are mostly interchangeable until you put Aadhaar numbers and money through them. Two constraints eliminated the field, and n8n was what survived.
It runs on the client’s own metal
Aadhaar e-KYC payloads, PAN, selfies and the full payment ledger pass through these workflows. Under the DPDP Act that data cannot casually transit a third-party automation cloud in another jurisdiction. n8n is self-hosted in-region, in the same private network as Postgres — so the sensitive hop never leaves the client’s infrastructure at all. This alone ruled out every hosted-only option.
A workflow is a JSON file
Every workflow exports as JSON, so it lives in git, arrives by pull request, and gets reviewed like any other change. The audit log records which workflow version caused each side effect. A visual tool you cannot diff has no business moving money; this one you can.
Real code where it’s needed
The awkward 5% — Cashfree signature verification, idempotency-key construction, six-language template selection — is written as TypeScript in Code nodes rather than contorted into drag-and-drop conditionals. The other 95% stays visual, which is exactly the part the ops lead needs to be able to read.
Priced per server, not per task
A thousand drivers generate a debit, up to two reminders, a receipt and assorted webhook traffic every day — six figures of task executions a month, growing linearly with the fleet. On per-task pricing the automation layer would have become a cost centre that punishes growth. Self-hosted, it is one VM.
Fourteen workflows. Each one does a single thing and says so.
Eight carry the business. The remaining six are plumbing: the shared error handler, the audit writer, the WhatsApp send sub-workflow, the template resolver, a health probe and the staging smoke test. The node chain under each one below is the actual shape of the workflow.
01 · Daily debit run
Schedule trigger · 06:00 IST · 11 nodesOne cron, batched by city. For each active assignment it calls a Postgres function that debits the day’s rent inside a transaction and returns the new balance. The workflow never does the arithmetic — it fans out, collects outcomes, and a Switch sends each one where it belongs: a receipt, a shortfall notice, or the retry lane.
02 · Low-balance ladder
Schedule trigger · T−6h, T−1h · 9 nodesFires twice before the debit, only for wallets that will not cover tomorrow. A Postgres query does the selection, so the “who is short” logic has exactly one home. Deduplicated per driver per day against a sent-messages table — a driver who tops up between the two never receives the second message.
03 · Cashfree webhook intake
Webhook trigger · 8 nodesSignature verified in a Code node, then written to a raw-event table keyed on the gateway’s own reference before anything else happens. A duplicate delivery hits the unique index and stops there. Only then does a Switch route by event type — top-up, autopay debit, payout, refund — into the ledger. Replaying a week of events changes no balances.
04 · KYC router
Webhook trigger · from driver app · 12 nodesAadhaar offline e-KYC and PAN through Cashfree Secure ID, selfie through liveness and face-match, the three calls running in parallel branches and merging. Clean passes queue as pre-approved; anything ambiguous routes to a human with the failing check named. Aadhaar is masked in a Code node before it is ever persisted, so the full number exists only in memory for the length of one execution.
05 · Dunning and escalation
Schedule trigger · daily · 13 nodesA shortfall opens a grace window whose length is read from the config table the client edits in the admin console — not hard-coded in the workflow. Reminders on a schedule, then a call task for the ops desk, then — and only then — the driver becomes eligible for the lock chain. Eligibility is a flag. It is never the lock itself.
06 · Immobilization chain
Webhook trigger · from admin console · 15 nodesThe most guarded workflow on the system. It refuses to start unless eligibility is already set, waits on a second approver from a different role, warns the driver, and re-reads live telematics at the last node before the command — if speed is not zero it aborts and reschedules. Prevent-restart only. The release path is a separate, much shorter workflow with no approval gate at all.
07 · Nightly reconciliation
Schedule trigger · 02:00 IST · 10 nodesPulls the gateway’s settled transactions for the day, diffs them against the ledger in a Code node, and files any row that exists on one side and not the other as a finance task. Finance hears about a mismatch over morning coffee rather than at month end.
08 · Deposit refund
Webhook trigger · on vehicle return · 9 nodesSettles outstanding dues against the deposit, initiates the balance as a Cashfree payout, and then stops — the assignment stays open until the payout webhook confirms, at which point workflow 03 closes it. Money leaving the business is never assumed to have left.
The one that moves the money, every morning at six.
The hardest workflow is the one that takes someone’s livelihood away.
Every rung is reversible and every rung is logged. The asymmetry is deliberate: locking a vehicle takes two people and four checks, unlocking it takes a successful payment.
What it takes before you trust a workflow with money.
A default n8n install is a prototyping tool. Six things turned it into something a payments back office can sit on.
Queue mode, not single-process
n8n runs in queue mode with Redis and separate worker processes. The 06:00 debit run for the whole fleet does not block a Cashfree webhook arriving in the same second, and a worker restart mid-batch resumes rather than loses.
One shared error workflow
Every workflow points at the same error handler. A failed execution becomes an ops task with the input payload attached, plus an alert if it touched money. Nothing fails into a log file nobody reads.
Sub-workflows for shared work
Sending a WhatsApp message — resolve the template, pick one of six languages, fall back to email, record what was sent — is one sub-workflow called by five others. The WABA credential is configured in exactly one place.
A staging instance that matters
Workflows are imported into staging against gateway sandbox credentials and a seeded database, and a smoke-test workflow runs the full debit path before anything is promoted. Nobody edits nodes on the production canvas.
Credentials scoped and rotated
Cashfree, WABA and the telematics vendor each hold their own credential with its own role; the Postgres credential n8n uses cannot read the KYC document table at all. Rotation is a config change, not a hunt through nodes.
Policy lives in the console
Daily rent, deposit, auto-reload threshold and grace period are rows the client edits in the admin app and the workflows read at runtime. Changing the grace window from two days to three is an operations decision, not a deployment.
Collections became a scheduled job.
- 1,000+ renters onboarded and collecting daily, with no collections headcount added.
- A debit that does not go through is a shortfall, never a technical failure — the retry lane and the dead-letter handler mean an error can no longer be mistaken for non-payment.
- Reminders before the debit do most of the work — the overwhelming majority of shortfalls resolve inside the grace window, before a lock is ever requested.
- 8 weeks from spec to launch in Bengaluru, across Android, iOS and the admin console, in six languages.
- ₹10L+ has moved through the wallet, every paisa of it against a ledger row with a workflow run behind it.
- The gateway and the ledger reconcile every night. Finance finds out about a mismatch the next morning, not at month end.
- Adding a city is a config row and a WhatsApp template — the workflows do not know how many cities there are.
Is your back office a person with a spreadsheet and an alarm?
Start with a two-week operations leak audit. We map the work that happens on a schedule, the work that happens because somebody remembered, and the money that moves in between — then show you which of it should be a workflow. Applies against the build if you continue.
Book the leak audit