NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
QR for Laravel

The Qr facade

RoundlyConsulting\Qr\Facades\Qr is the recommended entry point (auto-aliased as Qr). Payload methods return an immutable PendingQr builder; svg(), matrix(), info() and fits() answer in one call:

use RoundlyConsulting\Qr\DataTransferObjects\QrOptions;
use RoundlyConsulting\Qr\Enums\ErrorCorrection;
use RoundlyConsulting\Qr\Facades\Qr;

// Entry points — each returns an immutable PendingQr builder
Qr::make($stringOrPayload);                  // a raw string becomes a Text payload
Qr::text('Table 12 — scan to order');
Qr::url('https://example.com');
Qr::wifi('Clinic Guest', 'guest-password');
Qr::otpauth($setup->provisioningUri);
Qr::epc($payment);                           // unset version/charset from config
Qr::payBySquare($document);                  // unset version/deburr from config

// One-call shortcuts — no builder
$svg = Qr::svg('https://example.com', new QrOptions(size: 200));                  // Svg
$matrix = Qr::matrix('HELLO WORLD');                                              // QrMatrix
$info = Qr::info('hello', new QrOptions(errorCorrection: ErrorCorrection::High)); // EncodingInfo
$fits = Qr::fits($request->input('text'));                                        // bool

Method reference

MethodReturnsWhat it does
make(string|Payload $data)PendingQrAny payload — your own Payload implementation, or a raw string (becomes Text).
text($text)PendingQrPlain text; otpauth- or Wi-Fi-looking text is treated as a secret.
url($url, $schemes = ['http', 'https'])PendingQrA link; other schemes only when you allow them (an opted-in otpauth or Wi-Fi URL is Secret).
email($to, $subject, $body)PendingQrA mailto: code.
phone($number)PendingQrA tel: code.
sms($number, $message, SmsFormat $format)PendingQrSMSTO: or sms: (default Smsto).
wifi($ssid, $password, WifiSecurity $security, $hidden)PendingQrWi-Fi credentials (default WPA) — always Secret.
vcard(VCard $card)PendingQrA vCard 3.0 contact.
geo($latitude, $longitude)PendingQrA geo: location.
otpauth(string|Otpauth $uriOrPayload)PendingQrA 2FA enrolment code — the URI unchanged, sensitivity locked to Secret.
epc(EpcPayment $payment)PendingQrSEPA credit transfer; unset version/charset fields from config.
payBySquare(PayBySquare $document)PendingQrPAY by square; unset version/deburr fields from config.
svg($data, ?QrOptions $options)SvgRender in one call.
matrix($data, ?QrOptions $options)QrMatrixEncode in one call, without rendering.
info($data, ?QrOptions $options)EncodingInfoHow the data would be encoded — version, level, mask, segments, bit budget.
fits($data, ?ErrorCorrection $level, ?int $maxVersion, ?Segmentation $segmentation)boolWhether the data would encode — no symbol is built.

Payment payloads get their unset version, charset, strictCharset or deburr fields from the configuration whichever entry point they come through — make(), svg(), matrix(), epc() / payBySquare() or <x-qr-code>.

Does it fit?

Qr::fits() answers “would this encode?” without building the symbol — cheap enough for a form, a preview or a queue guard. Unset arguments take what the payload requires, then the configuration (the settings the data would really be encoded with), so true never meets a DataTooLongException later:

use RoundlyConsulting\Qr\Enums\{ErrorCorrection, Segmentation};

Qr::fits($request->input('text'));                          // configured level + version window
Qr::fits($text, ErrorCorrection::Medium, maxVersion: 13);   // explicit level and ceiling
Qr::fits($digits, segmentation: Segmentation::Byte);
Qr::fits($epcPayment);                                      // EPC's own cap (v13, level M) applies

Qr::url($link)->errorCorrection('H')->version(3)->fits();   // fluent: the builder's current settings

It returns false for input over 7089 bytes or beyond the version window’s capacity. A maxVersion outside 1–40, or overriding an option a payment payload locks (EPC’s level, for instance), throws InvalidOptionException exactly as rendering would. The FitsInQrCode rule is the validation face of the same check — see Validation rules & cast.

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 crypto

By 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.