Skip to content

HTTP Responses

The builder implements Laravel's Responsable contract, so you can return it straight from a route or controller.

Returning a QR

php
use RealRashid\RaastQr\Facades\RaastQr;

Route::get('/orders/{order}/qr', function (Order $order) {
    return RaastQr::make()
        ->amount($order->total)
        ->format('svg');
})->middleware('auth');

Laravel calls toResponse() for you. The response carries the right content type — image/svg+xml or image/png — and Cache-Control: no-store, private, because a code carrying someone's order total has no business sitting in a shared cache.

In a Controller

php
class InvoiceQrController extends Controller
{
    public function __invoke(Invoice $invoice)
    {
        $this->authorize('view', $invoice);

        return RaastQr::make()
            ->amount($invoice->total)
            ->expiry($invoice->due_at)
            ->size(600)
            ->format('svg');
    }
}

Then point an image at it:

blade
<img src="{{ route('invoices.qr', $invoice) }}" alt="Scan to pay">

Downloads

php
return RaastQr::make()
    ->amount($invoice->total)
    ->download('invoice-' . $invoice->number . '.png');

Adds a Content-Disposition: attachment header. Omit the filename and you get raast-qr.png or raast-qr.svg.

Data URL vs Route

Data URLRoute
Extra requestNoYes
Page weightLarger HTMLSmaller HTML
CacheableNoNo (deliberately)
Works in emailRarely — most clients strip themNo
Easy to authoriseInherits the pageNeeds its own check

For a normal checkout page, the data URL via <x-raast-qr /> is simpler and one request cheaper. Reach for a route when the same code appears in several places, or when you want the QR to load lazily.

Always Authorise

A QR route is a route like any other. Because the code encodes an order total, gate it:

php
Route::get('/orders/{order}/qr', function (Order $order) {
    abort_unless($order->user_id === auth()->id(), 403);

    return RaastQr::make()->amount($order->total)->format('svg');
})->middleware('auth');

Handling Failures

If the IBAN or amount is bad, RaastQrException is thrown while the response renders. Catch it where you can still do something useful:

php
Route::get('/orders/{order}/qr', function (Order $order) {
    try {
        return RaastQr::iban($order->vendor->iban)
            ->amount($order->total)
            ->format('svg');
    } catch (RaastQrException $e) {
        report($e);
        abort(422, 'This order cannot be paid by QR right now.');
    }
});

See Handling Errors.


Made with ❤️ from Pakistan