Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Windows Tipps & SecurityDave Plummer Has Made the Task Manager of Your Dreams(21.09.2026 um 21:20 Uhr)
Sichere ProgrammierungSubqueries and CTEs: Asking a Question Inside a Question(21.09.2026 um 21:00 Uhr)
Sichere ProgrammierungTVL Trend Analysis & Liquidity Risk Assessment: Lido(21.09.2026 um 21:00 Uhr)
Sichere ProgrammierungReact is Officially Dead in 2026 (Thanks to AI)(21.09.2026 um 21:01 Uhr)
Sichere ProgrammierungUsing SHA256 to Build Trustworthy Data Portals in Brazil(21.09.2026 um 21:01 Uhr)
Sichere Programmierung🚀 I reached 1,001 views on DEV!(21.09.2026 um 21:03 Uhr)
Sichere ProgrammierungReact Mental Models 2(21.09.2026 um 21:05 Uhr)
Sichere ProgrammierungAustralian RAM and SSD prices climb as stock tightens(21.09.2026 um 21:09 Uhr)
Windows Tipps & SecurityDave Plummer Has Made the Task Manager of Your Dreams(21.09.2026 um 21:20 Uhr)
Sichere ProgrammierungSubqueries and CTEs: Asking a Question Inside a Question(21.09.2026 um 21:00 Uhr)
Sichere ProgrammierungTVL Trend Analysis & Liquidity Risk Assessment: Lido(21.09.2026 um 21:00 Uhr)
Sichere ProgrammierungReact is Officially Dead in 2026 (Thanks to AI)(21.09.2026 um 21:01 Uhr)
Sichere ProgrammierungUsing SHA256 to Build Trustworthy Data Portals in Brazil(21.09.2026 um 21:01 Uhr)
Sichere Programmierung🚀 I reached 1,001 views on DEV!(21.09.2026 um 21:03 Uhr)
Sichere ProgrammierungReact Mental Models 2(21.09.2026 um 21:05 Uhr)
Sichere ProgrammierungAustralian RAM and SSD prices climb as stock tightens(21.09.2026 um 21:09 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Build a GST Invoice Generator in 87 Lines of Python

If you freelance or run a small business in India, you have probably paid for invoicing software that does one thing: multiply numbers and put them in a PDF. Today we will build that ourselves — a GST-compliant tax invoice generator that r…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

If you freelance or run a small business in India, you have probably paid for invoicing software that does one thing: multiply numbers and put them in a PDF. Today we will build that ourselves — a GST-compliant tax invoice generator that reads line items from a CSV and produces a clean PDF, in 87 lines of Python.



It handles the part everyone gets wrong: the CGST/SGST vs IGST split. Intra-state sales split the tax into equal CGST and SGST halves; inter-state sales charge a single IGST. Our script decides automatically by comparing the first two digits of the buyer's and seller's GSTINs (those digits are the state code).






What you'll need



One dependency:




pip install fpdf2






fpdf2 is a maintained, pure-Python PDF library — no system packages, works the same on Windows, Mac, and Linux.






The input format



Keep your line items in a plain CSV. Anyone on your team can edit this in Excel:




description,hsn,qty,rate,gst_pct
Website development,998314,1,45000,18
Annual hosting,998315,1,12000,18
SSL certificate,998316,2,1500,18









The full code






"""GST invoice generator — reads line items from CSV, outputs a PDF invoice."""
import csv
import sys
from datetime import date
from fpdf import FPDF

SELLER = {
"name": "Acme Tech Services Pvt Ltd",
"address": "221 MG Road, Bengaluru, KA 560001",
"gstin": "29ABCDE1234F1Z5",
"state_code": "29",
}


def load_items(path):
with open(path, newline="") as f:
return [
{
"desc": r["description"],
"hsn": r["hsn"],
"qty": float(r["qty"]),
"rate": float(r["rate"]),
"gst_pct": float(r["gst_pct"]),
}
for r in csv.DictReader(f)
]


def compute_totals(items, interstate):
rows, subtotal, tax_total = [], 0.0, 0.0
for it in items:
taxable = it["qty"] * it["rate"]
tax = taxable * it["gst_pct"] / 100
subtotal += taxable
tax_total += tax
rows.append((it, taxable, tax))
return rows, subtotal, tax_total


def build_pdf(rows, subtotal, tax_total, buyer, interstate, out_path):
pdf = FPDF()
pdf.add_page()
pdf.set_font("Helvetica", "B", 16)
pdf.cell(0, 10, "TAX INVOICE", align="C", new_x="LMARGIN", new_y="NEXT")
pdf.set_font("Helvetica", size=10)
pdf.cell(0, 6, f"{SELLER['name']} | GSTIN: {SELLER['gstin']}",
new_x="LMARGIN", new_y="NEXT")
pdf.cell(0, 6, SELLER["address"], new_x="LMARGIN", new_y="NEXT")
pdf.cell(0, 6, f"Invoice date: {date.today():%d-%m-%Y} | Bill to: "
f"{buyer['name']} (GSTIN: {buyer['gstin']})",
new_x="LMARGIN", new_y="NEXT")
pdf.ln(4)
pdf.set_font("Helvetica", "B", 9)
widths = (70, 20, 15, 25, 15, 25)
for w, h in zip(widths, ("Description", "HSN", "Qty", "Rate (Rs)",
"GST %", "Amount (Rs)")):
pdf.cell(w, 7, h, border=1)
pdf.ln()
pdf.set_font("Helvetica", size=9)
for it, taxable, _ in rows:
cells = (it["desc"], it["hsn"], f"{it['qty']:g}",
f"{it['rate']:,.2f}", f"{it['gst_pct']:g}", f"{taxable:,.2f}")
for w, v in zip(widths, cells):
pdf.cell(w, 7, str(v), border=1)
pdf.ln()
pdf.ln(3)
pdf.set_font("Helvetica", "B", 10)
pdf.cell(0, 6, f"Taxable value: Rs {subtotal:,.2f}",
new_x="LMARGIN", new_y="NEXT")
if interstate:
pdf.cell(0, 6, f"IGST: Rs {tax_total:,.2f}",
new_x="LMARGIN", new_y="NEXT")
else:
pdf.cell(0, 6, f"CGST: Rs {tax_total / 2:,.2f} SGST: "
f"Rs {tax_total / 2:,.2f}", new_x="LMARGIN", new_y="NEXT")
pdf.cell(0, 8, f"Grand total: Rs {subtotal + tax_total:,.2f}",
new_x="LMARGIN", new_y="NEXT")
pdf.output(out_path)


if __name__ == "__main__":
csv_path = sys.argv[1] if len(sys.argv) > 1 else "items.csv"
buyer = {"name": "Globex Retail LLP", "gstin": "27PQRSX5678G1Z3"}
interstate = buyer["gstin"][:2] != SELLER["state_code"]
rows, subtotal, tax_total = compute_totals(load_items(csv_path), interstate)
build_pdf(rows, subtotal, tax_total, buyer, interstate, "invoice.pdf")
print(f"invoice.pdf written - grand total Rs {subtotal + tax_total:,.2f}")






Run it:




python gst_invoice.py items.csv
# invoice.pdf written - grand total Rs 70,800.00









How it works



Loading (load_items). csv.DictReader turns each CSV row into a dict keyed by the header row, so the code reads like the spreadsheet. We cast qty, rate, and gst_pct to floats up front so the math functions never deal with strings.



The tax math (compute_totals). Each line's taxable value is qty x rate, and tax is a simple percentage of that. We accumulate a subtotal and a tax total and keep the per-row figures for the PDF table. The interstate decision happens once, in the entrypoint: buyer GSTIN state code != seller state code means IGST applies. In our example the buyer's GSTIN starts with 27 (Maharashtra) and the seller's with 29 (Karnataka), so the invoice shows a single IGST line. Change the buyer's GSTIN to start with 29 and you will see it split into equal CGST and SGST halves instead — no other change needed.



The PDF (build_pdf). fpdf2's cell() API is old-school but predictable: each cell has a fixed width, border=1 draws the table lines, and new_y="NEXT" moves the cursor down a row. The widths tuple is the entire layout — adjust six numbers and the whole table reflows. Total layout code: about 40 lines, and you own every pixel of it.






Extending it



A few upgrades that each take only a handful of lines: pull SELLER and the buyer from a JSON config instead of hardcoding; add an invoice number that auto-increments from a counter file; loop over a folder of CSVs to batch-generate a month of invoices; or add pdf.image("logo.png", x=10, y=8, w=30) for letterhead branding.



One honest caveat: this covers the common single-rate service invoice. If you deal with cess, reverse charge, or e-invoicing (IRN/QR codes), those are regimes of their own — treat this as the foundation, not a compliance department.



That's a working invoice pipeline in 87 lines — CSV in, compliant PDF out, and the tax split handled correctly without a subscription.



Follow me on Twitter @automate_archit for daily AI automation tips.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Build a GST Invoice Generator in 87 Lines of Python

Thematisch verwandte Begriffe: Build, Invoice, Generator, Lines · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-94494 | jshERP through 3.6 contains a tenant isolation bypass vulnerability that…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick