Skip to main content

Overview

The QR Codes API provides functionality to generate QR codes for tenant landing pages and track when they are scanned. Each tenant has a unique QR code that redirects to their landing page while recording analytics.

QR Code Flow

  1. Generate: Admin dashboard generates a QR code for the tenant
  2. Scan: User scans the QR code with their phone
  3. Track: System records a qr_scan event in analytics
  4. Redirect: User is redirected to the tenant’s landing page

Download QR Code

Download the QR code as a PNG image file. This endpoint requires authentication.

Path Parameters

tenantId
integer
required
The ID of the tenant

Query Parameters

size
integer
default:"300"
Size of the QR code in pixels (optional)

Response

Returns a PNG image file with appropriate headers for download. Headers:
  • Content-Type: image/png
  • Content-Disposition: attachment; filename="{subdomain}_qr.png"

Example

<!-- Direct download link -->
<a href="/tenant/1/qr/download" download>
  Download QR Code
</a>
// Download via JavaScript
fetch('/tenant/1/qr/download')
  .then(response => response.blob())
  .then(blob => {
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'my-landing-qr.png';
    a.click();
  });

Filename Pattern

The downloaded file is named after the tenant’s subdomain:
  • Tenant subdomain: mi-negocio
  • Downloaded file: mi-negocio_qr.png

QR Code Target URL

This is the URL encoded in the QR code. When scanned, it:
  1. Verifies the code is valid for the tenant
  2. Records a qr_scan analytics event
  3. Redirects to the tenant’s landing page

Path Parameters

tenantId
integer
required
The ID of the tenant
code
string
required
The unique verification code generated for the tenant

Response

Returns a 302 Redirect to the tenant’s landing page:
Location: https://example.com/{subdomain}

Error Responses

Invalid QR code

Example URL

https://synticorex.com/t/1/abc123xyz789
Redirects to:
https://synticorex.com/mi-negocio

Analytics Tracking

Automatic Event Recording

When a QR code is scanned, the system automatically creates an analytics event: Event Type: qr_scan Recorded Data:
  • tenant_id: The tenant’s ID
  • event_type: 'qr_scan'
  • user_ip: SHA-256 hash of IP address (first 45 chars)
  • user_agent: Browser/device user agent string
  • referer: HTTP referer header (if available)
  • event_date: Date of scan (Y-m-d format)
  • event_hour: Hour of scan (0-23)

Privacy Protection

IP addresses are never stored in plain text:
$ipHash = hash('sha256', request()->ip() . config('app.key'));
$storedIp = substr($ipHash, 0, 45);
This ensures user privacy while still allowing unique visitor tracking.

Viewing QR Scan Data

QR scans can be viewed through the Analytics API:
fetch('/tenant/1/analytics')
  .then(response => response.json())
  .then(data => {
    console.log('QR scans (7 days):', data.data.qr_scans);
  });

QR Code Generation

QRService

QR codes are generated using the QRService class, which:
  1. Generates a unique verification code for the tenant
  2. Creates a shortlink URL: /t/{tenantId}/{code}
  3. Encodes the URL in a QR code image
  4. Returns PNG binary data

Code Verification

The QRService::verifyUniqueCode() method ensures:
  • The code matches the tenant’s stored code
  • The code has not been revoked or expired
  • The tenant exists and is active

Customization Options

Size:
$qrService->generateQRPNG($tenantId, 500); // 500x500px
Default Size: 300x300 pixels

Implementation Notes

Error Handling

If analytics tracking fails during a QR scan, the error is logged but the redirect still happens:
try {
    AnalyticsEvent::create([...]);
} catch (\Exception $e) {
    \Log::error('Error registrando QR scan event', [
        'tenant_id' => $tenantId,
        'error' => $e->getMessage(),
    ]);
}

// Redirect happens regardless
return redirect($landingUrl);
This ensures a good user experience even if analytics fail.

Subdomain Resolution

The redirect uses the tenant’s subdomain field:
$landingUrl = url('/' . $tenant->subdomain);
// Example: https://synticorex.com/mi-negocio

Database Schema

QR codes use the tenants table:
ColumnTypeDescription
subdomainstringUnique subdomain for the tenant
qr_codestringUnique verification code
statusenum'active', 'inactive', etc.

Use Cases

Physical Marketing

  • Print QR codes on business cards
  • Display on restaurant table tents
  • Include in printed catalogs
  • Add to store windows

Event Tracking

  • Track which marketing materials are most effective
  • Monitor QR scans by date and time
  • Compare QR traffic vs. direct visits

Multi-Location Businesses

Each branch can have its own QR code pointing to the same landing page, allowing you to track which physical location generates more scans.

Example Dashboard Integration

// Download QR code button
const downloadButton = document.getElementById('download-qr');
downloadButton.addEventListener('click', () => {
  window.location.href = `/tenant/${tenantId}/qr/download`;
});

// Display QR scan count
fetch(`/tenant/${tenantId}/analytics`)
  .then(response => response.json())
  .then(data => {
    document.getElementById('qr-scans').textContent = data.data.qr_scans;
  });

Build docs developers (and LLMs) love