DEV Community

Subhendu Das
Subhendu Das

Posted on

GSTR-2B Reconciliation with GSTBot: AI‑Powered Accuracy

Feature Spotlight: GSTR‑2B Reconciliation with Tolerances

In the Indian GST ecosystem, the GSTR‑2B feed is the authoritative record of purchases that a taxpayer must match against invoices received from vendors. For small‑to‑medium businesses, the volume of invoices—often hundreds per month—makes a manual, string‑by‑string comparison tedious and error‑prone. GSTBot addresses this bottleneck with an automated reconciliation engine that tolerates minor discrepancies while still flagging genuine mismatches. The engine is a core component of the GST reconciliation software that powers GSTBot.

The Problem

When a vendor issues an invoice, the details recorded on the paper or PDF may differ from the values captured in the GSTR‑2B feed. Common sources of variance include:

  • Rounding differences in tax amounts (e.g., 18% of ₹10,000 may appear as ₹1,800 in one source and ₹1,799.99 in another).
  • Minor typographical errors in invoice numbers or vendor names.
  • Different date formats or time zones that shift the effective invoice date by a day.

Traditional reconciliation tools rely on exact string matching across all fields. A single mismatch in the vendor name or a cent‑level difference in the taxable value causes the entire line to be flagged as an exception. For SMBs, this leads to a backlog of manual investigations and delays in filing returns.

How GSTBot’s Tolerant Reconciliation Works

GSTBot implements a two‑phase reconciliation pipeline built on FastAPI, PostgreSQL, Redis, and Celery. The pipeline is exposed through a FastAPI endpoint that accepts a batch ID and triggers a Celery task. The task retrieves invoice records from PostgreSQL, fetches the corresponding GSTR‑2B entries via the tax portal API, and compares them using configurable tolerances.

1. Data Ingestion

Invoices are ingested through AI extraction modules that populate the invoices table:

CREATE TABLE invoices (
    id SERIAL PRIMARY KEY,
    batch_id INTEGER REFERENCES batches(id),
    vendor_name TEXT,
    gstin TEXT,
    invoice_number TEXT,
    invoice_date DATE,
    taxable_value NUMERIC(12,2),
    tax_rate NUMERIC(5,2),
    hsn_code TEXT,
    extracted_at TIMESTAMP DEFAULT now()
);
Enter fullscreen mode Exit fullscreen mode

The GSTR‑2B feed is stored in gstr2b_entries with a similar schema.

2. Reconciliation Logic

The core comparison logic resides in a Celery task:

@celery.task
def reconcile_batch(batch_id: int):
    invoices = db.session.query(Invoice).filter_by(batch_id=batch_id).all()
    gstr_entries = fetch_gstr2b_entries(batch_id)
    tolerance = config.get('TAXABLE_TOLERANCE')  # e.g., 0.5 for ₹0.50

    for inv in invoices:
        match = next(
            (e for e in gstr_entries
             if e.vendor_name.lower() == inv.vendor_name.lower()
             and abs(e.taxable_value - inv.taxable_value) <= tolerance),
            None
        )
        if match:
            record_success(inv.id, match.id)
        else:
            classify_exception(inv)
Enter fullscreen mode Exit fullscreen mode

The TAXABLE_TOLERANCE value is configurable through the admin UI and defaults to ₹0.50. By comparing the absolute difference between the taxable values rather than requiring exact equality, the system accepts minor rounding errors while still ensuring that the vendor and invoice numbers align.

3. Exception Classification

When no match is found, GSTBot classifies the exception into one of several categories:

  • Missing Entry: No corresponding GSTR‑2B record.
  • Amount Discrepancy: Difference exceeds tolerance.
  • Vendor Mismatch: Vendor name or GSTIN differs.

Each exception is stored in the exceptions table with a recommended action, such as “Verify vendor details” or “Adjust taxable value.” The classification logic uses simple conditional checks and is easily extendable.

4. Caching and Performance

Redis is leveraged to cache the GSTR‑2B feed for the duration of the reconciliation run, reducing repeated API calls. The Celery workers process batches in parallel, and PostgreSQL’s indexes on vendor_name and invoice_number accelerate lookups.

User Experience

From an accountant’s perspective, the reconciliation result appears as a concise table in the React‑based dashboard. Each row shows:

  • Invoice reference
  • GSTR‑2B status (matched, exception)
  • Exception type (if any)
  • Suggested action

Accountants can click on a row to open a detailed view, which presents the raw invoice data, the matched GSTR‑2B line, and a side‑by‑side diff of the taxable amounts. The UI also provides bulk actions—e.g., “Mark all matched as verified”—to speed up the filing workflow.

Impact on Compliance

By automating the reconciliation against the GSTR‑2B feed with tolerances, GSTBot reduces manual effort, minimizes the risk of input tax credit (ITC) misstatements, and ensures that the GSTR‑1 and GSTR‑3B data generated for the portal are accurate. The feature aligns with the broader goal of GST compliance automation for small businesses in India.

External Integration

GSTBot also exposes a GraphQL API that allows external systems to query reconciliation status in real time. The API is built on FastAPI's dependency injection, ensuring that authentication and rate limiting are handled uniformly across all endpoints.

Top comments (0)