Gatilab Products

Release Notes

Improvements, fixes, and the details behind each release.

Core Forms

Build forms, collect submissions, and connect the actions your site needs.

View Product
← All Core Forms Releases
Stable

Core Forms 4.1.0

Core Forms 4.1.0 — stable

Five months of beta cooking, condensed into one release: payments on submission, headless / cross-origin REST, six new payment-ready templates, a full admin redesign, and a bootstrap hardening that protects the site during plugin upgrades.

Payments on submission

Five providers, all bundled, all webhook-verified.

  • Stripe Checkout — hosted Checkout Sessions, test + live keys side-by-side
  • PayPal — Orders API, fixed or donor-driven amounts via [field] references
  • Razorpay — UPI / cards / wallets via Razorpay Checkout
  • Polar.sh — Standard Webhooks signature verification
  • FluentCart — hosted-checkout handoff. Free + Pro, one-time + subscriptions. Address fields prefilled into FluentCart's checkout (and its tax engine). Order paid → submission paid via fluent_cart/order_paid_done; refunds round-trip.

New submission statuses (pending_payment, paid, payment_failed, refunded), atomic CAS on the paid-state transition so concurrent webhook retries can't double-fire the action loop, return-URL signing with 2-hour expiry to stop replay.

Headless / cross-origin REST

External sites — Astro, Next.js, Vue, Svelte, plain HTML — can now render and submit Core Forms over REST. Same validation, captcha, action loop and payment redirect machinery runs server-side; the headless site just submits JSON.

  • GET /wp-json/core-forms/v1/forms/{id} — schema + rendered HTML
  • POST /wp-json/core-forms/v1/forms/{id}/submit — runs the full pipeline
  • GET /wp-json/core-forms/v1/embed.js — drop-in vanilla JS widget
  • Single API key per site (Settings → Headless), per-form opt-in toggle
  • Snippets in three flavours: widget, native fetch, cURL — each pre-filled with your actual submit URL + active key
  • New "Keeping the API key private" guidance card with copy-paste server-side proxy templates for Cloudflare Workers / Pages Functions, Next.js App Router, and Astro server endpoints

Six new payment-ready starting points

Each ships with a provider preselected so the form lands one configuration step away from working:

| Template | Provider | Pricing | |---|---|---| | One-time payment | Stripe | Fixed $19 | | Donation | PayPal | Donor-entered via [AMOUNT] | | INR payment | Razorpay | Fixed ₹999 | | FluentCart product | FluentCart | Variation-driven, with address fieldset | | Subscription | FluentCart Pro | Variation-driven, recurring | | Event ticket | Stripe | Tier select drives [TIER] |

Templates registry gained settings and messages callbacks alongside markup. Every starting point — payment and non-payment — now ships with a context-appropriate success message ("Redirecting to PayPal…", "Booking received…") instead of the generic "We will be in touch soon."

Admin redesign

  • Per-form Settings, Messages, Payment, Headless tabs converted to native <details>/<summary> accordions with state badges (rate-limit count, schedule "window set", honeypot on/off, FluentCart variation price/type/subscription summary, custom CSS/JS indicators, headless On/Off, configured/not-configured per gateway).
  • Per-form Submissions list rebuilt: Inbox / Spam / All view tabs with live counts (no more bouncing to global Spam to triage one form), redesigned table with status badges (New / Read / Replied / Archived / Paid / Pending payment / Refunded / Payment failed / Spam), row stripes for new/spam, per-row actions, relative dates with absolute on hover, varied empty states per view.
  • All Submissions page rebuilt for WordPress 7.0: toolbar split into a filter card (form picker + date range + Filter + Clear) and a search card. Consistent control heights so taller WP 7.0 native dates don't stagger the row. Side-fix: filter inputs are now in their own GET form so form_id / date_from / date_to actually land in the URL — previous version had them inside the bulk-actions POST form so filtering silently did nothing.
  • WordPress Screen Options dropdown hidden across all Core Forms admin screens.
  • Persistent "Akismet spam protection is active" banner removed from form-edit pages — status info doesn't belong as a banner on screens unrelated to it.
  • New cf_get_form_submissions / cf_count_form_submissions is_spam argument; new bulk_mark_spam per-form action.

Bootstrap hardening

  • vendor/autoload.php require now guarded with file_exists() so a mid-extraction race during a WordPress in-place plugin upgrade can't fatal the site. The upgrader replaces the plugin directory non-atomically; a hard require in that window kills every PHP request including wp-login.php. Now falls through cleanly and surfaces an admin notice on the next page load if vendor/ is genuinely missing.

Modernisation

  • Minimum requirements: PHP 8.1, WordPress 6.4
  • Schema\Field and Schema\FormSchema properties typed, declare(strict_types=1)
  • CI matrix runs PHP 8.1 / 8.2 / 8.3
  • prefers-reduced-motion respected throughout; logical-property RTL fixes
  • Fullscreen multi-step forms expose aria-current="step" + a polite live region for step changes

New filters + actions

cf_payments_orchestrator, cf_payment_completed, cf_form_default_settings, cf_form_templates. Full upgrade guide at docs/getting-started/upgrade-to-4.1.md.

Upgrading

Drop-in compatible from 4.0.x. The vendor-autoload guard means in-place WP upgrades from 4.0.x → 4.1.0 won't fatal even on slow filesystems. Database migrations run automatically on activation / via upgrader_process_complete.