=== PBJ Form Builder ===
Contributors: pbj
Tags: forms, form builder, payments, square, stripe, paypal, captcha, honeypot, shortcode
Requires at least: 5.8
Tested up to: 6.8
Requires PHP: 7.4
Stable tag: 1.4.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Build unlimited forms with custom fields, drop them anywhere via shortcode, and accept payments through Square, Stripe, or PayPal. Built-in math CAPTCHA and honeypot — no Google.

== Description ==

PBJ Form Builder is a self-hosted form plugin built for sites that want to collect submissions (and optionally take payment) without sending anyone's data through Google's reCAPTCHA.

= Core =

* Unlimited forms, each with its own shortcode `[pbj_form id="N"]`
* Standard field types — text, email, phone, URL, number, date, paragraph, dropdown, radio, checkbox, consent, hidden — plus a "Custom" type for user-defined inputs
* Per-form settings: gateway, price, submit-button label, success message, redirect URL, anti-bot toggles
* Submission storage in WordPress (own admin screen, filterable by form)
* Optional admin email notification on every submission

= Anti-bot, no Google =

* **Built-in math CAPTCHA** ("3 + 5 = ?") signed with a per-request HMAC — no transients, no database writes, works on cached pages
* **Honeypot** hidden field that real humans never fill in
* **Time-trap** — submissions arriving in under N seconds are rejected
* **Per-IP rate limit** — configurable, hour-long window

= Payments =

* **Square** — Web Payments SDK in the browser, server-side `/v2/payments` charge
* **Stripe** — Stripe.js Elements card in the browser, server-side PaymentIntents charge (test vs live decided by which keys you enter)
* **PayPal** — Smart Buttons, server-side order create + capture, with amount verification to prevent tampering
* Sandbox and production environments configurable per gateway (Square/PayPal)
* Admin sets a fixed price per form
* Optional plain-text buyer receipt email on every paid submission

== Installation ==

1. Upload `pbj-form-builder.zip` via Plugins → Add New → Upload Plugin, or extract into `wp-content/plugins/`.
2. Activate the plugin.
3. Go to **Form Builder → Settings**, enter your Square and/or PayPal credentials, pick currency, save.
4. Go to **Form Builder → Add New**, build the form, set price and gateway.
5. Copy the shortcode from the form's edit page and paste it into a page or post.

== Upgrade Notice ==

= 1.2.0 =
Stripe gateway, buyer receipt emails, richer admin notifications, and security hardening: proxy-IP trust filter, single-use CAPTCHA tokens, idempotent charges, PayPal order throttling, reserved field keys, and non-JS submission feedback.

= 1.0.0 =
Initial release.

== Changelog ==

= 1.4.0 =
* **Guided admin.** Every admin screen now explains itself in plain English. The Forms list opens with a "Getting started" card: a live status checklist (forms created, payment provider configured — optional, PBJ License Manager detected — optional) plus five numbered how-to steps covering building, embedding by slug/title (never numeric id — IDs change on a Studio→Live sync), testing, charging money, and the built-in anti-bot layers.
* **Builder intro.** The Add/Edit screen explains how the page works (title = shortcode title match, one row per field, the Required toggle, what each field type is for, field keys, half/full width) and now shows the recommended slug-based shortcode alongside the title and id variants.
* **Submissions intro.** The Submissions screen explains filtering by form, how paid amounts are stored (cents) and displayed, and what the View and Delete actions do.
* **Settings walkthroughs.** Each settings section now says exactly what it does and where to find credentials: Square (Developer Dashboard → Credentials/Locations, sandbox vs production), Stripe (Dashboard → Developers → API keys, test vs live by key prefix), PayPal (Developer Dashboard → Apps & Credentials, sandbox vs live), plus buyer receipts, anti-bot master switches, and general defaults.
* No functional or database changes — documentation/UI only.

= 1.3.0 =
* Added a License section in the plugin's settings where you enter your PBJ license key to unlock automatic updates. The plugin is fully functional without a key; a key covers up to 3 sites, and on pbj.tech itself no key is required.

= 1.2.0 =
* **Stripe gateway.** Stripe.js Elements card field in the browser, server-side PaymentIntents charge. No environment toggle — test vs live is decided by which keys (pk_test_/sk_test_ vs pk_live_/sk_live_) you enter.
* **Buyer receipt emails.** Paid submissions email the buyer a plain-text receipt (fields, amount, transaction ID, gateway). Configurable subject with a `{form}` placeholder and optional From name; replies go to the admin notification address.
* **Richer admin emails.** The admin notification now includes Amount / Transaction ID / Gateway on paid submissions and sets Reply-To to the buyer's email.
* **Security: proxy-IP trust filter.** `CF-Connecting-IP` / `X-Forwarded-For` are no longer trusted by default (they are trivially spoofable); return true from the `pbj_form_builder_trust_proxy_headers` filter when you're behind Cloudflare or a proxy you control.
* **Security: single-use CAPTCHA tokens.** Math-CAPTCHA tokens are now bound to the form ID and burned after one successful validation, closing a replay window.
* **Security: idempotent charges.** Square and Stripe idempotency keys are derived from the card token/payment method, so a retried submission can never double-charge.
* **Security: PayPal order throttling.** The create-order REST route now enforces the same per-IP rate limit as form submission.
* **Security: reserved field keys.** Field keys that would collide with the plugin's own POST inputs (`action`, `form_id`, `square_token`, CAPTCHA fields, etc.) are silently prefixed with `f_`.
* **Time-trap hardening.** A missing render timestamp is now rejected as too-fast instead of skipping the check.
* **Non-JS feedback.** Visitors without JavaScript now see the success or error message rendered server-side after the redirect back to the form page.
* **Paid-but-unsaved alerting.** If a payment captures but the submission row fails to save, the plugin logs a critical line and emails the admin with the transaction details for recovery.
* Settings schema bumped to db_version 2 (new Stripe + receipt keys backfilled automatically).

= 1.1.1 =
* The `[pbj_form]` shortcode also resolves by exact `title`, e.g. `[pbj_form title="Contact PBJ.Tech"]`. Like `slug`, the title survives a Studio→Live clone, so it keeps resolving after a sync.

= 1.1.0 =
* The `[pbj_form]` shortcode now accepts a `slug` attribute, e.g. `[pbj_form slug="contact-pbj-tech"]`. Slugs survive a Studio→Live clone (numeric post IDs do not), so slug-based shortcodes keep resolving after a sync. The numeric `id` attribute still works.

= 1.0.0 =
* Initial release.
* Forms CPT with shortcode renderer and field repeater builder.
* Standard field types + custom field type.
* Math CAPTCHA, honeypot, time-trap, per-IP rate limit.
* Square Web Payments SDK integration.
* PayPal Smart Buttons integration with capture verification.
* Submission storage with admin list and detail view.
* `Update URI` header + self-hosted updater for in-place upgrades.
* Settings schema versioning with idempotent migrations.
