Formora Form & survey builder script – one organisation, its team and every form it needs · Documentation Version 1.0.0
Version 1.0.0 · November 2026

Formora documentation

Formora is a complete form and survey builder script for one organisation – a company, school, club, clinic or nonprofit. Your team builds registrations, order and payment forms, surveys, quizzes, polls, job applications and contact forms in a drag-and-drop builder with 38 field types, shares them with a link, an embed or a QR code, and reads the answers in a results table with charts and exports. People who fill your forms never need an account.

One installation is one organisation under your own name, logo and colours. Forms can take one-time payments – registration fees, orders and donations – through Stripe, PayPal, Paystack, Razorpay or bank transfer. Every payment is a single payment; nothing renews. Answers can be sent anywhere through signed webhooks (Zapier, Make, n8n, Pabbly or your own server).

The Formora form portal with search, quick chips and live cards
The public form portal of the demo organisation: search, quick chips, live cards and every open form in one place.

Choose your path through this guide

Areas, roles & logins

Form portal /Your public list of open forms with search, categories, “How it works”, a give band and the install-app card. It can be switched off – then only direct form links work.
Public forms /f/your-formEvery form at its own address, plus embeds at /embed/your-form, the thank-you page, the payment step, receipts and certificates. Nobody needs an account.
Team area /adminDashboard, forms and folders, builder, design, settings, share, results, summary, templates, payments and – for the owner – every setting. The addresses can be changed with ADMIN_PATH and FORM_PATH in .env.
RoleWhat it can do
OwnerEverything: forms, results, payments (approve bank transfers, refunds), payment gateways, integrations, the team, appearance and every site setting. Created by the installer; there is always at least one owner.
EditorCreates, edits, publishes, closes and archives forms; sees, edits and exports responses – for all forms or only the forms and folders you choose.
ViewerSees responses and charts and exports them – read-only, for all forms or only chosen ones (for example a board treasurer who only sees fundraising).
Form fillerAnyone with the link. Fills the form, pays, gets the confirmation e-mail, receipt or certificate and can save and finish later.

With the demo data the accounts below exist (password password). While demo mode is on, the sign-in page shows one-click buttons: /demo-login/owner, /demo-login/editor and /demo-login/viewer.

RoleNameE-mail
OwnerDanielle Brooks, Executive Directordanielle@brightsidecc.org
Editor (Programs + Year-End Giving)Maria Delgado, Program Directormaria@brightsidecc.org
Editor (all forms)Ryan Patel, Operations Managerryan@brightsidecc.org
Viewer (Fundraising, results only)Carol Whitman, Board Treasurercarol.whitman@gmail.com

Demo accounts with two-step sign-in switched on skip the code only through the one-click demo buttons.

Sign-in page with the demo logins
Sign in for the team. People who fill forms never need an account.

Features

AreaIncluded
BuilderDrag and drop or click to add, 38 field types in 7 groups with search, pages, duplicate, undo / redo, device preview, field settings, options with prices and spot limits, conditional logic for fields and pages, calculations, draft and publish with versions, import / download a form as JSON.
LayoutsClassic (one page), one question at a time (keys A–F, Enter, arrows, welcome screen) and multi-step with a progress bar, Back / Continue, automatic review step and “save and finish later”.
Kinds of formsForms, surveys (NPS, stars, emoji, opinion scale, matrix, ranking), quizzes (score, pass mark, result screens, certificates), payment forms (products, quantities, donations, totals) and polls.
Templates36 ready templates in 11 categories – registration, events, payments, surveys, quizzes, feedback, HR, education, nonprofit, health and business.
SharingLink, custom address, prefilled links, inline embed, popup, side slider, floating button, full page, QR code in PNG / SVG with your logo, printable poster, social share, portal listing.
AccessOpen and close dates, scheduled opening with countdown, response limit, password, one response per person (e-mail, browser or both), anonymous responses, waitlist for full options.
ResultsDashboard, results table with search, filters, columns, bulk actions, tags, stars, notes and activity; summary charts with NPS gauge, funnel, drop-off by question, matrix heat map, top phrases; CSV, Excel and PDF exports.
PaymentsOne-time payments with Stripe, PayPal, Paystack, Razorpay and bank transfer (receipt + approval), server-side totals, discount codes, spots held for unpaid card payments, sales tax (off / one rate / by US state), receipts with your prefix, refunds.
AutomationTeam e-mail alerts, auto-reply with answer variables and a PDF copy, weekly summary e-mail, signed webhooks with retries for Zapier, Make, n8n, Pabbly or your own server.
Security & privacyHoneypot, rate limit, Cloudflare Turnstile / hCaptcha / Google reCAPTCHA, two-step sign-in, team roles with per-form access, private files with signed links, masked IPs, retention rules, export / erase one person’s data (GDPR / CCPA), S3-compatible storage.
Your brandLight and dark theme, 6 colour presets plus custom colours with automatic AA button text, per-form themes, logos, social networks, installable app (PWA) with offline page, languages with auto-translate, own pages, e-mail templates.
Portal on a phone
Portal on a phone
Payment form on a phone
Payment form
Survey in the dark theme
Survey, dark theme
Team dashboard on a phone
Team dashboard

Server requirements

ItemNeeded
PHP8.3 or newer (8.4 works)
PHP extensionspdo, pdo_mysql (or pdo_sqlite), mbstring, openssl, tokenizer, xml, ctype, json, fileinfo, curl, gd (with WebP), zip (Excel export, updates and backups)
DatabaseMySQL 5.7+ / MariaDB 10.4+ (recommended) or SQLite 3
Web serverApache or LiteSpeed with mod_rewrite (the .htaccess files are included), or Nginx
CronOne cron job every minute (webhook retries, spots of unpaid card payments, weekly summary, retention, backups)
HTTPSAn SSL certificate – needed for the payment gateways, embeds on other websites and the installable app

Everything needed to run is inside the package, including the vendor folder – no Composer, no Node and no build step on your server.

Package contents

Formora-v1.0.0.zip
├── formora/            the script (upload this)
│   ├── app, bootstrap, config, database, resources, routes, storage, vendor
│   ├── public/         assets (CSS, JS, fonts, icons, demo photos), uploads, codester/ (online documentation)
│   ├── index.php + .htaccess   let the whole folder run from a document root
│   └── start-windows.bat       local start on Windows
├── documentation/      this guide (open index.html)
└── START-HERE.txt

Install on cPanel / shared hosting

  1. Create the domain. In cPanel Domains add your domain or sub-domain (for example forms.example.org) and note its document root, for example /home/yoursite/forms.example.org.
  2. Create a database. cPanel MySQL® Databases: a new database, a new user with a strong password, and add the user to the database with All privileges.
  3. Choose PHP 8.3+. cPanel Select PHP Version or MultiPHP Manager; switch on the extensions listed under Server requirements.
  4. Upload. Upload Formora-v1.0.0.zip with the File Manager, Extract it, and move the contents of the formora folder into the document root, so that index.php, .htaccess, app, public … sit directly inside it. Show hidden files in the File Manager so the .htaccess files are moved too.
    • The included index.php and .htaccess send every request to the public folder and block the program folders – nothing private can be opened from the browser.
    • Alternatively set the document root of the domain to the public folder (Domains › Manage › Document root). Both ways work.
  5. Open your domain. The installer starts automatically (see The browser installer).
  6. Add the cron job in cPanel Cron Jobs, every minute (see Cron job).
  7. Switch on HTTPS (cPanel SSL/TLS Status → AutoSSL or Let's Encrypt), then Admin › General & languages › Always use https.

Install on a VPS (Nginx / Apache)

cd /var/www
unzip Formora-v1.0.0.zip
mv formora /var/www/formora
chown -R www-data:www-data /var/www/formora
chmod -R 775 /var/www/formora/storage /var/www/formora/bootstrap/cache /var/www/formora/public/uploads /var/www/formora/database

Nginx

server {
    listen 80;
    server_name forms.example.org;
    root /var/www/formora/public;
    index index.php;
    client_max_body_size 110M;
    gzip on;
    gzip_types application/json application/javascript text/css image/svg+xml application/manifest+json;

    location / { try_files $uri $uri/ /index.php?$query_string; }
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }
    location ~* \.(css|js|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; try_files $uri /index.php?$query_string; }
    location ~* \.(webp|png|jpe?g|svg|ico)$ { expires 30d; try_files $uri /index.php?$query_string; }
    location ~ /\.(?!well-known) { deny all; }
}

Set client_max_body_size (and PHP's upload_max_filesize / post_max_size) at least as large as the biggest upload you allow in Storage & privacy. SSL: certbot --nginx -d forms.example.org.

Apache

<VirtualHost *:80>
    ServerName forms.example.org
    DocumentRoot /var/www/formora/public
    <Directory /var/www/formora/public>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Then open the domain in the browser – the installer starts – and add the cron job for the web server user: crontab -u www-data -e.

Install on Windows (XAMPP / Laragon)

  1. Install XAMPP or Laragon with PHP 8.3+ and start Apache and MySQL.
  2. Unzip the package and copy the folder formora to C:\xampp\htdocs\formora (Laragon: C:\laragon\www\formora).
  3. Create an empty database in phpMyAdmin (for example formora, collation utf8mb4_unicode_ci).
  4. Open http://localhost/formora and follow the installer.
  5. Or double-click start-windows.bat in the folder: it starts PHP's own web server on http://127.0.0.1:8000 (PHP must be in the PATH).

The browser installer

On the first visit every address redirects to /install. The installer checks the server, writes the .env file with a new application key and sets up the database.

  1. Requirements – PHP version, extensions and writable folders, each with a clear mark.
  2. Database – MySQL / MariaDB (host, port, name, user, password – the connection is tested) or SQLite (no settings).
  3. Your organisation – organisation name, country and currency, time zone (new installs start with America/New_York), city and state, website address, Import demo data or Start empty, and the owner account.
  4. Progress – the import runs in short steps with a progress bar, each well under two seconds on a normal host, so it finishes on small shared hosting too. If the browser is closed, open the address again and press Retry: finished steps are not repeated.
Installer: database
Step 2: MySQL / MariaDB or SQLite.
Installer: your organisation, demo data and owner account
Step 3: your organisation, demo data, owner account.

The demo data tells one story: Brightside Community Center in Austin, Texas (Central Time) with a team of 7, 12 live, scheduled, closed and draft forms plus 4 archived ones – Summer Camp Registration 2027 with weeks, add-ons and a waitlist, Volunteer Sign-up, a Customer Satisfaction Survey with NPS, a Food Safety quiz with certificates, Year-End Giving, a job application, room booking, a food drive, gala tickets and more – about 9,000 completed responses, partly finished ones, payments through every method, tags, notes, webhooks, discount codes and Spanish and Vietnamese translations. The installer then locks itself (storage/app/installed.lock). To install again on a fresh database, delete that file and .env.

Start empty for your real website. You get the 36 templates, pages, e-mail templates, the built-in social networks and the default settings (United States, USD, English, America/New_York), ready for your own forms.

Cron job & scheduled tasks

Add one cron job that runs every minute (cPanel Cron Jobs → “Once Per Minute”):

* * * * * cd /home/yoursite/forms.example.org && php artisan schedule:run >> /dev/null 2>&1

Use the real path of the folder that holds artisan. On some hosts the PHP binary has a version in its path, for example /usr/local/bin/ea-php83 or /opt/cpanel/ea-php83/root/usr/bin/php.

TaskWhenWhat it does
fm:dailyevery 5 minutesRetries webhook deliveries (after 1, 5, 30, 120 and 720 minutes), frees the spots of card payments nobody finished after the hold time you chose, moves new uploads to S3-compatible storage when it is on.
fm:weeklyMondays, 7:47 AMSends the weekly summary e-mail to every team member who chose it in Your account.
fm:prunedaily, 3:41 AMRemoves old notifications and activity rows, and responses and unfinished responses past the retention you set.
fm:backup2 AM, daily or SundaysCompressed SQL backup when automatic backups are on.
fm:demo-todayevery 5 minutesDemo mode only – keeps “today” moving: new responses and payments arrive through the day, the dashboard and charts always end today.
fm:demo-resetevery 6 hoursDemo mode only – loads fresh demo data (your real team accounts and the gateway, mail, captcha, translation and storage keys are kept).

Admin › General & languages › Maintenance shows the exact cron line for your server.

First steps after installing

  1. General & languages – organisation name and legal name, contact details, address, country, currency, time zone, date format; portal switches.
  2. Appearance – pick a colour preset or your own colours, upload your logos and favicon, choose the default theme.
  3. Integrations – set up e-mail sending (SMTP) and send a test; add captcha keys if you want a captcha; add webhooks.
  4. Payment gateways – currency, sales tax and receipt prefix; switch on the gateways you use, paste the keys and copy the webhook URLs into the gateway dashboards.
  5. Team & roles – invite editors and viewers and choose which forms they see.
  6. Social networks and App (PWA) – add your social links, check the app name and icons.
  7. Your first form – Templates → Use template, or Forms › New form, then Build, Design, Settings and Publish.

The form portal

The home page lists your open forms as photo cards with time to finish, deadline, spots left and price, grouped by category, with a search, quick chips, “How it works”, a give band for your donation form and an install-app card. It carries your name and logo; a small “Forms by Formora” line can be switched off.

  • Turn it off in General & languages › Public form portal – then only direct form links work and the home page shows your logo and a short note.
  • Every text, menu link, chip, photo, category, step and the give band is edited in General & languages › Portal texts.
  • Each form decides in its Settings › Access whether it is listed and under which category; Share can feature it at the top.
Portal in the light theme
Light theme.
Portal in the dark theme
Dark theme.

Forms, folders & templates

Forms lists every form with folders and counts, search, status chips (live, scheduled, draft, closed, archived), sort and list or grid view. Quick actions: open the builder, results, share, duplicate, close, archive. An archived form can be restored or deleted for good (forms with payments keep their records).

Templates has 36 ready forms in 11 categories with mini previews; Use template makes a draft you can change freely. A form can also be downloaded and imported as a JSON file (in the builder) to move it between installations.

Forms list with folders
Forms with folders, status and quick actions.
Templates
36 templates in 11 categories.

The builder & 38 field types

Open a form and choose Build. Drag a field type from the palette onto the canvas or click it to add it below the selected field. Click a field to select it: the toolbar offers logic, duplicate, settings and delete; the right panel shows the question, help text, placeholder, required, width (full / half), options and the field’s own settings. The top bar has the layout switch, device preview (desktop, tablet, phone), undo / redo, Preview and Publish.

GroupField types
BasicShort text, Long text (with counter), Email, Phone, Number, Website, Name, Address (US states + ZIP)
ChoicesDropdown, Single choice, Checkboxes, Picture choice, Yes / No, Multi-select (chips)
Date & timeDate, Time, Date range
Rating & scalesStar rating, NPS (0–10), Opinion scale, Emoji scale, Matrix, Ranking
AdvancedFile upload, Signature, Calculation, Hidden field, Consent
PaymentsProduct, Donation amount, Total, Payment
LayoutHeading, Paragraph, Image, Divider, Page break, Section
  • Options can carry a price, a spot limit (“22 left”, “Full · waitlist”), an image and a note; Bulk add pastes many at once.
  • Every field has a key (for example parent_email) used in e-mail variables, prefilled links, exports and webhooks.
  • Changes are saved as a draft while you work; the live form only changes when you press Publish, and every publish is kept as a version. Responses always remember the version they were sent with.
  • On phones the builder has three tabs: Fields, Form and Settings.
The builder with the field palette, the canvas and the field settings
The builder: 38 field types, canvas with pages, field settings with prices and spot limits.

Conditional logic & calculations

Select a field and open Logic: Show or Hide it when all or any of the rules match. A rule compares another answer with is, is not, contains, does not contain, is greater than, is at least, is less than, is at most, is empty, is answered, is any of, has at least … chosen, is before, is after. Pages have their own logic, so whole steps can be skipped. Fields with logic show a small badge on the canvas (“Shows if allergies = Yes”).

The same rules run in the browser and on the server: hidden questions are never required and never block sending. A Calculation field works out a value from other answers (for example a score or a number of nights) with a safe formula – no code is run.

Layouts: classic, one at a time, multi-step

ClassicAll questions on one page with numbered sections – best for short forms and payment forms with a live order summary.
One question at a timeA welcome screen, one question per screen with a progress bar, letter keys A–F, Enter and arrow keys, up / down buttons and a done screen.
Multi-stepPages become steps with a progress bar, Back / Continue, an automatic review step and “save and finish later”.
One question at a time
One question at a time (Volunteer Sign-up).
Multi-step form
Multi-step (Job Application).
Classic form
Classic layout (Community Room Booking) with date, time, choices, address, file upload and signature.

Form design & themes

Design gives every form its own look with a live preview: 6 theme presets (Ultramarine, Coral pop, Butter, Lilac dream, Midnight, Paper), colours for buttons, page background, form card and text – the button text colour is picked automatically for contrast – your logo or organisation mark, a background photo, font, corner radius, button style (filled, outline, pill) and the progress bar.

Form design with presets and live preview
Design: presets, colours with automatic button text, photo, font and shape.

Form settings

SectionWhat you set
Team notificationsWho gets an e-mail for each response, subject, all answers in the e-mail, uploaded files attached (up to 10 MB), only when the payment is confirmed.
Auto-replyAn e-mail to the person who filled the form, with variables such as {parent_name}, {total}, {receipt_link} – every field key is a variable – and an optional PDF copy of the answers.
Limits & scheduleOpen and close date and time (the form shows “opens soon” with a countdown before), response limit, the messages when closed or full.
AccessPassword, one response per person (by e-mail address, this browser or both), save and finish later (an e-mail link valid for the days you set), listing on the portal and category.
Spam protectionHidden honeypot field, submissions per IP address per hour, captcha (see below).
Texts & buttonsSubmit, Next and Back labels, the welcome screen, numbered questions, prefilled links, anonymous responses, waitlist for full options, the form’s currency.
TagsLabels the team can put on responses (for example Scholarship, Needs follow-up).
After submitThank-you page (title, text, summary of answers, “Submit another response”) or redirect to an address, with answers passed as ?name={name}.
Form settings
Form settings: notifications, auto-reply, schedule, access and spam protection.
Form that opens soon
A scheduled form shows “opens soon” with a countdown.
Thank-you page with receipt
Thank-you page with the payment receipt.

Spam protection & captcha

The honeypot field and the rate limit work on every form without any setup. For a captcha, add the keys once in Integrations › Captcha keys – Cloudflare Turnstile, hCaptcha or Google reCAPTCHA (site key + secret key from the provider’s dashboard) – then pick it per form in Settings › Spam protection. Providers without keys are greyed out. The answer of the captcha is checked on the server before the response is stored. New forms start with the captcha chosen in General & languages › Forms.

Quizzes, scoring & certificates

A form of the kind Quiz gets a Quiz tab:

  • Scoring – score shown as a percentage, points or both; pass mark; negative marking; partial points for checkboxes.
  • Answers & points – the correct answer, points and topic of each question in one table, plus an explanation shown after submit.
  • Result screens – a different message for each score range.
  • Rules – time limit with a timer, shuffle questions and answers, show the correct answers and explanations, number of attempts and the wait between them (counted by e-mail address).
  • Certificate – a PDF with name, score and date for everyone who passes, with your title, “signed by” and how many months it is valid; a certificate number is printed on it.
Quiz settings
Quiz settings: scoring, answers, result screens, rules, certificate.
Quiz result
The result: score ring, pass mark, score by topic, certificate and answer review.

Surveys, NPS & polls

Surveys use the rating fields – NPS 0–10, stars, emoji scale, opinion scale, matrix and ranking – next to checkboxes and open text, and can be anonymous (no IP address or browser is kept). The Summary turns them into an NPS gauge with promoters, passives and detractors, star distribution, matrix heat map and top phrases. A poll is a short form whose summary shows the votes per option.

Survey with NPS, stars and matrix
Customer Satisfaction Survey: NPS, stars, emoji scale, matrix and ranking.

Link, prefill & custom address

Share shows the form link with a copy button, the custom address (/f/summer-camp-2027), prefilled links (?camper_first_name=Ava fills a question – switch it on in Settings), “Email the link”, social share buttons and the portal listing with “Feature at the top”. The social link preview uses the form title, description and cover photo.

Share: link, embed and QR code
Share: link, custom address, embed code and QR code.

Embeds: inline, popup, slider, button

Choose the embed type in Share and copy the code. It works with WordPress, Wix, Squarespace and plain HTML:

<script src="https://forms.example.org/embed.js" data-form="volunteer" data-mode="inline" data-height="auto" async></script>
AttributeValues
data-modeinline (in the page), popup (centred window), slider (side panel), button (floating button that opens the popup). “Full page” in Share is simply the form link.
data-heightauto – the frame grows with the form – or a number of pixels
data-header0 hides the form title and cover (when your page already has a heading)
data-transparent1 uses your page’s background
data-text, data-delayLabel of the button or tab; seconds before a popup or slider opens by itself

Any element of your page with data-formora-open="volunteer" opens that form’s popup. Payments started inside an embed open the payment step in a new tab, as the gateways require, and the frame shows the thank-you page. See preview shows all embed types on a sample page.

Embed preview
Embed preview: inline, popup, side slider and floating button.

QR code & poster

The QR card in Share makes a code for flyers and the front desk in the colour you choose, with your logo in the middle if you like, as PNG or SVG. Print poster makes a Letter-size PDF poster with your organisation, the form title and description, the QR code and the short address.

Dashboard

The dashboard shows live forms, responses today and this week, the completion rate, money collected this month, a 30-day chart against the previous period (7 / 30 / 90 days), top forms this week, recent responses, “Needs your attention” (bank transfers to approve, forms that close or open soon) and where responses come from (direct link, embed, QR code, social). Each member only sees the forms they may open.

Dashboard
Dashboard, light theme.
Dashboard in the dark theme
Dashboard, dark theme.

Results table & response detail

Results shows KPIs for the form’s kind (responses, collected, spots per option, completion, average score …), a search over answers, names and e-mails, filters (date range, status, payment, tag, starred, passed, answer of a question, test responses), the columns you want, bulk select with CSV / Excel / PDF / e-mail / delete, the payment status of each row and pagination. Results in the side menu lists every form’s newest responses.

A response shows the answers page by page, uploaded files (private, opened through short signed links), the signature, the payment with its gateway and transaction ID, tags, a star, team notes and the activity (auto-reply sent, webhook delivered, payment confirmed). Editors can edit answers; a PDF of the response is one click.

Results table
Results table with filters, columns and payment status.
Response detail
Response detail with payment, tags, notes and activity.

Summary charts

Summary turns every question into a chart: choice bars, NPS gauge with 0–10 bars, star distribution and average, matrix heat map, ranking, numbers, the completion funnel (viewed, started, completed), drop-off by question (where people stop), top phrases and the latest text answers. Filter by date range and export the summary as a PDF report.

Summary charts
Summary: NPS, funnel and drop-off.
Summary in the dark theme
The same in the dark theme.

Exports: CSV, Excel, PDF

Export the whole table, the filtered rows or only the selected ones as CSV, Excel (.xlsx) or PDF. The largest PDF and the most responses in one Results e-mail are settings in General & languages › Forms. Exports are written in parts, so large forms export on shared hosting too. Every export is noted in the privacy log.

E-mail alerts, auto-reply & weekly summary

  • Team alerts per form (Settings › Team notifications) and in the bell of every member who sees the form.
  • Auto-reply to the person with answer variables and a PDF copy.
  • Your account › Notifications I get – each member chooses: new responses of my forms, payments and bank transfers, and the weekly summary (sent Mondays by fm:weekly with the responses and money of the week and a link to the dashboard).
  • Every e-mail uses your logo, colours and social links; the texts are in E-mail templates.

Webhooks & automation apps

Integrations › Webhooks › Add webhook: a name, the address, the events and the forms (every form or chosen ones). Events: response.completed, response.updated, payment.paid, payment.refunded. Each delivery is a JSON POST with the form, the response (number, name, e-mail, score, total, payment status, tags, link) and every answer by field key. Send test sends a sample.

A receiver that does not answer with 2xx is tried again after 1, 5, 30, 120 and 720 minutes; then the delivery is marked failed and the owners get an e-mail. Paused webhooks get nothing.

Verify the signature

Every webhook has its own signing secret (shown when you edit it; “Make a new signing secret” replaces it). Each request carries:

X-Formora-Event: response.completed
X-Formora-Delivery: dlv_…              (the same on every retry – ignore repeats)
X-Formora-Signature: t=1730812345,v1=5f2c…   (HMAC-SHA256 of "t.body" with your secret)
// PHP receiver
$body = file_get_contents('php://input');
parse_str(str_replace(',', '&', $_SERVER['HTTP_X_FORMORA_SIGNATURE'] ?? ''), $sig);
$expected = hash_hmac('sha256', $sig['t'] . '.' . $body, 'YOUR_SIGNING_SECRET');
if (! hash_equals($expected, $sig['v1'] ?? '') || abs(time() - (int) $sig['t']) > 300) { http_response_code(400); exit; }
$event = json_decode($body, true);   // $event['answers']['parent_email']['value'] …
// Node.js receiver (Express, raw body)
const crypto = require('crypto');
const [t, v1] = req.get('X-Formora-Signature').split(',').map(p => p.split('=')[1]);
const ok = crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(crypto.createHmac('sha256', SECRET).update(t + '.' + req.rawBody).digest('hex')));

Zapier, Make, n8n, Pabbly Connect: start a new automation with the app’s webhook trigger (“Webhooks by Zapier › Catch Hook”, “Webhooks › Custom webhook”, “Webhook node · POST”, “Webhook trigger”), copy its address into Add webhook, press Send test and map the answers by their field keys. From there answers can go to Google Sheets, Slack, a CRM or any other app.

Integrations: webhooks, automation apps, SMTP and captcha keys
Integrations: signed webhooks, automation apps, e-mail sending and captcha keys.

Payments inside forms

Add Product fields (or prices on choice options), quantities, a Donation amount and a Total; the form then shows a live order summary and a payment step. Options can have spot limits – a full option shows “Full · waitlist” and can offer a free waitlist choice. Every payment is a one-time payment: the form says “One-time payment · nothing renews”, and there are no subscriptions.

  1. The person fills the form and chooses a payment method: card (Stripe), PayPal, Paystack, Razorpay or bank transfer.
  2. The server works out the total from the published form (prices, quantities, discount, sales tax) – the browser’s numbers are only a preview – and checks the spots under a lock.
  3. The response is stored as pending and the payment opens with the gateway. Spots of an unpaid card payment are held for the minutes you set (60 by default), then freed by fm:daily.
  4. When the gateway confirms the same amount and currency, the payment and response become paid, the receipt e-mail goes out, the team is told and the payment.paid webhook is sent.
Payment form with weeks, add-ons and order summary
Weeks with prices and spots, add-ons with quantity, live order summary.
Payment step with five methods
The payment step: card, PayPal, Paystack, Razorpay, bank transfer.

Sales tax, receipts & discount codes

  • Sales tax (Payment gateways): Off (default – nonprofits usually keep it off), One rate (a percentage for every order) or By US state (one line per state, for example TX | 8.25; the state comes from the form’s address question; other states pay no tax). Tax is added on what is sold after the discount and shown as its own line on the order and the receipt. Donations are never taxed.
  • Receipt prefix starts every payment reference, for example FM-12-00487 (prefix, form number, response number).
  • Currency of the site, and of each form if needed (fixed after its first payment). Each gateway can charge in its own currency with an exchange rate you set.
  • Discount codes are added in the builder’s Form panel of a payment form: a percentage or a fixed amount, the most uses, start and end date, on / off (demo: SIBLING15, EARLYBIRD). The server checks the code again when the form is sent.

Payment gateways & webhook URLs

Open Admin › Payment gateways. Each gateway has its own card: test or live mode, the keys, the charge currency and the webhook URL with a copy button. Keys are stored encrypted and shown masked. A gateway appears in your forms once it has its keys.

GatewayKeysWebhook URL / events
Stripe (cards worldwide)Publishable key, secret key, webhook signing secrethttps://your-site.com/webhooks/stripe – event payment_intent.succeeded
PayPalClient ID, secretNo webhook needed – the order is captured and checked with PayPal on the server when the payer returns.
Paystack (Nigeria, Ghana, Kenya, South Africa)Public key, secret keyhttps://your-site.com/webhooks/paystack – event charge.success (signed with your secret key, HMAC SHA-512, and confirmed again with the verify API)
Razorpay (India: UPI, cards, net banking, wallets)Key ID, key secret, webhook secrethttps://your-site.com/webhooks/razorpay – events payment.captured, order.paid
Bank transferBank name, account name, account number, routing / SWIFT, noteThe payer uploads the receipt; you approve it (see below).

Paste each webhook URL into the gateway's dashboard (Stripe Developers › Webhooks, Paystack Settings › API Keys & Webhooks, Razorpay Settings › Webhooks). The exact URLs for your domain are shown on each card. Use test keys and test mode first, then switch to live.

Payment gateways
Payment gateways with currency, sales tax, receipt prefix, keys and webhook URLs.

Bank transfer

With bank transfer on, the payment step shows your bank details and the payment reference to use. The payer uploads the transfer receipt (image or PDF – the largest size is a setting) and the payment waits as Pending approval; the payer sees “we are checking your transfer”. The team gets a bell message and an e-mail and the dashboard lists it under “Needs your attention”. Open Payments › Pending approval, view the receipt, check amount and currency, enter the bank reference and Approve – the payment is counted and the receipt e-mail goes out – or Reject with a reason (the payer gets an e-mail with a link to pay another way). A bank transfer waiting for review keeps its spots.

Thank-you page while a bank transfer is checked
What the payer sees while the transfer is checked.

Payments ledger & refunds

Payments shows collected, waiting for approval, refunded and failed amounts, and a table with date, payer, form, gateway, amount, status and the gateway transaction ID, with filters, search and CSV export. Owners can refund: refund in the gateway’s dashboard first, then record it here with the amount, reason and the gateway refund ID – the response, the form total and the payment.refunded webhook follow.

Payments ledger
Payments: one-time payments with gateway and transaction ID.

How payments are protected

  • The amount and currency always come from the stored payment, worked out on the server from the published form; what the browser sends is never trusted.
  • Every payment is confirmed with the gateway on the server (return page, capture, verify API) or by a signed webhook that is checked over the raw request body; a missing secret or a wrong signature is refused and changes nothing.
  • Each gateway transaction ID can be used once; completing a payment is idempotent and runs under a row lock, so a payment is counted once even when the return page and the webhook arrive together.
  • Totals and spots change only inside that verified completion. Nothing can be marked paid from the browser – also not in demo mode.
  • Bank transfer receipts are private files; only owners can approve them.

Every settings area

MenuWhat is in it
Team & rolesInvite, roles, per-form access, two-step sign-in reset, permissions matrix.
Payment gatewaysCurrency, sales tax, receipt prefix, hold time for unpaid card payments, Stripe, PayPal, Paystack, Razorpay, bank transfer, exchange rates.
IntegrationsWebhooks, Zapier / Make / n8n / Pabbly guides, e-mail sending (SMTP), captcha keys.
AppearanceColour presets, custom colours, default theme, motion, sun / moon button, logos, organisation mark, favicon.
Social networksYour links with icons, on / off, order, Add network.
App (PWA)App name, colours, start page, icons, install button, iPhone hint, offline page.
General & languagesTabs: General & languages (organisation, region, portal, sign-in, search engines, forms, languages), Portal texts, Pages, E-mail templates, Maintenance.
Storage & privacyThis server or S3-compatible storage, upload limits and allowed types, retention, IP addresses, one person’s data, consent and cookies, privacy log.

Team, roles & per-form access

Team & roles: invite a member by e-mail with a role (Owner, Editor, Viewer) and form access. The invite link lets them set a password. The table shows title, role, form access, last active and whether two-step sign-in is on; owners can reset a member’s two-step sign-in or remove a member (a removed member can be invited again later).

Per-form access: “All forms” or “Chosen forms” – single forms with can edit or results only, or whole folders (new forms in them are included). A member never sees a form they have no access to – not in the dashboard, the lists, search or exports. The permissions matrix below shows what each role can do.

Team and roles
Team & roles with form access, two-step sign-in and the permissions matrix.

Your account & two-step sign-in

Your account (click your name): name, job title and photo, e-mail, password (at least 10 characters; changing it signs out your other browsers), two-step sign-in and the notifications you get. Two-step sign-in asks for a 6-digit code from an authenticator app (Google Authenticator, Microsoft Authenticator, 1Password …) after the password, with 10 one-time recovery codes. Owners can reset a member’s two-step sign-in in Team & roles when a phone is lost.

Your account
Your account: profile, password, two-step sign-in, notifications.

Appearance, presets & dark mode

  • Colour presets: Ultramarine + Coral (default), Ink + Butter, Lilac + Coral, Sky + Ink, Plum + Peach, Cobalt + Rose. Click one – the page recolours so you see it at once.
  • Custom colours: primary (buttons, links), accent buttons (Give, Pay), the field-type accents (butter, lilac, sky), deep ink (footer) and the page background of the light and dark theme. The button text colour is chosen automatically so it passes WCAG AA, and the contrast is shown next to each colour.
  • Default theme: light, dark or follow the device. Visitors can switch with the sun / moon button; their choice is saved on their device (formora-theme) and applied before the page paints, so there is no flash.
  • Motion effects on / off (always off for people who prefer less motion), the sun / moon button on / off.
  • Logos for the light and dark theme, the square organisation mark used in forms and the portal, and the favicon. SVG files are cleaned of scripts; PNG and WebP are re-encoded.
Appearance
Appearance: presets, custom colours with AA check, default theme, logos.
Appearance in the dark theme
The team area in the dark theme.

Social networks

Social networks holds your organisation’s links, shown in the portal footer, the contact area and every e-mail. The built-in list has icons for Facebook, Instagram, X, YouTube, TikTok, LinkedIn, WhatsApp, Phone, Telegram, Threads, Pinterest, Snapchat, Discord, Email and Website. Switch each on or off, paste the link or number, drag to reorder and replace an icon. Add network adds any other one with a name, link and your own icon (SVG cleaned of scripts, PNG / WebP re-encoded, 512 KB max). WhatsApp and phone numbers are saved in international format (+1 512 555 0100) and open the app.

Social networks
Social networks with the footer preview.

App (PWA)

People can install the form portal like an app on Android, iPhone and desktop. App (PWA) sets the app name, short name (12 characters), theme and background colour, start page, display mode, description and icons (upload one 512 × 512 PNG – the 192, maskable and 180 sizes are made for you). Switch the “Install app” button and the iPhone hint (“Share › Add to Home Screen”) on or off and edit the offline page. The service worker caches only static files – never form answers or private data; answers on an open form stay on the device until they are sent.

App (PWA) settings
App (PWA) with the home-screen preview.
Offline page
The offline page.

General settings & portal texts

  • Organisation: name, legal name (receipts), tagline, contact e-mail, phone, street address, city and state, ZIP code, the region shown under the name.
  • Region: country, currency, time zone, date and time format, first day of the week (used by “this week” on the dashboard, in Results and the weekly summary).
  • Public form portal: show the portal, list new forms, search on the portal, “Forms by Formora”.
  • Sign in: the shortest password of the team. Search engines: portal title and description, share image, sitemap, always use https.
  • Forms: layout and captcha of new forms, most fields per form, most rows in a PDF export, responses per page, most responses in one Results e-mail, “Closing soon” days on the dashboard, “N spots left” from.
  • Portal texts: top line, header menu, hero, quick chips, photos, categories, “How it works”, give band, install-app card, footer, newsletter box and the sign-in page.
  • Pages: your own pages (about, privacy policy, terms) at /p/your-page, linked in the footer.
General and languages
General & languages with the language list.

Languages & auto-translate

Forms, the portal, the payment step, e-mails and the team area are in English. Add a language in General & languages › Languages › Add language; visitors then see the forms in their language when a translation exists (a language switch appears on the portal). New languages are filled in with auto-translate: choose the translation service under Translation service – DeepL (free or pro key), Google Cloud Translation (API key) or a LibreTranslate server – and press Auto-translate missing. Every line stays editable in the translation editor; a translation that would break a placeholder or tag is skipped. The demo includes Spanish (US) and Vietnamese for every public text.

Languages and the translation editor
Languages with auto-translate and the translation editor.

E-mail sending & templates

Integrations › Email (SMTP): send with your SMTP server (host, port, TLS / SSL, username, password, from name and from e-mail) or the server’s sendmail; Send test email checks it. Use a from address on your own domain.

General & languages › E-mail templates holds the subject and text of every e-mail – payment receipt, bank transfer received / not found, finish your form later, new response and payment for the team, bank transfer to check, team invite, password reset, webhook failing and the weekly summary – with placeholders such as {name}, {form}, {reference}. Send me a test shows the result in your inbox.

E-mail templates
E-mail templates with placeholders.

File storage (S3) & privacy

  • File storage: this server (default) or S3-compatible storage – Amazon S3, Wasabi, Backblaze B2, Cloudflare R2, DigitalOcean Spaces or MinIO – with endpoint, bucket, region, access key and secret and a Test connection button. New files stay on your server first and move to the bucket an hour after the response is sent. Files open only through signed five-minute links, for team members who may see the form.
  • Uploads: largest file size (5–100 MB; each upload field can set less) and allowed types (default pdf, jpg, jpeg, png, webp, heic, doc, docx; each field can allow fewer). Photo location data (EXIF) is removed and photos are re-encoded.
  • Retention: delete responses after 6–36 months or never, unfinished responses after 7–90 days, uploaded files with their response. Payment records are kept for the books.
  • IP addresses: keep them (spam protection and one response per person) and store them masked (72.181.xx.xx).
  • A person’s data (GDPR / CCPA): find everything one e-mail address sent you, then export it or delete it. Payment records stay for tax, without the personal details.
  • Consent & cookies: a privacy consent box for new forms with your text, a cookie notice on the portal and the privacy policy link. The privacy log lists exports and data requests.
Storage and privacy
Storage & privacy: S3-compatible storage, uploads, retention and data requests.

SEO & speed

Every form has its own title, description and share image (the cover photo) for search engines and social previews; the portal has its own in General & languages. /sitemap.xml lists the portal and the listed live forms; /robots.txt points to it. Pages are light: no build step, own CSS and JavaScript, fonts on your server, images in WebP, long cache times for static files through the included .htaccess.

Backups & maintenance

General & languages › Maintenance:

  • Maintenance page with your title and message – visitors see “back soon”, the team keeps working and payment webhooks keep arriving.
  • Backups: Back up now, automatic backups every night or every Sunday at 2 AM, how many to keep, download. Backups are private files in storage/app/private/backups.
  • Update: installed and file version, waiting database steps, server requirements, Run update.
  • Scheduled tasks: the cron line for your server. Panel addresses: the team area and form addresses (change them with ADMIN_PATH and FORM_PATH in .env).
Maintenance
Maintenance: maintenance page, backups, update and the cron line.

Demo mode

For a public demo set in .env:

DEMO_MODE=true
APP_DEBUG=false
  • Every public form can be filled and sent (uploaded files are replaced by samples), and payment forms run through to the bank-transfer step with sample bank details. In the team area visitors can add notes, tags and stars and approve or reject bank transfers. Form edits, settings, gateways, the team, languages, deletes and the updater are locked. A short ribbon on top says it is a demo (text in Maintenance).
  • The sign-in page shows one-click logins: /demo-login/owner, /demo-login/editor, /demo-login/viewer.
  • No e-mail and no webhook leaves the demo.
  • With the cron job running, fm:demo-today keeps the day current every 5 minutes and fm:demo-reset reloads the demo every 6 hours. Run once after installing: php artisan fm:demo-reset --force.

Updating

  1. Make a backup (General & languages › Maintenance › Back up now) and download it with a copy of your files.
  2. Upload the files of the new version over the old ones. Keep .env, storage and public/uploads.
  3. Open General & languages › Maintenance › Update and press Run update (or run php artisan fm:update). It applies the database changes and new default settings.
  4. Reload with Ctrl + F5.

Artisan commands

CommandWhat it does
php artisan fm:admin-password you@example.comNew password for a team account (random when you leave it out).
php artisan fm:backupCompressed SQL backup now.
php artisan fm:updateDatabase changes and new settings after uploading a new version.
php artisan fm:dailyWebhook retries, spots of unpaid card payments, moving files to S3-compatible storage.
php artisan fm:weeklySends the weekly summary e-mail now.
php artisan fm:pruneOld notifications and activity rows, responses past their retention.
php artisan fm:demo-reset --forceFresh demo data (demo mode only).
php artisan fm:demo-todayMoves the demo day to now (demo mode only).
php artisan fm:scan-stringsCollects new texts for the translation editor.

FAQ & troubleshooting

The page shows “500” or a blank page

Check that storage, bootstrap/cache and public/uploads are writable and that PHP is 8.3+. Set APP_DEBUG=true in .env for a moment to see the message, then set it back. The log is in storage/logs.

The installer does not start / shows 404

The .htaccess file did not reach the document root (hidden files) or mod_rewrite is off. Alternatively point the document root to public.

E-mails do not arrive

Use Send test email in Integrations and read the message it returns. The from address should belong to your domain; ask your host for the SMTP details.

A card payment still shows as pending

Check that the webhook URL is added in the gateway dashboard with the events listed above and that the signing secret in Payment gateways matches. PayPal needs no webhook.

My webhook receiver says the signature is wrong

Compute the HMAC over the raw request body exactly as received (before any JSON parsing), as timestamp + "." + body, with the webhook’s own signing secret.

The embedded form does not show on my website

Your site must use HTTPS. Check that the form is live and that the data-form value is the form’s address (the part after /f/).

Uploads fail for large files

Raise PHP’s upload_max_filesize and post_max_size (and Nginx client_max_body_size) to at least the size set in Storage & privacy.

Can people pay monthly?

Formora takes one-time payments only – registration fees, orders, tickets and donations. There are no subscriptions and nothing renews.

How do I move the team area to another address?

Set ADMIN_PATH (and FORM_PATH for the forms) in .env; Maintenance shows the current addresses.

Credits & licences

  • Laravel and PHP libraries (MIT), dompdf (LGPL), stripe-php (MIT).
  • Fonts: Plus Jakarta Sans and Instrument Serif (SIL Open Font License, included in public/assets/licenses).
  • Icons: Lucide (ISC). Demo photos: free stock photos (Pexels licence, listed in public/assets/licenses/PHOTO-CREDITS.txt); the demo people and organisation are invented.

Changelog

1.0.0 – November 2026

Initial release: form and survey builder for one organisation with a public form portal; drag-and-drop builder with 38 field types in 7 groups, pages, conditional logic for fields and pages, calculations, drafts and published versions; classic, one-question-at-a-time and multi-step layouts with save and finish later; surveys with NPS, stars, emoji, matrix and ranking; quizzes with scoring, pass mark, result screens, attempts, time limit and PDF certificates; polls; 36 templates; per-form design themes; access rules (schedule, limit, password, one response per person); honeypot, rate limit and Turnstile / hCaptcha / reCAPTCHA; link, prefill, embeds (inline, popup, slider, button), QR code and poster; dashboard, results table, response detail with notes, tags and activity, summary charts with funnel and drop-off; CSV, Excel and PDF exports; team alerts, auto-reply, weekly summary; signed webhooks with retries; one-time payments with Stripe, PayPal, Paystack, Razorpay and bank transfer, discount codes, sales tax, receipt prefix and refunds; team roles with per-form access and two-step sign-in; light and dark theme, colour presets, installable app, social networks, languages with auto-translate, S3-compatible storage, privacy tools, backups, one-click update and demo mode.