Skip to main content
~/makemydev/blog/qr-codes-beyond-urls

QR codes beyond URLs — WiFi, vCard, payment

QR Code Generator#001·7 min read·

Most QR codes you scan link to a URL. But the QR code spec doesn’t care what data it encodes — it’s just a binary payload wrapped in error correction. Smartphones recognize specific text patterns inside QR codes and act on them: joining a WiFi network, adding a contact, opening an app, or initiating a payment. The “smart” behavior comes from the phone’s camera app parsing the decoded text, not from the QR code itself.

How QR codes work under the hood

A QR code is a two-dimensional barcode that stores data in a grid of black and white modules. The three large squares in the corners are finder patterns — they let the scanner determine the code’s orientation and size. The data is encoded using one of four modes: numeric (0–9), alphanumeric (0–9, A–Z, and nine symbols), byte (arbitrary UTF-8), or kanji.

Each QR code has a version(1–40) that determines the grid size, from 21×21 modules (version 1) to 177×177 (version 40). Higher versions hold more data but produce denser, harder-to-scan codes.

Error correction levels

QR codes use Reed-Solomon error correction, which means part of the code is redundant recovery data. You choose one of four levels:

  • L (Low)— recovers up to 7% damage. Smallest code for a given payload. Use when the code will be displayed on a clean screen.
  • M (Medium)— recovers up to 15% damage. The default for most generators. Good general-purpose choice.
  • Q (Quartile)— recovers up to 25% damage. Use when the code might be partially obscured or printed on a textured surface.
  • H (High)— recovers up to 30% damage. This is what lets people put logos in the center of a QR code — the logo covers modules, but the error correction reconstructs the lost data. The tradeoff: the code is significantly larger for the same payload.

Choosing H when you don’t need it wastes space. A URL that fits in a version 3 code at L might require version 5 at H — that’s a denser grid that’s harder to scan from a distance or at small print sizes.

WiFi QR codes

Both iOS and Android recognize a specific text format for WiFi credentials. When the camera app decodes a QR code containing this string, it offers to join the network automatically:

WIFI:T:WPA;S:MyNetwork;P:hunter2;;

The format breaks down as:

  • T: — authentication type. Valid values: WPA (covers WPA2 and WPA3), WEP, or nopass for open networks.
  • S: — the SSID (network name). If the SSID contains special characters (\, ;, :, ,), escape them with a backslash.
  • P: — the password. Same escaping rules apply. Omit for open networks.
  • H: — optional. Set to true if the network is hidden (not broadcasting its SSID).

The trailing ;; is intentional — it terminates the format. WiFi QR codes are genuinely useful: print one and tape it next to your router, and guests connect by scanning instead of typing a 20-character password. Cafes and coworking spaces use them everywhere.

One catch: the password is embedded in the QR code in plain text. Anyone who scans it — or photographs it — gets the password. Don’t use WiFi QR codes for networks where access should be individually credentialed.

vCard QR codes

A vCard is a standard format for contact information (RFC 6350). When a QR code contains a vCard, smartphones offer to save it as a new contact. The format is plain text:

BEGIN:VCARD
VERSION:3.0
N:Doe;Jane;;;
FN:Jane Doe
ORG:Acme Corp
TEL;TYPE=CELL:+1-555-867-5309
EMAIL:[email protected]
URL:https://jane.example.com
END:VCARD

Each line is a property. The semicolons in the N: field separate last name, first name, middle name, prefix, and suffix. FN: is the display name. You can include multiple phone numbers, emails, addresses, and even a photo (Base64-encoded, though this bloats the QR code substantially).

vCards in QR codes are popular on business cards. Instead of a physical card that gets lost, a QR code on a card (or on a conference badge, or a slide deck) lets the recipient save your info in one scan. Keep the vCard minimal — name, phone, email, maybe an org. Every extra field adds bytes and makes the QR code denser.

There’s also MECARD, a simpler format that Android supported before vCard became universal:

MECARD:N:Doe,Jane;TEL:+15558675309;EMAIL:[email protected];;

MECARD is more compact but less widely supported than vCard. Stick with vCard 3.0 for maximum compatibility.

Deep links and app-specific schemes

Any URI scheme that a phone recognizes works in a QR code. Beyond https://, common ones include:

  • tel:+15558675309 — opens the dialer with the number prefilled
  • sms:+15558675309?body=Hello — opens a new text message
  • mailto:[email protected]?subject=Hi — opens the email client
  • geo:37.7749,-122.4194 — opens the maps app at a location

Apps can register custom URL schemes or universal links, so a QR code can deep-link into a specific screen in a mobile app. This is how payment apps, loyalty programs, and event check-in systems work — the QR code contains a URL that the app intercepts.

Payment QR codes

Payment QR codes vary by system. The EMVCo standard (used by many national payment systems) defines a structured TLV (tag-length-value) format. But in practice, most consumer-facing payment QR codes are just URLs:

  • UPI (India) upi://pay?pa=merchant@upi&pn=StoreName&am=100&cu=INR
  • PIX (Brazil)— an EMVCo payload string encoding merchant info, amount, and a transaction reference
  • Bitcoin bitcoin:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa?amount=0.001

The key insight: the QR code itself doesn’t process the payment. It transfers a string to the phone, and the phone’s payment app interprets that string. The QR code is just the transport layer.

Capacity limits

The maximum data a QR code can hold depends on the encoding mode and error correction level:

ModeEC Level LEC Level H
Numeric7,089 digits3,057 digits
Alphanumeric4,296 chars1,852 chars
Byte (UTF-8)2,953 bytes1,273 bytes

In practice, you want to stay well under these limits. A version 40 QR code (177×177 modules) is enormous and hard to scan reliably. For real-world use, aim for under 300 bytes of data. That comfortably fits a URL, a WiFi string, or a basic vCard. If your QR code generator is producing a grid denser than about 50×50 modules, reconsider whether you’re putting too much data in it.

Practical tips for generating QR codes

  • Keep the payload short. Use URL shorteners for long URLs. Trim unnecessary fields from vCards. Every byte saved makes the code smaller and easier to scan.
  • Use error correction M unless you have a reason not to. L is fine for screens. H is necessary if you’re overlaying a logo. M is the right default for print.
  • Print size matters.A QR code should be at least 2 cm × 2 cm for close-up scanning (menus, business cards). For posters or signage scanned from a distance, scale up proportionally — roughly 10:1 ratio of scanning distance to code width.
  • Contrast is non-negotiable.Dark modules on a light background. The spec says black on white, but dark blue on white or black on light yellow work too. Avoid low-contrast combinations — a light gray QR code on a white background will fail to scan.
  • Test on multiple devices. Generate the code, scan it with an iPhone, scan it with an Android phone, and scan it with a dedicated QR reader app. Edge cases in WiFi and vCard parsing differ between platforms.
  • SVG for print, PNG for screens.SVG scales to any size without pixelation. PNG is fine for web embeds and digital displays. Never use JPEG for QR codes — compression artifacts blur the module boundaries and can make the code unscannable.

The QR Code Generator supports all of these formats — text, URL, WiFi, and vCard — with adjustable size and error correction levels. It runs entirely in your browser, generates both PNG and SVG, and doesn’t send your WiFi password or contact info to a server.