# 04 — WordPress Integration Audit

**Inspected read-only:**
- POS backend storefront API in `C:\wamp64\www\techpos\backend`
- NH WordPress plugin in `C:\wamp64\www\nh\wp-content\plugins\vmwebs-commerce`

Nothing in the NH plugin or the NH WordPress install was modified or executed.

---

## 1. Key finding: the local plugin is not the POS connector

The `vmwebs-commerce` plugin found on disk is a **standalone e-commerce plugin**:

- Version **0.3.0**, git history "Phase 0 → Phase 2 (cart)".
- It has its own `vmwc_product` post type, `vmwc_*` tables, a cart and a REST cart API under `vmwc/v1`.
- It makes **no outbound HTTP calls**, has no POS URL or token settings, and its docs state "Out of scope for V1: inventory management, POS integration" (`docs/ARCHITECTURE.md:330`, `README.md:30`).

But the POS database shows a real connector in use:

- Audit-log entries with user agent **`VMWebs-Commerce/0.4.0`** creating customers and orders.
- Storefront connections for `http://localhost/NHweb` and `nhdream.ca`.

**That v0.4.0 connector build does not exist on this machine.** There is no `NHweb` directory under `C:\wamp64\www`. Its source must be supplied before the WordPress side can be audited.

**Status:** WordPress connector is **Not Verified (source missing)**.

## 2. Plugin v0.3.0 summary (local, NH)

| Aspect | Finding |
|---|---|
| Main file | `vmwebs-commerce.php` (PHP 8.1+, WP 6.5+); kernel `src/Plugin.php`, container `src/Container.php` |
| Modules | `src/{Admin,Catalog,Cart,Storefront,Database,Install,Logging,Security,Settings,Support}` |
| Settings | Single option `vmwc_settings` (general, orders, tax, emails, advanced, cart, catalog) |
| Secrets | libsodium encryption via `VMWC_ENCRYPTION_KEY` or derived from `wp_salt` (`src/Support/Encryption.php`). Reusable for storing a POS token |
| Catalogue | Local CPT/taxonomy and tables (`src/Database/Migrations/M0002CreateCatalogTables.php`). **Not** WooCommerce |
| Front end | Shortcodes `[vmwc_products] [vmwc_categories] [vmwc_product] [vmwc_cart] [vmwc_mini_cart]`, 5 blocks, classic templates |
| Cart | HMAC cookie guest cart, `vmwc/v1/cart*` routes, rate limiting |
| Checkout / orders / payments | **Not built** (`vmwc_checkout_url` placeholder filter) |
| Images | WP Media Library only |
| Cron | `vmwc_daily_maintenance` (cleanup) |
| Stock | None |
| NH-specific values in code | None. Docs mention NH (`wpnh_` prefix, Ontario HST). `tests/wp-tests-config.php` has default test DB credentials |

## 3. POS storefront API (backend), status: Working

**Auth:**
- Header `Authorization: Bearer {uuid}.{secret}`, guard `storefront-connection` (`config/auth.php:70`, `app/Providers/StorefrontServiceProvider.php`).
- Only a bcrypt hash and `last_four` are stored (`app/Storefront/StorefrontConnectionTokenIssuer.php`).
- Rotation revokes all tokens immediately, with no grace period.
- Tokens have `expires_at=null`.
- Tenant and location come only from the connection (`ResolveStorefrontConnectionContext`, `reject.tenant_id`).

**Admin routes** (`routes/api.php:281–295`, tenant users): connections CRUD, enable/disable, catalogue assignment and default, credentials issue/rotate/revoke.

**Connection routes** (`routes/api.php:1256–1308`):

| Endpoint | Purpose |
|---|---|
| `GET storefront/me` | Connection identity |
| `GET storefront/catalogues[/{c}]` | Catalogues |
| `GET storefront/catalogues/{c}/categories` | Categories |
| `GET storefront/catalogues/{c}/products[/{p}]` | Products. Online names and prices, sale price and end date, variants, `availability{stock_status,purchasable}`, featured image and gallery |
| `POST storefront/checkout/quote`, `GET …/quotes/{q}` | Server-authoritative quote (price, tax, shipping, stock check, 900 s TTL) |
| `POST storefront/checkout/orders` | Quote becomes order (DRAFT, ONLINE_PICKUP/ONLINE_DELIVERY); customer find-or-create; idempotent |
| `GET storefront/checkout/orders/{o}/status` | Status |
| `POST storefront/checkout/payment-options`, `/payments`, `/payments/confirm` | Hosted tokenization (Bambora Custom Checkout / Moneris HT), then authorize, then capture and finalize (`app/Payments/OrderFinalizationCoordinator.php`) |
| `POST storefront/payments/webhook/{provider}` | WordPress relays the gateway webhook |
| Public `pay-links/{token}`, `track-links/{token}` | Payment and tracking pages |

**Tests:** `tests/Feature/Storefront` (Connection 13, Catalogue 14, CataloguePerformance 3, Checkout 15, Payment 19, Bambora 6, MultiGateway 5) and `tests/Feature/Checkout/CheckoutQuoteApiTest.php` (7). Present but not executed in this copy.

## 4. Synchronization matrix

| Data | Direction | Mechanism | Status |
|---|---|---|---|
| Products and categories | WordPress pulls | Catalogue endpoints, UUID as sync key | POS **Working**; WordPress side **Missing locally** |
| Images | WordPress pulls | **30-minute signed URLs** (`CatalogueImageService.php:266`) | POS Working. WordPress must download them, not hotlink |
| Prices / sale prices | Pull + quote | Product payload; quote is authoritative | Working |
| Stock / availability | Pull (status only) | `stock_status`/`purchasable`; checked at quote; deducted at payment capture | **Partial**: no quantities, no reservation, pre-capture check is a stub |
| Orders | WordPress → POS | quote → order → pay → finalize | Working (POS) |
| Customers | WordPress → POS inside orders | find-or-create by email or phone | Partial (no account API) |
| Payments | WordPress → POS, plus webhook relay | Hosted fields → initiate → confirm | Working; reconciliation not scheduled |
| Order status / tracking | WordPress pulls | Status endpoint, track links | Working |
| Any POS → WordPress push | — | No outbound HTTP to WordPress anywhere (`Http::` used only for gateways) | **Missing** |
| Delta sync (`updated_since`, ETag) | — | — | **Missing** |
| WooCommerce compatibility | — | No WooCommerce mapping (`external_product_mappings` unused by storefront) | **Missing** |

## 5. Security and isolation notes

- The `techpos` database still holds **6 NH storefront connections with valid token hashes**. Revoke them or start from a clean DB before running the TechTitans API on a host that NH WordPress can reach.
- `backend/docs/security/WORDPRESS_PRODUCTION_INVESTIGATION.md` documents a suspected malicious plugin (`lucid-relay-jet`) on NH's **production** WordPress.
  - It is not present in the local `nh` install.
  - TechTitans must **not** reuse any NH production WordPress files, database or credentials.
  - Build TechTitans' site from clean sources.
- Tokens never expire, and rotation has no grace period. Consider an overlap window and expiry for TechTitans.

## 6. Gaps for TechTitans online selling

1. **Connector source.** Obtain the v0.4.0 connector (or decide to build a TechTitans connector, possibly WooCommerce-based) before any WordPress work.
2. **Stock accuracy for high-value items:**
   - add reservations at checkout (quote or order holds);
   - implement `stockAvailable()`;
   - expose a quantity or "only N left" per policy;
   - require integer quantities for serialized goods (today the quote accepts decimals: `StorefrontCheckoutQuoteRequest.php:35`).
3. **Condition and serialized listings.** Used and refurbished devices sold online need per-condition variants or unit-level listings with photos.
4. **Push sync.** Add an outbox plus a signed outbound webhook for stock, price and product changes, plus `updated_since` delta pulls.
5. **Image sync.** WordPress-side download into the Media Library, keyed by media UUID.
6. **Ops.** Schedule `payments:reconcile`.
