UNPKG

sgf-gstin-validator

Version:

Module to validate GSTIN and verify Signed QR of GST eInvoice

198 lines 7.67 kB
'use strict'; var jwt = require('jsonwebtoken'); var certs = require('./certs.js'); function calcCheckSum(gstin) { var GSTN_CODEPOINT_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; var factor = 2; var sum = 0; var checkCodePoint = 0; var mod = GSTN_CODEPOINT_CHARS.length; var i; for (i = gstin.length - 2; i >= 0; i--) { var codePoint = -1; for (var j = 0; j < GSTN_CODEPOINT_CHARS.length; j++) { if (GSTN_CODEPOINT_CHARS[j] === gstin[i]) { codePoint = j; } } var digit = factor * codePoint; factor = factor === 2 ? 1 : 2; digit = Math.floor(digit / mod) + (digit % mod); sum += digit; } checkCodePoint = (mod - (sum % mod)) % mod; return GSTN_CODEPOINT_CHARS[checkCodePoint]; } // GSTIN Regex validation result function validatePattern(gstin) { // eslint-disable-next-line max-len var gstinRegexPattern = /^([0-2][0-9]|[3][0-8])[A-Z]{3}[ABCFGHLJPTK][A-Z]\d{4}[A-Z][A-Z0-9][Z][A-Z0-9]$/; return gstinRegexPattern.test(gstin); } function isValidGSTNumber(gstin) { gstin = gstin.toUpperCase(); if (gstin.length !== 15) { return false; } if (validatePattern(gstin)) { return gstin[14] === calcCheckSum(gstin.toUpperCase()); } return false; } function getGSTINInfo(gstin) { var _a; var states = [ { state_name: 'Andaman and Nicobar Islands', state_code: '35', state_shortcode: 'AN', }, { state_name: 'Andhra Pradesh', state_code: '28', state_shortcode: 'AP' }, { state_name: 'Andhra Pradesh (New)', state_code: '37', state_shortcode: 'AD', }, { state_name: 'Arunachal Pradesh', state_code: '12', state_shortcode: 'AR', }, { state_name: 'Assam', state_code: '18', state_shortcode: 'AS' }, { state_name: 'Bihar', state_code: '10', state_shortcode: 'BH' }, { state_name: 'Chandigarh', state_code: '04', state_shortcode: 'CH' }, { state_name: 'Chattisgarh', state_code: '22', state_shortcode: 'CT' }, { state_name: 'Dadra and Nagar Haveli', state_code: '26', state_shortcode: 'DN', }, { state_name: 'Daman and Diu', state_code: '25', state_shortcode: 'DD' }, { state_name: 'Delhi', state_code: '07', state_shortcode: 'DL' }, { state_name: 'Goa', state_code: '30', state_shortcode: 'GA' }, { state_name: 'Gujarat', state_code: '24', state_shortcode: 'GJ' }, { state_name: 'Haryana', state_code: '06', state_shortcode: 'HR' }, { state_name: 'Himachal Pradesh', state_code: '02', state_shortcode: 'HP' }, { state_name: 'Jammu and Kashmir', state_code: '01', state_shortcode: 'JK', }, { state_name: 'Jharkhand', state_code: '20', state_shortcode: 'JH' }, { state_name: 'Karnataka', state_code: '29', state_shortcode: 'KA' }, { state_name: 'Kerala', state_code: '32', state_shortcode: 'KL' }, { state_name: 'Ladakh', state_code: '38', state_shortcode: 'LA' }, { state_name: 'Lakshadweep Islands', state_code: '31', state_shortcode: 'LD', }, { state_name: 'Madhya Pradesh', state_code: '23', state_shortcode: 'MP' }, { state_name: 'Maharashtra', state_code: '27', state_shortcode: 'MH' }, { state_name: 'Manipur', state_code: '14', state_shortcode: 'MN' }, { state_name: 'Meghalaya', state_code: '17', state_shortcode: 'ME' }, { state_name: 'Mizoram', state_code: '15', state_shortcode: 'MI' }, { state_name: 'Nagaland', state_code: '13', state_shortcode: 'NL' }, { state_name: 'Odisha', state_code: '21', state_shortcode: 'OR' }, { state_name: 'Pondicherry', state_code: '34', state_shortcode: 'PY' }, { state_name: 'Punjab', state_code: '03', state_shortcode: 'PB' }, { state_name: 'Rajasthan', state_code: '08', state_shortcode: 'RJ' }, { state_name: 'Sikkim', state_code: '11', state_shortcode: 'SK' }, { state_name: 'Tamil Nadu', state_code: '33', state_shortcode: 'TN' }, { state_name: 'Telangana', state_code: '36', state_shortcode: 'TS' }, { state_name: 'Tripura', state_code: '16', state_shortcode: 'TR' }, { state_name: 'Uttar Pradesh', state_code: '09', state_shortcode: 'UP' }, { state_name: 'Uttarakhand', state_code: '05', state_shortcode: 'UT' }, { state_name: 'West Bengal', state_code: '19', state_shortcode: 'WB' }, ]; var panTypes = [ { code: 'C', pan_type: 'Company' }, { code: 'P', pan_type: 'Person' }, { code: 'H', pan_type: 'HUF (Hindu Undivided Family)' }, { code: 'F', pan_type: 'Firm' }, { code: 'A', pan_type: 'Association of Persons (AOP)' }, { code: 'T', pan_type: 'AOP (Trust)' }, { code: 'B', pan_type: 'Body of Individuals (BOI)' }, { code: 'L', pan_type: 'Local Authority' }, { code: 'J', pan_type: 'Artificial Juridical Person ' }, { code: 'G', pan_type: 'Government' }, ]; gstin = gstin.toUpperCase(); if (!isValidGSTNumber(gstin)) return 'Invalid GSTIN'; var state = states.find(function (o) { return o.state_code === gstin.slice(0, 2); }); var info_msg = 'The GSTIN ' + gstin + ' is entity #' + parseInt(gstin.slice(12, 13), 36) + ' belonging to ' + ((_a = panTypes.find(function (o) { return o.code === gstin[5]; })) === null || _a === void 0 ? void 0 : _a.pan_type) + ' whose PAN is ' + gstin.slice(2, 12) + ' registered in ' + (state === null || state === void 0 ? void 0 : state.state_name) + ' (' + (state === null || state === void 0 ? void 0 : state.state_shortcode) + ')'; return info_msg; } function getCert(certname) { if (certname === undefined) { certname = 'einv_prod'; } if (certname.endsWith('.pem')) { certname = certname.replace('.pem', ''); } // get public key var buf = Buffer.from(certs[certname], 'base64'); return buf.toString(); } // This function is to validate a eInvoice QR function validateEInvoiceSignedQR(qrText, publickey) { var cert = getCert(publickey); try { var decodedQR = jwt.verify(qrText, cert, { issuer: 'NIC' }); } catch (err) { throw new Error('Signature Verification Failed!'); } return decodedQR; } function validateSignedInvoice(signedInvoiceJWT, publickey) { var cert = getCert(publickey); try { var invoice = jwt.verify(signedInvoiceJWT, cert, { issuer: 'NIC' }); } catch (err) { throw new Error('Signature Verification Failed!'); } return invoice; } function ValidateGSTIN(gstin) { gstin = gstin.toUpperCase(); if (gstin.length !== 15) { return 'Enter a valid 15 character GSTIN'; } if (!validatePattern(gstin)) { return 'Invalid GSTIN format'; } else { if (gstin.toUpperCase()[14] !== calcCheckSum(gstin.toUpperCase())) { return 'Invalid checksum character in GSTIN'; } else return 'Valid GSTIN'; } } module.exports = { isValidGSTNumber: isValidGSTNumber, ValidateGSTIN: ValidateGSTIN, validateEInvoiceSignedQR: validateEInvoiceSignedQR, validateSignedInvoice: validateSignedInvoice, getGSTINInfo: getGSTINInfo, }; //# sourceMappingURL=index.js.map