Invoice Number Check

Checks a GST invoice number against CGST Rule 46(b): 16 characters at most, only letters, digits, - and /, and unique in the financial year.

StopsHelps catch a GST invoice number the rules don't allow

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/invoice-number-check.json

The files land in your project. They're yours to edit.

Usage

invoice-number-check-usage.tsx
import { InvoiceNumberCheck, type IssuedInvoice } from "@/components/ui/invoice-number-check"

<InvoiceNumberCheck value={value} onValueChange={setValue} issued={issued} date="2026-10-14" placeholder="SK/26-27/0008" />

What it catches

  • More than 16 characters
  • Characters other than letters, digits, hyphen and slash
  • Number already used this financial year, including case-only differences and cancelled numbers
  • Financial-year token that doesn't match the invoice date
  • Skipped or reused counter and gaps in the series

Props

InvoiceNumberCheck props
PropTypeDefault
value

Controlled invoice number.

string—
defaultValue

Initial invoice number when uncontrolled.

string""
onValueChange

Called with the number on every change.

(value: string) => void—
issued

Invoices already issued under this GSTIN, any year.

IssuedInvoice[][]
date

This invoice's date; its financial year decides uniqueness and the reset. Defaults to today after mount.

Date | number | string—
einvoice

Apply the e-invoice rule that a number can't start with 0, / or -.

booleantrue
locale

BCP 47 locale for dates in messages.

string"en-IN"
messages

Override any visible string.

Partial<InvoiceNumberCheckMessages>—
wrapperClassName

Classes for the wrapper; `className` styles the input.

string—

* required. Also accepts the native props of <input> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Visible label; input has aria-invalid on errors and is described by the hint
  • Problems are announced in a polite live region; icons are aria-hidden
  • Fix and next-number buttons are real buttons; focus returns to the input after applying

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

This is a UX guard rail. Enforce on the server: Allocate invoice numbers on the server with a unique constraint per GSTIN and financial year.

  • Only checks against the issued list you pass; numbers issued elsewhere are unknown
  • Case-insensitive duplicate matching mirrors portal behaviour as the authors understood it, not a rule text
  • Doesn't validate the rest of the invoice (GSTIN, HSN, tax)

Rules

Rules last verified:

Informational; check the official source. Confirmed: consecutive serial number not exceeding sixteen characters, letters, numerals, - and /, one or multiple series, unique for a financial year. The case-insensitive portal comparison and e-invoice specifics are not from the rule text and were not verified. Copied components don't update themselves, so re-check after rule changes (see updating a component).

What it stops

Helps catch a GST invoice number the rules don't allow

Also known as

invoice number · gst invoice · bill number · cgst rule 46 · e-invoice · billing · invoice series · financial year

Field type

Dependencies

Pairs well with