PRD.md defines product requirements across 4 phases (critical fixes, React admin, frontend enhancements, missing features). TASKLIST.md breaks all work into checkable tasks with file references. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
10 KiB
Formipay — Product Requirements Document
Version: 1.0 Date: April 17, 2026 Status: Approved for Implementation
1. Current State
Formipay is a WordPress payment form plugin (~60 files, ~15,000 lines). It supports:
- Custom post types for Forms, Products, Coupons, Access Items, Licenses
- Payment gateways: PayPal, Bank Transfer
- Custom database tables for Orders, Customers, Tokens, Notification Logs
- Admin pages via WPCFTO framework + Vue.js partial editor
- Public form rendering via PHP shortcode
[formipay]
A comprehensive audit (FINDINGS.md) identified 6 critical bugs, 6 moderate bugs, 10 security concerns, and 12 performance issues. Several features are stubs or incomplete (ExchangeRateAPI, License API, stock management, tax system).
2. Product Vision
Transform Formipay into a production-ready, modern WordPress payment plugin using an incremental modernization strategy:
- Fix all critical bugs immediately (Phase 1)
- Introduce React for admin UX (Phase 2)
- Enhance frontend with React islands while preserving SSR as default (Phase 3)
- Complete missing features (Phase 4)
This follows the same pattern used by WooCommerce, GiveWP, and Gravity Forms: SSR for public forms, React for admin.
3. Phase 1 — Critical Fixes & Stabilization (Weeks 1–2)
Goal
Make the plugin production-ready. Zero fatal errors, no critical security holes, acceptable performance.
Requirements
| ID | Requirement | Files |
|---|---|---|
| F1.1 | Fix Customer::update() undefined $table_name and $new_args — fatal error on every update |
includes/Customer.php |
| F1.2 | Fix Order::delete() — uses $id instead of $order_id parameter |
includes/Order.php |
| F1.3 | Fix Order::formipay_bulk_delete_order() — iterates $ids but calls delete($order_id) instead of loop variable |
includes/Order.php |
| F1.4 | Fix Email::send_email() — calls non-existent \Formipay_Notification:: instead of parent:: |
includes/Notification/Email.php |
| F1.5 | Fix Paypal::auto_cancel_order_on_timeout() — missing use Formipay\Order as Order import |
includes/Integration/Paypal.php |
| F1.6 | Fix Paypal::paypal_settings — undefined property, no declaration |
includes/Integration/Paypal.php |
| F1.7 | Fix BankTransfer::add_unique_code_details() — calls check_unique_code() 3 times, may get different values |
includes/Payment/BankTransfer.php |
| F1.8 | Fix color field label showing "Number" instead of "Color" | admin/functions.php |
| F1.9 | Add nonce check to Customer::formipay_tabledata_customers() |
includes/Customer.php |
| F1.10 | Replace maybe_serialize() in cookie handling with json_encode() |
includes/Order.php |
| F1.11 | Move flush_rewrite_rules() from init to activation hook only (Thankyou + Payment) |
includes/Thankyou.php, includes/Payment/Payment.php |
| F1.12 | Add PayPal webhook signature verification | includes/Integration/Paypal.php |
| F1.13 | Cache formipay_currency_array() and formipay_country_array() JSON reads in static variables |
admin/functions.php |
| F1.14 | Add pagination to Customer::formipay_tabledata_customers() |
includes/Customer.php |
| F1.15 | Optimize Order::formipay_tabledata_orders() — use COUNT(*) GROUP BY status |
includes/Order.php |
| F1.16 | Delete Paypal.phpbak backup file from production |
includes/Integration/Paypal.phpbak |
| F1.17 | Add uninstall.php for cleanup (options, tables, scheduled events) |
uninstall.php (new) |
Success Criteria
- Zero PHP fatal errors on all CRUD operations (Customer, Order, Product, Coupon)
- All admin-ajax endpoints have nonce verification
flush_rewrite_rules()fires only on activation/deactivation- PayPal webhook rejects unsigned payloads
- Customer table pagination works for 10,000+ records
4. Phase 2 — React Admin Foundation (Weeks 3–6)
Goal
Set up React build pipeline and migrate the highest-value admin pages to React.
Requirements
| ID | Requirement | Deliverable |
|---|---|---|
| F2.1 | Set up @wordpress/scripts build pipeline with webpack |
package.json, webpack.config.js |
| F2.2 | Create React component library structure (DataTable, SettingsPanel, Modal, StatusBadge) | src/admin/components/ |
| F2.3 | Create API client layer with nonce handling | src/admin/api/client.js |
| F2.4 | Build drag-and-drop form builder (replace Vue editor) | src/admin/pages/FormBuilder/ |
| F2.5 | Build order list page with filters and status management | src/admin/pages/Orders/ |
| F2.6 | Build order detail view (replace Handlebars templates) | src/admin/pages/Orders/Detail.jsx |
| F2.7 | Build analytics dashboard (orders, revenue, charts) | src/admin/pages/Dashboard/ |
| F2.8 | Build global settings page (replace WPCFTO dependency) | src/admin/pages/Settings/ |
| F2.9 | Build product editor page | src/admin/pages/Products/ |
| F2.10 | Build coupon editor page | src/admin/pages/Coupons/ |
| F2.11 | Build notification log viewer | src/admin/pages/Notifications/ |
| F2.12 | Build license management page | src/admin/pages/Licenses/ |
Success Criteria
npm run buildproduces working admin bundle- Form builder supports drag-and-drop, live preview, field settings
- Order management supports filtering, status changes, pagination
- All existing WPCFTO settings migrated to React UI
- Vue admin code deprecated but not yet removed
5. Phase 3 — Frontend Enhancements (Weeks 7–10)
Goal
Add React-powered frontend features while keeping SSR as the default rendering mode.
Requirements
| ID | Requirement | Deliverable |
|---|---|---|
| F3.1 | Implement React island architecture — optional React mode alongside SSR | src/frontend/widgets/FormRenderer.jsx |
| F3.2 | Add render mode setting per form: "Classic (SSR)" or "Modern (React)" | Admin setting + Render.php update |
| F3.3 | Implement multi-step form navigation (missing in current SSR) | src/frontend/widgets/MultiStepForm.jsx |
| F3.4 | Register Gutenberg block formipay/form with block.json |
src/frontend/blocks/formipay-form/ |
| F3.5 | Build customer order history page | src/frontend/widgets/CustomerPortal/ |
| F3.6 | Build order detail / download access page | src/frontend/widgets/OrderDetail.jsx |
| F3.7 | Add [formipay_my_orders] shortcode for customer portal |
PHP + React widget |
Success Criteria
- SSR mode works identically to current behavior (no regression)
- React mode provides multi-step navigation and real-time validation
- Gutenberg block renders form in editor with live preview
- Customer portal shows order history and download links
- Both render modes share the same PHP backend API
6. Phase 4 — Missing Features (Weeks 11–16)
Goal
Complete all stubbed and missing features identified in the audit.
Requirements
| ID | Requirement | Priority |
|---|---|---|
| F4.1 | Implement ExchangeRateAPI (currently empty class) | High |
| F4.2 | Implement License API endpoints (verify, activate, deactivate, revoke — currently stubs) | High |
| F4.3 | Add Stripe payment gateway | High |
| F4.4 | Add tax calculation engine | Medium |
| F4.5 | Implement stock management (decrement on order, validation, "out of stock" UI) | Medium |
| F4.6 | Add product variations on frontend (variation dropdown rendered) | Medium |
| F4.7 | Build donation form mode (pay-what-you-want, suggested amounts) | Medium |
| F4.8 | Add refund workflow (full and partial refunds) | Medium |
| F4.9 | Add PDF invoice generation | Medium |
| F4.10 | Add CSV export for orders, customers, products | Low |
| F4.11 | Add outgoing webhook system (Zapier, Slack, custom endpoints) | Low |
| F4.12 | Add rate limiting on public endpoints (retrieve_form_data, check_coupon_code) | Medium |
| F4.13 | Add form analytics (view tracking, conversion rate, abandonment) | Low |
| F4.14 | Full i18n — generate .pot file, wrap all hardcoded strings in __() |
Medium |
Success Criteria
- Exchange rates fetched and cached with configurable TTL
- License API actually validates, activates, deactivates licenses against DB
- Stripe payments complete end-to-end with webhook verification
- Stock decrements on successful order, prevents overselling
- Tax calculated per-product or per-order based on settings
- PDF invoices downloadable from order detail page
7. Non-Functional Requirements
| Category | Requirement |
|---|---|
| Security | All AJAX/REST endpoints have nonce checks + capability checks (manage_options for admin) |
| Security | No maybe_serialize() in cookie/session handling |
| Security | All payment webhooks verify signatures |
| Performance | flush_rewrite_rules() only on activation/settings save |
| Performance | dbDelta() runs only on activation or schema version change |
| Performance | Currency/country data cached in static vars or transients |
| Performance | Admin tables use server-side pagination |
| Compatibility | PHP 7.4+ minimum, tested through PHP 8.3 |
| Compatibility | WordPress 6.0+ minimum |
| Code Quality | PSR-4 autoloading via Composer |
| Code Quality | Remove .phpbak files, commented-out code, dead code |
| Build | npm run build produces optimized production bundles |
| Build | .distignore for clean WordPress.org packaging |
8. Architecture Overview
PHP Backend (existing, fixed) React Admin (new)
├── Custom Post Types ├── Form Builder
├── Custom DB Tables ├── Order Management
├── Payment Gateways ├── Product/Coupon Editor
├── Email Notifications ├── Dashboard/Analytics
├── REST API Endpoints ◄──────► ├── Settings Pages
├── Webhook Handlers └── Notification Log
└── Cron Jobs
React Frontend (optional)
SSR Form Renderer (default) ├── Multi-step Navigation
├── [formipay] shortcode ├── Customer Portal
├── Thank-you page └── Gutenberg Block
└── No-JS fallback
End of PRD.