Home›Loyalora›Quickstart
Loyalora · Quickstart

Loyalora Quickstart, as shipped in the download

The QUICKSTART.txt in the download — the same steps your delivery email carries.

LOYALORA — QUICKSTART
=====================

Loyalty & rewards register. Self-hosted PHP 8 + MySQL/MariaDB or SQLite.
No Composer, no build step, no external services.


1 · WHAT YOU NEED
-----------------
  * PHP 8.0 or newer with PDO (pdo_mysql or pdo_sqlite)
  * MySQL/MariaDB, OR nothing at all if you use SQLite
  * Any web server that serves PHP


2 · INSTALL (2 minutes)
-----------------------
  a. Upload the "app" folder to your server.
  b. Point a domain or subdomain at it.
  c. Open it in a browser. The installer runs automatically.
  d. Choose SQLite (zero config) or enter your MySQL details.
  e. Create your admin account. Done.

  The installer writes config.php. If you would rather write it yourself,
  copy config.sample.php to config.php and fill it in.


3 · TAKE A LOOK FIRST
---------------------
  With PHP on your own machine:

      cd app
      php -S localhost:8080

  Then open http://localhost:8080 and follow the installer.

  Or with Docker, from inside the app folder:

      docker compose -f deploy/compose.yml up -d

  Load the sample scheme from Settings -> Demo data. It contains a customer in
  every state — one who can afford the top reward, one a handful of points
  short, one who has redeemed before, one brand new at zero, and an inactive
  customer who still holds points — plus both program kinds running side by
  side, so you can see what the register is actually for.
      (demo login: admin@loyalora.app with the one-time password it prints — change it)


4 · WEB SERVER SNIPPETS
-----------------------
  Apache — the shipped .htaccess handles routing. Just:

    <VirtualHost *:80>
      ServerName loyalty.example.com
      DocumentRoot /var/www/loyalora/app
      <Directory /var/www/loyalora/app>
        AllowOverride All
        Require all granted
      </Directory>
    </VirtualHost>

  nginx:

    server {
      listen 80;
      server_name loyalty.example.com;
      root /var/www/loyalora/app;
      index index.php;
      location ~ ^/(src|data|bin|tests|controllers|deploy|cron)/ { deny all; }
      location ~ ^/views/.+\.php$ { deny all; }
      location ~ (^|/)(config\.php|\.demo-mode)$|\.sqlite$ { deny all; }
      location = /install/ { rewrite ^ /install/index.php last; }
      location / { try_files $uri /index.php?$query_string; }
      location ~ \.php$ { try_files $uri =404; include fastcgi_params; fastcgi_pass unix:/run/php/php8.3-fpm.sock;
                          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }
    }


5 · FIRST FIVE MINUTES IN THE APP
---------------------------------
  1. Programs. Create one. Choose how it earns:
       - points per amount spent (e.g. 1 point per unit, rounded down), or
       - stamps per visit (e.g. the tenth coffee free).
     Most businesses need exactly one program.
  2. Rewards. Add what the points are FOR. Points with nothing to spend them
     on are just a number.
  3. Customers. Add someone, or import a list you already keep (Customers ->
     Import CSV — it runs a dry run first and writes nothing until you
     confirm). An imported opening balance arrives as an adjustment entry
     reading "Imported opening balance", because a balance is the sum of the
     ledger and the ledger has to say where it came from.
  4. Open a customer's card and record what they spent. You enter what
     HAPPENED, never a number of points — the program's rate decides.
  5. When their balance reaches a reward, it appears on their card as
     "Can have right now", redeemable in place.
  6. Team. A clerk can redeem. Only a manager can ADJUST — the only entry
     that creates or destroys points with nothing behind it but a reason.


6 · GOING FURTHER
-----------------
  * API.md — REST API, signed webhooks, and the MCP endpoint for assistants.
  * Settings -> API & Webhooks — mint a key. Choose "Read only" for anything
    that should answer questions but never change anything.
  * Settings -> Outbound mail — one customer's own balance, through your own
    SMTP, off until you switch it on.
  * The ledger (/entries) — every entry ever written, filterable, exportable.
  * Points outstanding (/statement.pdf) — what the scheme owes, for the books.
  * Backup & restore — JSON export always; a byte-exact .sqlite download on
    SQLite installs. Restore previews the diff before it commits.


7 · HONEST LIMITS
-----------------
  * Loyalora is NOT a marketing tool. No campaigns, no mailing lists, no
    segments, no send-to-all — and that is a design decision, not a gap.
  * It holds no card numbers, takes no payments and connects to no till.
  * A balance is the sum of the ledger. There is no way to type a balance in,
    on any screen or endpoint, because there is nowhere to put it.
  * Entries are never edited or deleted. A mistake is corrected with a new,
    opposite entry and a reason.
  * Points earned are not voided when a program is switched off or a
    customer is set inactive. They were earned under the terms that applied
    then, and the register does not rewrite that.


8 · SUPPORT
-----------
  README.md covers the design decisions. Run `php tests/run.php` to prove the
  install against its own suite — including the parallel-process race that
  proves two people cannot spend the same points.

LOOKING AFTER IT (from 4.0)
---------------------------
  * Updates: open Updates in the menu, save your license key once, press Check for updates.
    Reaching 4.0 from 3.x is the last update by hand: replace the files; config.php and data/ stay.
  * Sample data: the installer offers to start with a sample; remove it later with one click.
  * Backups: "Back up once a day by itself" is on by default (/restore); add an S3-compatible bucket there for
    a copy somewhere else. The Health page (/health) says whether all of this is working.
  * On Nginx: use the NGINX lines above; they open the installer and keep data/ private.
  * One-line install for technical owners:
    curl -fsSL https://ownware.io/install.sh | sh -s -- loyalora <your license key>

← Back to Loyalora · Manual · API · Test run