npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

upi-validator

v1.0.2

Published

Zero-dependency, ultra-fast Indian UPI ID (VPA) validator, bank handle recognizer, and NPCI upi://pay deep link intent URL builder and parser.

Downloads

66

Readme

upi-validator

npm version CI License: MIT TypeScript Zero Dependencies Tests Passing ESM + CommonJS

Zero-dependency, ultra-fast Indian UPI ID (VPA) validator, bank handle recognizer, and NPCI upi://pay deep link intent URL builder & parser for Node.js, browsers, and Edge runtimes.


🚀 Features

  • ⚡ Zero Dependencies: Pure TypeScript implementation with zero external runtime packages.
  • 🎯 NPCI Compliance: Full validation of Indian Unified Payments Interface (UPI) VPA specifications (length limits, character sets, separators).
  • 🏦 170+ Official Handles: Extensive registry of NPCI-approved bank and PSP handles (Google Pay, PhonePe, Paytm, BHIM, CRED, Amazon Pay, SBI, HDFC, ICICI, Axis, Kotak, RRBs, SFBs).
  • 🔗 NPCI Intent Deep Links: Create and parse official upi://pay deep links with query parameters (pa, pn, am, cu, tn, tr, mc, url, sign).
  • 📦 Dual ESM & CommonJS: Ships with complete ES module and CommonJS distributions with .d.ts declaration maps.
  • 🛡️ Type-Safe: 100% strict TypeScript typing out of the box.

📦 Installation

# npm
npm install upi-validator

# yarn
yarn add upi-validator

# pnpm
pnpm add upi-validator

⚡ Quick Start

1. Validate UPI ID (VPA) & Recognize Bank / PSP

import { validateUpiId, isValidUpiId } from "upi-validator";

// Comprehensive validation result
const result = validateUpiId("rahul.sharma@okaxis");
console.log(result);
/*
{
  isValid: true,
  vpa: "rahul.sharma@okaxis",
  username: "rahul.sharma",
  handle: "okaxis",
  provider: "Google Pay",
  isKnownHandle: true
}
*/

// Fast boolean check
if (isValidUpiId("9876543210@paytm")) {
  console.log("Valid UPI ID!");
}

2. Generate NPCI Intent URL (upi://pay)

Generate standard deep links for QR codes, payment buttons, and mobile app intents:

import { buildUpiIntentUri } from "upi-validator";

const intentUri = buildUpiIntentUri({
  pa: "merchant@okhdfcbank",
  pn: "Acme Retail Store",
  am: 1249.50,
  tn: "Order #84920",
  tr: "TXN84920",
  cu: "INR",
});

console.log(intentUri);
// upi://pay?pa=merchant%40okhdfcbank&pn=Acme%20Retail%20Store&am=1249.50&cu=INR&tn=Order%20%2384920&tr=TXN84920

3. Parse and Validate UPI Deep Links

Extract payment parameters from incoming deep links or scanned QR strings:

import { parseUpiIntentUri } from "upi-validator";

const data = parseUpiIntentUri("upi://pay?pa=seller@ybl&pn=Coffee%20House&am=150.00&cu=INR");

console.log(data.pa); // "seller@ybl"
console.log(data.pn); // "Coffee House"
console.log(data.am); // 150
console.log(data.validationResult.provider); // "PhonePe"

📖 API Reference

validateUpiId(vpa: unknown): UpiValidationResult

Validates structure, characters, length, and checks against the registry of registered NPCI bank and PSP handles.

interface UpiValidationResult {
  isValid: boolean;
  vpa: string;
  username: string;
  handle: string;
  provider?: string;
  isKnownHandle: boolean;
  error?: string;
}

Validation Rules:

  • Length: 3 to 255 total characters.
  • Separator: Exactly one @ symbol.
  • Username (username@...):
    • 1 to 100 characters.
    • Allowed characters: alphanumeric (a-z, 0-9), dot (.), hyphen (-), underscore (_).
    • Cannot begin or end with a special character.
    • Cannot contain consecutive special characters (.., --, __, .-).
  • Handle (...@handle):
    • 2 to 64 characters.
    • Allowed characters: alphanumeric (a-z, 0-9) and dot (.).
    • Cannot be purely numeric.

buildUpiIntentUri(options: UpiIntentOptions): string

Constructs an NPCI-compliant upi://pay URI with validated parameters.

interface UpiIntentOptions {
  /** Payee VPA / UPI ID (Required) */
  pa: string;
  /** Payee Name (Required) */
  pn: string;
  /** Merchant Category Code (4 digits, e.g. "5411") */
  mc?: string;
  /** Transaction Reference ID */
  tr?: string;
  /** Transaction ID */
  tid?: string;
  /** Transaction Note / Description */
  tn?: string;
  /** Transaction Amount in INR (auto-formatted to 2 decimal places) */
  am?: number | string;
  /** Currency code (Defaults to "INR") */
  cu?: string;
  /** Reference URL */
  url?: string;
  /** Minimum Amount to be paid */
  mam?: number | string;
  /** Transaction Initiation Mode */
  mode?: string;
  /** Organization ID / NPCI Org ID */
  orgid?: string;
  /** Digital Signature for signed intent */
  sign?: string;
}

parseUpiIntentUri(uri: string): UpiIntentData

Parses query parameters from a upi://pay string and validates payee address pa.

interface UpiIntentData {
  rawUri: string;
  pa: string;
  pn: string;
  mc?: string;
  tr?: string;
  tid?: string;
  tn?: string;
  am?: number;
  amString?: string;
  cu: string;
  url?: string;
  mam?: number;
  mamString?: string;
  mode?: string;
  orgid?: string;
  sign?: string;
  otherParams: Record<string, string>;
  validationResult: UpiValidationResult;
}

Helper Functions

  • isValidUpiId(vpa: unknown): boolean: Fast boolean check for UPI ID validity.
  • getUpiHandle(vpa: string): string | null: Extracts and normalizes handle string, or returns null if invalid.
  • normalizeUpiId(vpa: string): string: Normalizes valid UPI ID to lowercase string, throws if invalid.
  • isKnownUpiHandle(handle: string): boolean: Checks whether a handle exists in the NPCI registry.
  • getUpiProvider(handleOrVpa: string): string | undefined: Looks up provider name from handle or full VPA.
  • getHandleInfo(handle: string): UpiHandleInfo | undefined: Retrieves detailed metadata for a handle.
  • getAllHandles(): readonly UpiHandleInfo[]: Returns the complete registry of 170+ approved handles.
  • isValidUpiIntentUri(uri: string): boolean: Validates whether a URI is a correct upi://pay intent link.

🏦 Supported UPI Handles (170+ Handles)

| Category | Popular Handles | Provider / Sponsor | | :--- | :--- | :--- | | Google Pay | @okhdfcbank, @okaxis, @okicici, @oksbi, @okbizaxis | Google Pay (HDFC, Axis, ICICI, SBI) | | PhonePe | @ybl, @ibl, @axl | PhonePe (YES Bank, IndusInd, Axis) | | Paytm | @paytm, @ptsbi, @pthdfc, @ptaxis, @pticici | Paytm (PPBL, SBI, HDFC, Axis, ICICI) | | BHIM / NPCI | @upi, @bhim | BHIM UPI (NPCI) | | Amazon Pay | @apl, @rapl | Amazon Pay (Axis Bank, RBL Bank) | | WhatsApp Pay | @waaxis, @wahdfcbank, @waicici, @wasbi | WhatsApp Pay | | CRED | @ckers, @cbaxis, @cbsbi, @cbicici, @cbhdfc | CRED | | FinTechs | @ikwik, @mbk, @slice, @jupiteraxis, @navi, @super, @postpe, @fam, @kiwi | MobiKwik, Jupiter, Slice, Navi, BharatPe | | Payments Banks | @airtel, @ippb, @postbank, @jio, @fino, @nsdl | Airtel, India Post, Jio, Fino, NSDL | | Public Sector Banks | @sbi, @pnb, @bob, @canbank, @cnrb, @uboi, @boi, @indianbank, @cbi, @iob, @uco, @mahb, @psb, @idbi | SBI, PNB, BOB, Canara, Union, BOI, etc. | | Private Sector Banks | @hdfcbank, @icici, @axisbank, @kotak, @indus, @federal, @yesbank, @rbl, @idfcbank, @sc, @hsbc, @dbs | HDFC, ICICI, Axis, Kotak, Federal, etc. | | Small Finance Banks | @aubank, @equitas, @ujjivan, @suryoday, @jana, @utkarsh, @csfb, @esaf | AU SFB, Equitas, Ujjivan, Utkarsh, etc. | | Co-operative Banks | @saraswatbank, @cosmos, @svc, @tjsb, @nkgsb, @abhyudaya, @apna, @kalupurbank | Saraswat, Cosmos, SVC, TJSB, etc. | | Gramin / RRB Banks | @bggb, @kgb, @kgrb, @apgb, @aryavart, @prathama, @sgb, @tgb, @agvb | Kerala Gramin, Aryavart, Prathama, etc. |


⚡ Performance

  • O(1) Handle Lookups: Internal registry utilizes a pre-computed hash Map for instant O(1) handle validation.
  • Zero Allocations for Simple Checks: Regular expressions are compiled once at module load.
  • Validation benchmarks easily exceed 1,000,000+ operations/second on modern hardware.

🧪 Testing

# Run tests with vitest
npm test

# Run tests with coverage
npm run test:coverage

📄 License

MIT © Vijay Misal

Security note

This package validates syntax and constructs intent URLs locally. It does not verify an account, initiate payments, or guarantee transaction success.