We built DEV3 AI Form Builder as a WordPress plugin in PHP with a React admin and a small vanilla-JS front end. Forms are stored as a normalised JSON definition (steps, fields, logic, payments, integrations) that both runtimes read.
Key design decisions
- One engine, two runtimes. Conditional logic (12 operators, all/any, step and field level), the formula language and the totals calculator exist twice:
src/shared/*.js for the live form and includes/Engine/*.php for the server. Both run the same 97 JSON fixture cases in Jest and PHPUnit, so a change that makes them disagree fails the build.
- No eval anywhere. Calculation fields use a recursive-descent parser with numbers,
{field_id} references, arithmetic, comparisons and nine functions (min, max, round, floor, ceil, abs, sqrt, pow, if). Division by zero gives 0, unknown references are 0, malformed formulas are rejected.
- Hidden means zero. Logic is evaluated first and blanks every hidden field and every field of a hidden step, so a product or extra the visitor cannot see never reaches the total.
- The server recomputes the charge. Values the browser posts for calculation and total fields are discarded.
Calculator::run() rebuilds them from the raw inputs, and that result becomes payment_total, converted to minor units with a zero-decimal currency list for Stripe.
- Hosted checkout only. Stripe Checkout Sessions and PayPal Orders v2, both as redirects, so no card data touches the site. The entry waits as pending, with notifications held, until the provider confirms.
- Returns that can't be forged. Return URLs carry an HMAC of the entry id. The Stripe session that gets verified is the one stored on the entry, never one from the URL; PayPal's token must match the stored order id. Completion is idempotent, and the Stripe webhook checks the signature with a five-minute replay window.
Architecture
The builder offers 35 field types, multi-step layouts, 8 templates and JSON import/export. Submissions pass a signed per-form token (so forms work behind full-page caches), honeypot, time trap and rate limit, validation against the same visibility map, the totals calculator and an optional AI spam check, then become entries with files stored privately. Entries live in their own tables with an inbox, notes, an activity log and CSV export, and are delivered by email, Mailchimp, Brevo, HubSpot, Google Sheets (through an Apps Script web app), Zapier or signed webhooks. DEV3 AI, on the Google Gemini API with the site's own key, drafts forms from one sentence, scores and summarises entries, drafts replies for approval, reads the conversion funnel and translates forms. The API client, encrypted key storage and usage budget come from a shared core used across DEV3's plugins.