UPI ID Input

Catches mistyped UPI IDs, cleans pasted upi://pay links and reads back the registered name, so money isn't sent to the wrong VPA.

StopsUPI payment to the wrong VPA

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/upi-id-input.json

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

Usage

upi-id-input-usage.tsx
import { UpiIdInput, type UpiVerification } from "@/components/ui/upi-id-input"

<UpiIdInput key={preset} label="Pay to UPI ID" defaultValue={value} expectedName={expectedName} verify={verify} />

What it catches

  • Pasted upi://pay links, reduced to the pa address
  • Email addresses typed as UPI IDs
  • Typo'd handles, with one-tap corrections
  • App names typed as handles (@gpay → its real handles)
  • Phone-number IDs with the wrong length or a +91 prefix
  • Registered name that differs from the expected or link-claimed name

Props

UpiIdInput props
PropTypeDefault
label

Visible label.

string"UPI ID"
value

Controlled UPI ID (cleaned).

string—
defaultValue

Initial UPI ID when uncontrolled.

string""
onValueChange

Called with the cleaned ID on every change; a pasted upi://pay link becomes its `pa`.

(value: string) => void—
verify

Asks your backend who the ID is registered to. Called once the ID settles and looks well formed.

(vpa: string, signal: AbortSignal) => Promise<UpiVerification>—
onVerifiedChange

Called with the verification result, or null when the ID changes.

(result: UpiVerification | null) => void—
expectedName

The name the user expects to pay; a different registered name is called out.

string—
handles

Known handles. Defaults to Google Pay, PhonePe, Paytm, Amazon Pay, WhatsApp, BHIM and major banks.

Record<string, UpiHandleInfo>UPI_HANDLES
delay

Pause in ms before warnings appear while typing.

number600
messages

Override any visible string, e.g. to translate.

Partial<typeof UPI_ID_MESSAGES>—

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

Accessibility

  • Visible <label>; aria-invalid and status via aria-describedby
  • Status and suggestions in a polite live region
  • Handle suggestions are buttons with aria-labels

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: Resolve the payee name server-side through your PSP before payment, and show it from that response, not from the link.

  • Format looks valid ≠ exists: only your verify callback can confirm the ID and its registered name
  • Handle list is common handles, not NPCI's full list
  • Name matching is approximate

What it stops

UPI payment to the wrong VPA

Also known as

upi · upi id · vpa · gpay · phonepe · paytm · upi://pay · payout

Field type

Dependencies

Pairs well with