Validate GSTIN

Validates a given Indian GSTIN (Goods and Services Tax Identification Number) based on format, state code, and embedded PAN.

Contributed by @PankajBaliyan

javascript
function validateGSTIN(gstin) {
  // Regex for GSTIN: 2 digits, 5 letters, 4 digits, 1 letter, 1 digit, 1 letter, 1 alphanumeric
  const gstinRegex = /^[0-3][0-9][A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/;
 
  if (!gstinRegex.test(gstin)) return false;
 
  const validStateCodes = [
    "01", "02", "03", "04", "05", "06", "07", "08", "09", "10",
    "11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
    "21", "22", "23", "24", "25", "26", "27", "28", "29", "30",
    "31", "32", "33", "34", "35", "36", "37"
  ];
  const stateCode = gstin.slice(0, 2);
  if (!validStateCodes.includes(stateCode)) return false;
 
  const pan = gstin.slice(2, 12);
  const panRegex = /^[A-Z]{5}[0-9]{4}[A-Z]{1}$/;
  const validFirstChars = ['C', 'P', 'H', 'F', 'A', 'B', 'G', 'J', 'L', 'T'];
  if (!panRegex.test(pan) || !validFirstChars.includes(pan[0])) return false;
 
  if (gstin[13] !== 'Z') return false;
 
  return true;
}
javascript
// Valid GSTINs
validateGSTIN("29ABCDE1234F1Z5"); // true
validateGSTIN("27AABCU1234F1Z6"); // true
validateGSTIN("10AABCD1234F1Z7"); // true
validateGSTIN("19AABCE1234F1Z8"); // true
 
// Invalid GSTINs
validateGSTIN("29ABCDE1234F1Z"); // false - missing last character
validateGSTIN("12345ABCDE123F1Z"); // false - invalid state code and format
validateGSTIN("ABCD1234F1Z5"); // false - too short
validateGSTIN("29ABCDE1234F1Z5Z"); // false - extra character
validateGSTIN("12ABCD12345F1Z5"); // false - invalid PAN format
GitHubEdit on GitHub