Client-Side QR Synthesis
Generates standardized NPCI-compliant upi://pay URIs (pa, pn, am, cu, tn) rendered dynamically to an in-memory HTML5 Canvas with zero network hops.
A privacy-focused, browser-native UPI QR payment card generator with MDR transaction structuring, offline PWA support, and customizable high-resolution export. Produces production-ready, standardized upi://pay payment cards directly on client canvas with zero server uploads.
Generates standardized NPCI-compliant upi://pay URIs (pa, pn, am, cu, tn) rendered dynamically to an in-memory HTML5 Canvas with zero network hops.
Automated transaction splitting engine built to navigate India's UPI Merchant Discount Rate regulations (0.4% MDR on P2M transactions exceeding INR 2,000) down to exact paise precision.
Export styled payment cards in 1200x1600 PNG or JPG formats, or generate standalone 1080x1080 QR codes for physical counter stands and POS terminal displays.
Technical Protocol
upi://pay parameter matrix.Every QR card synthesized by QR4UPI conforms strictly to the National Payments Corporation of India (NPCI) deep link schema.
| Param | Field Name | Format & Validation | Role in QR Synthesis |
|---|---|---|---|
pa | Payee Address (VPA) | ^[a-zA-Z0-9.\-_]{2,256}@[a-zA-Z]{2,64}$ (Max 255 chars) | Mandatory routing identifier for recipient bank account |
pn | Payee Name | String (Max 99 characters) | Displays recipient legal merchant name inside scanning banking apps |
am | Transaction Amount | Decimal string up to 2 decimal places (paise) | Pre-fills the payment amount to prevent customer input errors |
cu | Currency Code | Strictly INR | Specifies Indian Rupee currency standard |
tn | Transaction Note | Alphanumeric (Strictly truncated to 25 chars) | Carries order IDs, invoice tags, and sequential split parts |
mc | Merchant Category Code | 4-digit ISO 18245 code | Optional business classification code for merchant accounts |
tr | Transaction Reference | Alphanumeric (Max 35 chars) | Optional merchant-generated tracking or invoice order reference |
All query parameters are escaped via encodeURIComponent to prevent parsing breaks on spaces, ampersands, or non-ASCII characters across different banking app parsers.
Quick-select support for India's major PSP handles: @okaxis, @okhdfcbank, @paytm, @ybl, @ibl, @axl, @barodampay, and @upi.
Regulatory Engineering
NPCI rules mandate a 0.4% Merchant Discount Rate on P2M UPI transactions exceeding INR 2,000.
Configurable installment splitting for multi-payer bills or phased client milestone billing.
(Part X/Y) while strictly truncating user transaction notes to keep the full tn parameter under UPI's 25-char limit.
To eliminate IEEE-754 floating-point drift, amounts convert to integer paise before division:
Remainder paise are distributed sequentially across the first cards: ₹10.00 split 3 ways yields [₹3.34, ₹3.33, ₹3.33] (sum: ₹10.00).
When appendSplitNote is active, note length is calculated to protect banking app limits:
Ensures deep links never get rejected by strict core-banking parsers during payment intent handshakes.
Capabilities
Cycle smoothly between partitioned cards with touch gestures or arrow keys. Batch export ("Download All Parts") includes concurrency locks and sequential progress counters.
Renders crisp print-ready PNG and JPG cards with vector typography, rupee symbol formatting, and formatted amount in words ("Rupees Five Thousand Only").
One-click export of a square standalone QR matrix designed for acrylic payment stands, table cards, counter stickers, and digital POS displays.
Fully installable Progressive Web App powered by sw.js. Functions completely offline in rural or low-connectivity retail environments with zero network calls.
Preset themes (Dark Metallic, Midnight Gold, Emerald Glass, Obsidian Purple, Crimson Slate) plus custom color picker, logo badge upload, and rounded QR dots.
Payment credentials never transmit over the wire. Settings persist locally in browser localStorage (upi-qr-card-details-v1) for merchant reuse.
Rendering Architecture
Direct Canvas rendering (CanvasRenderingContext2D) eliminates blurry HTML-to-image capture artifacts and yields vector-crisp typography.
Interactive display canvas operates at 600×800 (sub-16ms redraw) while master export canvas compiles at double-density 1200×1600 for laser-sharp thermal or color printing.
Renders a solid white container with rounded corners and diffuse shadow behind the QR matrix, guaranteeing 100% camera finder pattern detection across dark or metallic themes.
Choose between classic square modules for industrial scannability at distance, or rounded arc-calculated modules for modern consumer-friendly aesthetics.
Uploaded merchant logos preserve natural aspect ratios. Logo pixels are sampled across the ITU-R BT.601 formula:
White/light logos automatically receive dark center badges; dark logos default to crisp white badge surfaces.
For acrylic tent stands or counter stickers where full card branding is unnecessary:
User Ergonomics
For splits ≤ 7 parts, individual navigation dots are displayed. For large invoices (> 7 parts, such as ₹45,000 into 23 parts), the UI smoothly switches to a linear progress bar.
Cycle through split installment cards with ← and → arrow keys. Keystrokes are ignored when focusing on form inputs.
Sequentially compiles and triggers downloads with live status reporting (Downloading 2 of 5...) and concurrency locks to prevent duplicated exports.
Export Mechanics
Automatic capability detection routes exports through native OS sheets or direct file downloads.
# Native Share Sheet vs Download Fallback:
navigator.canShare({ files }) → true : Launches WhatsApp, Telegram, AirDrop, Messages
navigator.canShare({ files }) → false : Triggers direct automatic high-res PNG / JPG download
# Standardized Human-Readable Filename Outputs:
Single Card: upi_qr_acme_store_1850.png
Split Card: upi_qr_acme_store_part1_of_3_amt2000.png
Standalone QR: upi_qr_code_acme_store_part1_of_3_amt2000.png
Codebase Structure
Zero build step, zero heavy frameworks, and zero CDN dependencies at runtime.
upiqr/ ├── .github/workflows/ │ └── ci.yml # GitHub Actions CI workflow (lint + unit tests) ├── assets/ │ ├── favicon.svg # Vector favicon │ ├── manifest.json # PWA web application manifest │ ├── qrcode.min.js # Bundled QR matrix generator library (zero CDN) │ └── upi-logo.svg # Vector NPCI UPI brand mark ├── app.js # Application controller, canvas renderer, state management ├── index.html # Semantic HTML5 layout and form controls ├── style.css # Modern CSS styling, themes, and responsive design ├── sw.js # Offline cache service worker (v2) ├── test_split.js # Standalone unit test suite for split logic & note truncation └── upi_qr_mechanism.md # Technical specification of UPI deep links
Execution & Verification
# Option 1: Direct File Access (No build step required)
git clone https://github.com/thesatyamjain/upiqr.git
cd upiqr && start index.html
# Option 2: Local Static Server (For full PWA Service Worker testing)
npx serve . # or: python -m http.server 8000
# Automated Verification Suite
npm run lint # Syntax and static code validation
npm test # Unit tests: MDR arithmetic, 50-part INR 100,000, 25-char notes
npm run check # Full verification pass
Operating Flow
01 · Configure
Input your UPI ID and merchant name. Details persist in local storage for recurring use.
02 · Structure
Amounts over ₹2,000 auto-partition into sub-₹2,000 cards with exact paise conservation.
03 · Customize
Select card themes, rounded QR dots, and upload custom store badges with contrast guard.
04 · Export
Export 1200x1600 print cards, 1080x1080 counter QRs, or share via native Web Share API.
Deployment
Direct GitHub integration deploying to Cloudflare edge network globally. Zero build commands, instant cache invalidation.
Publish directly from the main branch with automated GitHub Actions CI checking syntax and unit tests on push.
Deployable to Vercel, Netlify, AWS S3, or any basic Nginx/Apache container without requiring Node.js runtime servers.