n8n Weekend Build: Auto GST Invoices From Razorpay Payment Links
A Razorpay payment link gets paid, n8n builds a Rule 46 GST invoice PDF (GSTIN, HSN, sequential number) and emails it in 8 seconds. The full 16-node weekend build.
Hrishikesh Baidya
May 10, 202513 min read
0%
A Razorpay payment link gets paid at 11:42 pm. By 11:42:08, the buyer has a GST-compliant invoice PDF in their inbox — correct GSTIN, the right HSN code, a sequential invoice number that survives a tax audit. No human touched it. We built this for a Jaipur handicrafts exporter (12 staff, ₹6.4 Cr turnover) who was hand-typing 40 invoices a day into Word. This post is the full n8n build — 16 nodes, the webhook setup, the Rule 46 fields most templates get wrong, and the sequential-numbering trick that keeps the GST officer happy.
16
n8n nodes in the flow
8 sec
Payment to invoice in inbox
₹740/mo
Self-hosted run cost (Hetzner CX22)
40/day
Invoices the team stopped typing
## The Answer in 60 Words
Set a Razorpay webhook for the payment_link.paid event. n8n catches it, pulls the customer GSTIN and line items, increments a sequential invoice number stored in a Postgres counter, renders a Rule 46-compliant PDF with HSN codes and a tax split, emails it to the buyer, and writes a row to your books. Total build time on a Saturday: about five hours. Run cost: ₹740/month self-hosted.
## Why this matters now (May 2026)
GST 2.0 went live on April 1, 2026, dropping the e-invoicing threshold to ₹5 crore. A trader who clocked ₹5.2 Cr in FY 2025-26 is now in scope. Manual invoicing was already painful — now a missing HSN code or a non-sequential number can get an invoice rejected at the Invoice Registration Portal. We covered the rollout in detail in our GST 2.0 six-software-changes checklist. This build automates the part that breaks first: getting a valid invoice out the door the second money lands.
One thing up front: this flow generates a tax invoice PDF and your internal record. It does NOT push to the IRP for an IRN. If your turnover is above ₹5 Cr you still need e-invoicing — wire the IRP step in after the PDF node, or let Tally/Zoho Books own the IRN and use this flow for the customer-facing copy. We say which is which below.
## What you'll need (prerequisites checklist)
n8n v1.62 or later — self-hosted on a Hetzner CX22 (₹740/month) or n8n Cloud
A Razorpay account with API keys (test mode keys for the build, live keys for go-live)
A Postgres database for the sequential invoice counter (the same Hetzner box works)
Your firm's GSTIN, registered address, and HSN/SAC codes for what you sell
An SMTP account or a transactional email service (we used Amazon SES at ₹0.07/email)
A 4-digit HSN for turnover under ₹5 Cr, or 6-digit for ₹5 Cr and above (Rule 46 requirement)
## The Rule 46 fields most templates get wrong
Rule 46 of the CGST Rules, 2017 lists what a tax invoice must contain. Miss one and the invoice is technically invalid. Per the Razorpay GST invoice guide, the fields that trip up DIY templates are the HSN/SAC code, the place of supply, and the supplier-vs-recipient GSTIN pair that decides whether you charge IGST or CGST+SGST.
| Field | What breaks if you skip it | Where it comes from |
|---|---|---|
| Sequential invoice number (max 16 chars, per FY) | Audit flag; duplicate numbers void the invoice | Your Postgres counter |
| Supplier GSTIN + address | Invalid invoice | Hardcoded n8n env variable |
| Recipient GSTIN | No input tax credit for a B2B buyer | Razorpay notes or a lookup |
| HSN/SAC code | Rejected at IRP; penalty exposure | Mapped per product |
| Place of supply (state code) | Wrong tax split (IGST vs CGST+SGST) | Recipient state |
| Taxable value + tax rate + tax amount | Reconciliation mismatch in GSTR-1 | Computed in a Function node |
The IGST-vs-CGST rule in one line: if the supplier state code and the place-of-supply state code differ, charge IGST. If they match, split into CGST + SGST. We compute this in a single n8n Function node — code below.
## The 16-node flow (architecture)
📥
Webhook trigger
Razorpay fires payment_link.paid to an n8n Webhook node. We verify the X-Razorpay-Signature HMAC before doing anything else — unsigned requests get a 401.
🔢
Sequential counter
A Postgres node runs an atomic UPDATE...RETURNING on a single-row counter table. This guarantees no two invoices ever share a number, even under concurrent payments.
🧮
Tax computation
A Function node maps the product to its HSN, decides IGST vs CGST+SGST from the state codes, and computes the taxable value and tax split to two decimals.
📄
PDF render + email
An HTML template goes to a PDF service, then an SMTP node emails the buyer and a Postgres node logs the invoice row for GSTR-1 reconciliation later.
## Step-by-step build
1
Create the Webhook node and register it with Razorpay
Add an n8n Webhook node, POST method, path /razorpay-paid. Copy the production URL. In the Razorpay dashboard under Settings → Webhooks, add it and subscribe ONLY to payment_link.paid. Set a webhook secret — you'll need it for signature verification. Verification: trigger a test payment link in test mode and watch the node light up in n8n.
2
Verify the HMAC signature
Razorpay signs every webhook with HMAC-SHA256 of the raw body using your webhook secret. A Function node recomputes it and compares to the X-Razorpay-Signature header. Mismatch → throw an error and stop. This is the single most-skipped security step in n8n payment flows. Verification: send a request with a tampered body; the flow must reject it.
3
Increment the sequential invoice number
A Postgres node runs an atomic increment so concurrent payments never collide. The format is something like SI/2026-27/00042 — a prefix, the financial year, and a zero-padded counter. Verification: fire two test payments within the same second and confirm two distinct numbers.
4
Compute the GST split
The Function node reads the buyer's state code and the supplier's, picks IGST or CGST+SGST, applies the HSN's tax rate, and rounds to two decimals. Verification: an intra-state sale shows CGST + SGST; an inter-state sale shows a single IGST line.
5
Render the PDF
Pass the computed fields into an HTML template (your logo, GSTIN, the tax table, an amount-in-words line). Send the HTML to a PDF render service or a self-hosted Gotenberg container. Verification: open the PDF and check every Rule 46 field is present and the totals add up.
6
Email the buyer and log the row
An SMTP node attaches the PDF and sends it to the buyer's email from Razorpay's notes. A final Postgres node writes the invoice number, GSTIN, taxable value, and tax amounts to an invoices table for monthly GSTR-1 reconciliation. Verification: the buyer receives the email; the row appears in the table.
## The signature-verification node (copy this)
This is the Function node from step 2. It is the difference between a secure webhook and one anyone on the internet can forge.
javascript
const crypto = require('crypto');
const secret = $env.RAZORPAY_WEBHOOK_SECRET;
const signature = $request.headers['x-razorpay-signature'];
const rawBody = JSON.stringify($json.body); // use the raw body in n8n's binary/raw mode
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
if (expected !== signature) {
throw new Error('Invalid Razorpay signature — rejecting webhook');
}
// Only the paid event should reach the invoice path
if ($json.body.event !== 'payment_link.paid') {
return [];
}
const link = $json.body.payload.payment_link.entity;
return [{
json: {
amount: link.amount / 100, // Razorpay sends paise
currency: link.currency,
customerEmail: link.customer.email,
customerGstin: link.notes?.gstin || null,
stateCode: link.notes?.state_code || null,
hsn: link.notes?.hsn || null,
productName: link.description,
},
}];
Notice three things. The amount arrives in paise, so divide by 100. The GSTIN, HSN, and state code ride in Razorpay notes — you set these when you create the payment link, which keeps the build no-code on the data-entry side. And a non-paid event returns an empty array, so the flow short-circuits cleanly.
## The atomic invoice-number query
The sequential-number requirement is where DIY invoicing quietly breaks. If two payments land in the same second and you read-then-write the counter in two steps, you get duplicate numbers. A duplicate invoice number voids both invoices in an audit. The fix is one atomic statement in the Postgres node:
sql
UPDATE invoice_counter
SET last_number = last_number + 1
WHERE fy = '2026-27'
RETURNING last_number;
Postgres runs this as a single locked operation, so concurrent payments queue and each gets a unique value. We format it in the next node as SI/2026-27/00042. The financial-year segment means the series naturally resets every April — which Rule 46 requires.
## When NOT to build this yourself
Three situations where this flow is the wrong call. First, if your turnover is over ₹5 Cr and you need a real IRN, let Tally Prime or Zoho Books own the e-invoicing — they already handle the IRP handshake and the digitally signed QR code. Use n8n only for the customer-facing copy or skip it entirely. Second, if you issue fewer than five invoices a week, the five-hour build won't pay back; a paid template in Razorpay's own dashboard is faster. Third, if your line items are complex (multiple HSN codes per invoice, partial advances, credit notes), the simple single-product version here will fight you — that's a custom build, not a weekend flow.
## Real example: the Jaipur exporter
The client, a handicrafts exporter in Jaipur with 12 staff, was sending 40 payment links a day through Razorpay and then hand-typing each invoice into a Word template. Two people spent roughly three hours a day on it, and roughly one in twenty invoices went out with a wrong HSN or a skipped number — which their CA caught at month-end and sent back. We shipped this flow in a single Saturday. The same pattern powers the reconciliation side of our Razorpay-to-Zoho Books auto-reconcile flow, and it sits next to the Claude Vision invoice-extraction build on the inbound side. We've shipped variations of it through our AI and automation team for four other Indian SMBs since. Built by Hrishikesh, our CTO, who also wrote our 22-minute daily Razorpay-Tally close.
We saw the same payback shape wiring the billing automation for Radiant Finance, where moving manual document generation into a webhook flow removed the month-end rework entirely. Outcome after one month: zero rejected invoices, six person-hours a day handed back to the team, and a clean GSTR-1 that reconciled on the first pass. We crosschecked the webhook approach against the r/n8n community, where the atomic-counter pattern is the consensus fix for the duplicate-number problem.
## Cost comparison: build vs SaaS
The honest read: at ₹740 vs ₹749, n8n self-hosted and Zoho Books cost almost the same per month. The reason to build is control — custom invoice layouts, your own numbering scheme, and the same n8n instance running ten other flows. If invoicing is all you need, Zoho Books is less work. We say so to clients before they pay us.
## FAQ
### Does this flow create a legal e-invoice with an IRN?
No. It creates a Rule 46-compliant tax invoice PDF and your internal record. An e-invoice with an IRN requires uploading to the Invoice Registration Portal. If your turnover is ₹5 Cr or more, add an IRP node after the PDF step, or let Tally/Zoho own the IRN.
### How do I stop duplicate invoice numbers under load?
Use a single atomic SQL statement — UPDATE...RETURNING on a counter row — instead of reading then writing in two steps. Postgres locks the row, so concurrent payments each get a unique number. This is the consensus fix in the n8n community.
### Where do the GSTIN and HSN come from if it's a payment link?
You set them in Razorpay notes when creating the link. The webhook delivers them back to n8n. For repeat B2B buyers, you can instead look up the GSTIN from a Postgres customer table keyed on email.
### What does it cost to run per month?
About ₹740/month on a Hetzner CX22 self-hosted, plus roughly ₹0.07 per email through Amazon SES. At 40 invoices a day that's under ₹100/month in email. The build itself was a one-time five-hour effort.
### Can I send the invoice over WhatsApp instead of email?
Yes. Swap the SMTP node for a WhatsApp Business API node and attach the PDF as a document message. We do this for buyers who never open email — the WhatsApp open rate in our projects runs far higher than email for invoice delivery.
### How do I handle a refund or a credit note?
Subscribe to payment_link.refunded as well and branch the flow. A refund triggers a credit-note PDF with its own sequential series (Rule 46 treats credit notes as a separate document type). Keep the credit-note counter separate from the invoice counter.
### Will this reconcile cleanly with GSTR-1?
Yes, because every invoice writes a row with the taxable value, tax rate, and tax amount to a Postgres table. At month-end you export that table and tie it to GSTR-1. We pair this with our GSTR-3B reconciliation sprint for the filing side.
Want this invoicing flow built and self-hosted on your infra?
We ship a working v1 in 7 working days — Razorpay or Cashfree webhook, Rule 46-compliant PDFs, sequential numbering, and IRP wiring if your turnover needs it. Typical cost: ₹45k–₹85k. Suitable if you're issuing 20+ invoices a day by hand. No slides — just your problem and our honest take.