diff --git a/PRD.md b/PRD.md new file mode 100644 index 000000000..39d2e1786 --- /dev/null +++ b/PRD.md @@ -0,0 +1,202 @@ +# 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 build` produces 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.* diff --git a/TASKLIST.md b/TASKLIST.md new file mode 100644 index 000000000..63d4d31f4 --- /dev/null +++ b/TASKLIST.md @@ -0,0 +1,179 @@ +# Formipay — Implementation Task List + +**Last Updated:** April 17, 2026 +**Reference:** PRD.md, FINDINGS.md, RECOMMENDATION.md + +--- + +## Phase 1 — Critical Fixes & Stabilization + +### Week 1: Critical Bug Fixes + +- [ ] **F1.1** Fix `Customer::update()` fatal error — define `$table_name` and fix `$new_args` reference + - `includes/Customer.php` ~line 172 +- [ ] **F1.2** Fix `Order::delete()` — change `$id` to `$order_id` in `$wpdb->delete()` where clause + - `includes/Order.php` +- [ ] **F1.3** Fix `Order::formipay_bulk_delete_order()` — use loop variable `$id` instead of outer `$order_id` + - `includes/Order.php` +- [ ] **F1.4** Fix `Email::send_email()` — change `\Formipay_Notification::` to `parent::` + - `includes/Notification/Email.php` +- [ ] **F1.5** Fix `Paypal::auto_cancel_order_on_timeout()` — add `use Formipay\Order as Order` import + - `includes/Integration/Paypal.php` +- [ ] **F1.6** Fix `Paypal::paypal_settings` — declare property or load from config + - `includes/Integration/Paypal.php` +- [ ] **F1.7** Fix `BankTransfer::add_unique_code_details()` — call `check_unique_code()` once, reuse result + - `includes/Payment/BankTransfer.php` +- [ ] **F1.8** Fix color field label "Number" → "Color" + - `admin/functions.php` `formipay_field_type_collection()` +- [ ] **F1.9** Add `check_ajax_referer` nonce check to `Customer::formipay_tabledata_customers()` + - `includes/Customer.php` + +### Week 2: Performance & Security + +- [ ] **F1.10** Replace `maybe_serialize()` in cookie handling with `json_encode()`/`json_decode()` + - `includes/Order.php` `retrieve_form_data()` +- [ ] **F1.11** Move `flush_rewrite_rules()` from `init` to activation hook + - `includes/Thankyou.php` `set_endpoint()` + - `includes/Payment/Payment.php` `set_endpoint()` + - `formipay.php` (add register_activation_hook) +- [ ] **F1.12** Add PayPal webhook signature verification + - `includes/Integration/Paypal.php` `webhook_endpoint()` +- [ ] **F1.13** Cache JSON file reads in static variables + - `admin/functions.php` `formipay_currency_array()` + - `admin/functions.php` `formipay_country_array()` +- [ ] **F1.14** Add server-side pagination to `Customer::formipay_tabledata_customers()` + - `includes/Customer.php` +- [ ] **F1.15** Optimize `Order::formipay_tabledata_orders()` — replace two queries with `COUNT(*) GROUP BY status` + - `includes/Order.php` +- [ ] **F1.16** Delete backup file `includes/Integration/Paypal.phpbak` +- [ ] **F1.17** Create `uninstall.php` — clean up options, custom tables, scheduled events + - `uninstall.php` (new file) +- [ ] **F1.18** Add capability checks (`current_user_can('manage_options')`) to admin-ajax handlers +- [ ] **F1.19** Fix timezone hardcode — replace `'Asia/Jakarta'` with `wp_timezone_string()` + - `includes/Render.php` + +--- + +## Phase 2 — React Admin Foundation + +### Week 3: Build Pipeline + +- [ ] **F2.1** Initialize `package.json` with `@wordpress/scripts` +- [ ] **F2.2** Create `webpack.config.js` extending wp-scripts +- [ ] **F2.3** Set up `src/admin/` directory structure +- [ ] **F2.4** Create API client (`src/admin/api/client.js`) with nonce handling +- [ ] **F2.5** Create admin page shell component (sidebar + routing) +- [ ] **F2.6** Register admin menu pages in PHP that render React mount points + +### Week 4: Form Builder + +- [ ] **F2.7** Build field palette component (drag-and-drop source) +- [ ] **F2.8** Build form canvas component (drop target) +- [ ] **F2.9** Build field settings panel +- [ ] **F2.10** Build live preview renderer +- [ ] **F2.11** Connect to existing PHP save/load endpoints +- [ ] **F2.12** Replace Vue/Classic Editor metabox with React form builder + +### Week 5: Order Management & Dashboard + +- [ ] **F2.13** Build order list page with filters (status, date, search) +- [ ] **F2.14** Build order detail view (replace Handlebars templates) +- [ ] **F2.15** Build status change workflow with timeline +- [ ] **F2.16** Build analytics dashboard (order count, revenue, charts) +- [ ] **F2.17** Build notification log viewer + +### Week 6: Settings & Editors + +- [ ] **F2.18** Build global settings page (replace WPCFTO) +- [ ] **F2.19** Build product editor page +- [ ] **F2.20** Build coupon editor page +- [ ] **F2.21** Build access items manager +- [ ] **F2.22** Build license management page +- [ ] **F2.23** Remove/deprecate Vue admin code + +--- + +## Phase 3 — Frontend Enhancements + +### Week 7-8: React Island Architecture + +- [ ] **F3.1** Add "Render Mode" setting to form admin (SSR / React) +- [ ] **F3.2** Update `Render.php` — output `
` mount point when React mode selected +- [ ] **F3.3** Build React form renderer component (`src/frontend/widgets/FormRenderer.jsx`) +- [ ] **F3.4** Implement island hydration — React attaches to SSR HTML +- [ ] **F3.5** Build multi-step form navigation component +- [ ] **F3.6** Add real-time field validation in React mode + +### Week 9: Gutenberg Block + +- [ ] **F3.7** Create `block.json` for `formipay/form` +- [ ] **F3.8** Build `edit.jsx` — form selector + live preview in editor +- [ ] **F3.9** Build `render.php` — server-side rendering for frontend +- [ ] **F3.10** Register block in PHP +- [ ] **F3.11** Test block in Gutenberg editor + +### Week 10: Customer Portal + +- [ ] **F3.12** Build customer order history page (React) +- [ ] **F3.13** Build order detail / download access page (React) +- [ ] **F3.14** Build access link request form (React) +- [ ] **F3.15** Integrate with WordPress user accounts +- [ ] **F3.16** Register `[formipay_my_orders]` shortcode + +--- + +## Phase 4 — Missing Features + +### Week 11-12: Payment & Commerce + +- [ ] **F4.1** Implement `ExchangeRateAPI` — fetch rates, cache, convert + - `includes/Payment/ExchangeRateAPI.php` +- [ ] **F4.2** Implement License API endpoints (verify, activate, deactivate, revoke) + - `includes/LicenseAPI.php` +- [ ] **F4.3** Add Stripe payment gateway + - `includes/Integration/Stripe.php` (new) +- [ ] **F4.4** Add tax calculation engine + - `includes/Tax.php` (new) +- [ ] **F4.5** Add product variations on frontend (render dropdown, process selection) + - `includes/Render.php`, `includes/Order.php` + +### Week 13-14: Stock & Shipping + +- [ ] **F4.6** Implement stock management — decrement on order, validate before submit + - `includes/Product.php` (new or extend) +- [ ] **F4.7** Add "out of stock" frontend messaging + - `includes/Render.php` +- [ ] **F4.8** Add refund workflow (status change + payment reversal) + - `includes/Order.php`, gateway integrations + +### Week 15-16: Advanced Features + +- [ ] **F4.9** Build donation form mode (pay-what-you-want, suggested amounts) + - `includes/Render.php` +- [ ] **F4.10** Add PDF invoice generation + - `includes/Invoice.php` (new) +- [ ] **F4.11** Add CSV export for orders, customers, products + - Admin pages +- [ ] **F4.12** Add outgoing webhook system + - `includes/Webhook.php` (new) +- [ ] **F4.13** Add rate limiting on public endpoints + - `includes/Order.php`, `includes/Coupon.php` +- [ ] **F4.14** Wrap all hardcoded English strings in `__()` translation functions + - All PHP + JS files +- [ ] **F4.15** Generate `.pot` file for translators +- [ ] **F4.16** Add form analytics (view tracking, conversion rate) + - `includes/Analytics.php` (new) + +--- + +## Definition of Done (per task) + +- [x] Code compiles without errors +- [x] No PHP warnings/notices in debug mode +- [x] Manual test passes for the specific fix/feature +- [x] No regression in existing functionality +- [x] Security-sensitive changes reviewed + +--- + +*End of task list.*