Payloads
Each payload knows the exact content format phones and apps read, validates its input in the constructor, and carries a default sensitivity:
use RoundlyConsulting\Qr\Enums\{SmsFormat, WifiSecurity};
use RoundlyConsulting\Qr\Payloads\{Geo, Otpauth, VCard};
Qr::text('Any text');
Qr::url('https://example.com'); // http/https only by default
Qr::url('mailto:[email protected]', ['mailto']); // opt in to other schemes
Qr::email('[email protected]', 'Hello', 'Body text'); // mailto:
Qr::phone('+421 900 123 456'); // tel:+421900123456
Qr::sms('+421900123456', 'See you at 10', SmsFormat::Smsto);
Qr::wifi('Clinic Guest', 'guest-password', WifiSecurity::Wpa, hidden: false); // WPA (passphrase 8–63 bytes), WEP, SAE (WPA3), None
Qr::vcard(new VCard(
name: 'MVDr. Jana Nováková', // display name (FN)
familyName: 'Nováková', // structured name (N) — how phones file the contact
givenName: 'Jana',
honorificPrefixes: 'MVDr.',
organization: 'VetClinic s.r.o.',
title: 'Veterinarian',
phones: ['+421 900 123 456'],
emails: ['[email protected]'],
url: 'https://example.sk',
address: 'Hlavná 1, Košice',
note: 'Mon–Fri',
));
Qr::geo(48.1486, 17.1077); // geo:48.1486,17.1077Catalogue
| Entry point | Encodes as | Sensitivity |
|---|---|---|
Qr::text() | The text as given (empty is a valid symbol). | Public; Secret when it starts with otpauth:, otpauth-migration: or WIFI: |
Qr::url() | The URL as given; http/https unless you allow more schemes. | Public; Secret for an opted-in otpauth:, otpauth-migration: or WIFI: URL (locked for otpauth) |
Qr::email() | mailto:to?subject=…&body=… (RFC 6068) | Personal |
Qr::phone() | tel:+421… (RFC 3966) | Personal |
Qr::sms() | SMSTO:+421…:msg or sms:+421…?body=msg (RFC 5724) | Personal |
Qr::wifi() | WIFI:T:WPA;S:ssid;P:pw;H:true;; | Secret (may be lowered) |
Qr::vcard() | vCard 3.0 (display and structured name, organization, title, phones, e-mails, URL, address, note) | Personal |
Qr::geo() | geo:48.1486,17.1077 (RFC 5870) | Personal |
Qr::otpauth() | The otpauth:// URI, unchanged | Secret (locked) |
Qr::epc() | EPC069-12 v3.1 SEPA credit transfer | Personal |
Qr::payBySquare() | PAY by square base32hex string | Personal |
Validation
- Url — at most 4096 bytes, no control characters or whitespace, scheme on the allow-list, host required for http(s); non-ASCII paths and hosts are accepted.
- Email — a valid address (Unicode allowed); subject and body are percent-encoded.
- Phone / Sms — separators (space, NBSP, -, ., (, ), /) are stripped, then an optional + and 3–20 digits.
- Wifi — SSID 1–32 bytes; a password is required unless WifiSecurity::None (and forbidden with it); a WPA passphrase is 8–63 bytes (not characters).
- VCard — name 1–255 characters; e-mails and phones validated as above.
- Geo — finite coordinates, latitude ±90, longitude ±180, at most 7 decimals in the output.
Invalid input throws InvalidPayloadException carrying $payloadType, $field and a $reason key — the message never contains the value.
vCard names
A vCard’s name is the display name (FN). Pass the parts — familyName, givenName, additionalNames, honorificPrefixes, honorificSuffixes — so contact apps file the card under the right name (N:Nováková;Jana;;MVDr.;). With only name the package never guesses a split: the whole name becomes the given name (N:;Jana Nováková;;;), which apps display unchanged and sort under its first letter.
Payload objects
The facade shortcuts wrap payload classes under RoundlyConsulting\Qr\Payloads. Build them directly and pass them to make(), svg() or matrix() — Wifi::withHexKey() is only available this way:
use RoundlyConsulting\Qr\Payloads\{Url, Wifi};
// Every payload class can also be built directly and passed to make()/svg()/matrix():
Qr::make(new Wifi('Guest', 'guest-password'));
Qr::make(Wifi::withHexKey('Clinic', $psk)); // raw hex key: 64-digit WPA PSK or 10/26/58-digit WEP key, unquoted
Qr::svg(new Url('https://example.com'));Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.