Decode. Verify. Pay Safely.
A privacy-first UPI QR code inspector and payment link generator.
Runs 100% locally in the browser — no server, no tracking, no data collection.
🌐 Live: upinspect.pages.dev
Most UPI QR scans blindly redirect you to a payment app with no chance to verify the details. UPInspect adds a transparent step in between:
Scan → Inspect → Choose → Pay
- Decode & Inspect — Extract and view the UPI ID, merchant name, and requested amount from any QR code before paying.
- Scan or Upload — Use your device camera for live scanning, or upload a saved QR screenshot from your gallery.
- Torch Toggle — Built-in torch control for scanning in low-light environments (on supported devices).
- Flexible Payments — Tap "Pay Now" to open your preferred UPI app, or copy the UPI ID for manual high-value transfers.
- Editable Amount — Modify the pre-filled amount on scanned QR codes before paying.
- Create & Share — Generate custom UPI payment links and professional QR standee cards.
- Shareable Links — Every standee share includes a tappable payment link so recipients can pay without scanning.
- 100% On-Device — Your scanned codes and payment data never leave your browser.
- URI injection blocked:
Number()(notparseFloat()) is used to parse amounts.Number('100&pa=attacker@upi')returnsNaNand is safely rejected. - Strict Encoding: UPI ID and amount are wrapped in
encodeURIComponent()before being placed in any URI or QR string. - Amount validation: Amounts below ₹1 are silently omitted from QR codes and payment links.
- No network requests: All QR decoding, generation, and image export happen entirely on-device.
UPInspect uses clean path-based URLs for shareable payment links:
https://upinspect.pages.dev/{upi-id}/{name}/{amount}
# Examples
https://upinspect.pages.dev/rahul@upi/Rahul%20Traders/500
https://upinspect.pages.dev/shop@okaxis/My%20Shop
https://upinspect.pages.dev/pay@upi/500
| Segment | Required | Description |
|---|---|---|
upi-id |
✅ | UPI ID (e.g. name@upi) — @ is kept readable |
name |
Optional | Merchant or payee name |
amount |
Optional | Pre-filled amount in ₹ (numeric segment auto-detected) |
The router auto-detects whether the second segment is a name or an amount, so both /pa/500 and /pa/name/500 resolve correctly.
When opened, the link shows a verified payment card with Pay Now and Copy UPI ID options. No app install required.
Deploying to Cloudflare Pages
- Push the repo to GitHub
- Connect it to Cloudflare Pages
- Set build command to none, output directory to
/(repo root) - The
_redirectsfile handles SPA routing. Asset directories are passed through first, then payment link paths fall through toindex.html:
Asset passthrough rules must come before the catch-all rules — Cloudflare matches the first rule that applies.
Third-Party Libraries
| Library | Version | Purpose |
|---|---|---|
| html5-qrcode | latest | Camera QR scanning |
| jsQR | 1.4.0 | File upload QR decoding (cross-browser, including Firefox) |
| qr-code-styling | 1.5.0 | Styled QR code canvas rendering |
| Google Analytics 4 | — | Anonymous visitor analytics |
Note on image export: The standee save/share flow uses native canvas compositing — not
html2canvas. The card is drawn directly onto a<canvas>using the exact colours and layout fromviews.css.
Note on file upload scanning: File uploads are decoded using
jsQRdirectly viacanvas.getImageData()to ensure cross-browser compatibility, bypassing Firefox's inconsistentcreateImageBitmap()behaviour.
Browser Support
| Feature | Chrome | Firefox | Safari | Samsung Internet |
|---|---|---|---|---|
| QR Camera Scan | ✅ | ✅ | ✅ | ✅ |
| File Upload Scan | ✅ | ✅ | ✅ | ✅ |
| Torch Toggle | ✅ | ✅ * | ✅ * | ✅ |
| Inverted QR (dark mode) | ✅ | ✅ | ✅ | ✅ |
| Save Image | ✅ | ✅ | ✅ | ✅ |
| Share with Image | ✅ | ❌ † | ✅ | ✅ |
| PWA Install | ✅ | ❌ | ✅ | ✅ |
| OS Theme Detection | ✅ | ✅ | ✅ | ✅ |
* Torch support depends on device hardware capability, not just the browser.
† Firefox Android does not support file sharing via the Web Share API. Tapping Share downloads the image and opens a text share sheet with the payment link included in the caption.
We welcome contributions! Please see our Contributing Guide for details on how to set up the project locally, project structure, code style guidelines, and how to add support for new languages.
This project is licensed under the GPL-3.0 License — see the LICENSE file for details.