WP eCommerce Core Plugin - Changelog
[9.10.2] - 2026-08-31 — Secured invoice PDFs, one authoritative total, and correct shipping & VAT
A security and money-correctness patch across invoicing, cart, checkout, payments and tax. The headline: from cart to checkout to order to invoice there is now one authoritative total — what a shopper sees is what they are charged.
Fixed
- Security: ERP invoice PDFs are no longer readable by anyone who guesses the address. Invoice PDFs were written to a sequential, public path, so an anonymous visitor could work through the invoice numbers and download every invoice's full customer details (name, address, VAT number, line items), bypassing the staff-only download screen. Invoice files now carry an unguessable name, the invoice folder is blocked at the web server (Apache, LiteSpeed and IIS), and existing invoices are renamed automatically on update so the fix also covers nginx. We strongly recommend updating.
- What you see is what you're charged. Coupons and cart-level promotions now fold into one authoritative cart discount that the cart, checkout, order, payment amount and invoice all read from — closing a class of bugs where the shown total and the charged total could differ. A coupon is no longer double-counted on the order total, and the card payment amount is now calculated on the server, so a browser can never name its own price (a mismatch fails the payment and releases the funds rather than accepting the wrong amount).
- A confirmed card or PayPal payment can now pay only one order. A verified payment reference carried no uniqueness guarantee, so the same confirmed payment could be presented against several orders and mark them all paid. A payment reference is now bound to exactly one order, enforced both by the gateway and by the database, so two simultaneous requests carrying the same reference can never both succeed. Existing stores are checked and de-duplicated automatically on update, with any pre-existing conflicts flagged for review.
- Shipping is always charged for a method that actually serves the delivery address. Nothing previously confirmed that the chosen shipping method served the destination's zone, so an order could be charged €0 or the wrong rate, and changing the address after choosing a method left the stale method in the charge. Shipping is now re-authorised against the delivery address at the point the amount is set and again when the order completes. If nothing serves the address the order is refused before payment; a payment already taken for an unshippable address is automatically refunded or voided, the order failed and the stock restored — never left charged.
- Shipping now reaches the order, and free shipping is genuinely free everywhere. A shipping method chosen after checkout started previously never reached the order (shipping charged €0), and a free-shipping coupon or "free shipping over €X" promotion only zeroed the charge on one of the checkout surfaces — page-builder checkouts still charged for shipping the shopper was promised free. Cart, order and payment now all agree on every checkout surface, and the page-builder checkout's headline total matches what the order charges.
- Shipping is no longer over-charged VAT on a tax-inclusive store. On a prices-include-tax store the shipping VAT was counted twice, so a €5.00 courier was charged €5.97 on every paid-shipping order — and that inflated amount flowed into the payment, the order and the myDATA invoice. Subtotal + shipping + tax now add up to the total on every surface.
- A cart discount is applied before tax, so a coupon delivers its full advertised percentage. The discount was previously applied after tax, so on a tax-inclusive store a "10% off" coupon actually delivered about 8%, a 100% coupon still charged VAT, and the declared VAT figure was wrong. The discount now reduces each line's taxable base before VAT, so "X% off" is a real X% off the quoted price on both tax models, and the VAT is declared correctly. Product-scoped coupons still discount only their own lines.
- Invoice figures now match the order. On a tax-inclusive store, creating an invoice from an order treated each line's gross price as net and added VAT again — a €124 order produced a €153.76 invoice, which was transmitted to myDATA and posted to the ledger. Invoice figures are now derived from the order's own charged numbers, a safety check refuses to transmit any document whose total doesn't match the order to the cent, and orders that carry a discount can be invoiced again.
- The invoice now carries a Shipping line, built from the order's own sale-time figures, so an order with shipping no longer produces a document whose total is short by the shipping charge. A free or discounted-shipping order also records what the store actually paid the courier, so courier vouchers and the shipments/margin view show real spend instead of €0.
- A plain admin order Save no longer corrupts the order total. Saving an order's status, notes or address used to re-run the total calculation and inflate a tax-inclusive order's grand total (a €129 order became €153).
- A product variant on sale is charged the sale price it shows. A variant displayed at €80 was previously added to the cart and charged at €100, and that wrong amount flowed to the order and invoice.
- The cart charges the current catalogue price. ⚠ Behaviour change. A cart persists for seven days, and each line's price used to be frozen at the moment it was added — so if you changed a price, or a sale started or ended, an existing cart kept charging the old price while the product page showed the new one. The cart now re-resolves each line from the live product on every recalculation, so a shopper always pays what your store currently lists and every discount rule composes onto the current price. For merchants: a shopper who added an item during a sale and returns after it ends now sees and pays the current price. A deleted product, or one with a missing price, keeps its last-known price — never €0.
- Stripe and PayPal payment webhooks now resolve the order correctly — payment-succeeded, refunded and dispute webhooks were silently ignored. Also fixed: a Stripe manual-capture path that could fail with an error, and a stock double-restore on the cancel → re-open → cancel cycle.
- Creating an invoice from an order no longer fails with a server error, and the ERP invoice endpoints now return a clear logged error instead of a blank white screen if something unexpected happens.
- Your store country is read consistently everywhere — guest checkout, the Eurobank gateway, marketplace orders and courier defaults now all normalise the Greek
ELVAT prefix to the standardGRcountry code, so a store configured either way behaves identically. - Storefront pages are faster — shipping zones and methods are now read once per request instead of on every cart calculation, and the cart's tax and category lookups are batched (roughly 30–50 fewer database queries per cart calculation on a 10-line cart), with no change to any charged or displayed amount.
- Guest checkout hardening. Tax-exemption and sale-time tax figures can no longer be set from a public request, an order-ownership check now compares the right identifiers, and a tax-exempt checkout is re-verified at completion rather than trusting a stored snapshot.
[9.10.1] - 2026-08-03 — Payment security, currency handling & checkout fixes
A security and correctness patch across payments, checkout and invoicing.
Fixed
- Payment gateway security hardening. A full security pass across the bank/PSP gateways closed a critical case where a payment return could mark an unrelated order as paid, added a shared check that the captured amount matches the order total before any order is marked paid, and fixed several smaller issues (an underpayment accepted as paid, a forgeable callback when a secret was left blank, an authorization-only response treated as paid).
- Payment amounts are now converted using each currency's real decimal count — previously every non-Stripe gateway assumed two decimals, so a zero- or three-decimal currency would have been mis-charged. No change for the euro/dollar-style currencies stores use today.
- Payment credentials are protected in the admin — a saved secret can no longer be accidentally overwritten by its masked preview, and each gateway shows only the fields for the selected test/live mode.
- Checkout now remembers the address (and name) you enter, so a returning shopper isn't asked to retype it — while a guest can no longer overwrite an existing customer's saved address by knowing their email.
- Viva Wallet: the correct currency is now charged, the post-payment return reliably completes the order, and webhooks can be registered (with the Return/Redirect URL shown in the admin).
- PayPal checkout now creates the order correctly and verifies the captured amount before marking it paid.
- Invoices created from an order now use the order's real VAT rate (instead of snapping to a Greek bracket), with the Aegean-island 17% rate reported correctly to myDATA; VAT numbers entered with an
ELprefix are now accepted automatically. - The admin now formats prices with your store's currency position and separators, matching the storefront.
[9.10.0] - 2026-07-27 — Per-product tax status, Linked Products, and migration & self-update fixes
Added
- Per-product Tax Status (Taxable / None) — now on variable products too. Set a product to None to sell it untaxed (gift cards, deposits, exempt supplies); the Tax Class dropdown now appears for variable products as well. A "None" product is correctly untaxed in the cart and bills to myDATA in the right exempt VAT category.
- A "Linked Products" tab in the product editor for assigning upsells, cross-sells and related products (matching WooCommerce's placement) — this powers the storefront recommendation rails.
- Back-in-stock alert controls in the product editor — an Enabled / Disabled / Use-store-default choice per product (works with the theme's Stock Alerts module).
Updated
- Migrated product reviews can now keep their original review date.
Fixed
- Product saves no longer corrupt internal fields (cost source, stock status) — a regression from the new Tax Status field. A clean re-import on this build restores correct values.
- The admin Settings screen no longer freezes ("no tab opens") right after a plugin update or when another plugin shows an admin notice.
- Variable products with a disabled variation no longer crash their storefront page.
- Migrated WooCommerce products and orders now keep their original dates instead of being re-dated to the moment of migration.
- Hardened database schema updates so future schema changes reliably apply.
[9.9.0] - 2026-07-14 — Per-product SEO editor, myDATA key encryption, category UX & ERP polish
Added
- Product SEO editor. The product editor's SEO tab is now a full editor: Search Appearance (SEO title + meta description with character counters and a live Google preview), Social (Open Graph title/description + a share image with a live social-card preview), an Advanced section (canonical URL + a search-engine visibility / robots setting, e.g. "No index" for a discontinued product), and a completeness checklist. Every field is optional — leave it blank and the product falls back to your global SEO templates. The tab shows its editable fields only when the theme's SEO module is active. (Pairs with the theme's per-product SEO overrides.)
Updated
- Safe admin tools can now be unlocked with your Flavor licence. The Maintenance and Product Seeder utilities can now be enabled remotely by FlavorTeam support via your licence, instead of only by editing a file on your server. The destructive Danger Zone (delete all products/orders) and Force Repair stay strictly off unless explicitly enabled on the server.
Fixed
- The myDATA subscription key is now encrypted at rest. Your myDATA (AADE) Subscription Key — a sensitive government-API credential — was stored in plain text; it is now encrypted at rest, with an automatic one-time migration of any existing key. The Settings screen still shows it masked, and saving or testing the connection is unchanged.
- New hierarchical category picker. Choosing a category — as a product's Parent Category or in the Products list filter — now uses a shared tree picker that opens collapsed to your top-level categories, expands only the branch you need, and lets you type to search (each result shows its full path, e.g.
Equipment › Cases › Spare Parts, so duplicate names are unambiguous). Replaces the old long, flat dropdown. - Category URLs stay clean. Category pages now stay on the tidy
/shop/category/{slug}/address instead of bouncing to a query-string URL — matching the storefront sidebar and keeping links clean for visitors, bookmarks and SEO. - Your review settings are now enforced on the server. The review rules you set — verified-purchaser only, required title/content, and the moderation policy — are now applied on the server too, so a review submitted directly to the API can no longer bypass what you configured.
- A self-update no longer removes your installed gateways, couriers or ERP add-ons. On the slim update package a plugin self-update could strip your on-demand components (for a payment gateway or courier, that means a broken checkout until they re-download). The plugin now backs them up before the update and restores them right after — and a security review of this work closed a tampered-backup path-traversal window, bringing the plugin to full parity with the theme's preservation fixes.
- ERP and HR polish. A pure self-service employee now lands straight on their own My HR area (no company-wide Dashboard or Marketplace); the ERP sidebar gained a Log out link for everyone and hides the WP Admin link from staff without backend access; Marketplace management is now limited to the roles that use it; the myDATA "Auto-transmit on issue" toggle is now honestly marked "Coming soon"; and a duplicate leave-request cancel path was cleaned up.
- Faster product saves — the admin product editor no longer repeats the same table-structure lookup seven times per save.
- Internal security and stability hardening — admin license locks now fail closed on an unknown feature (matching the server-side gate), plus a developer-facing encrypted-option helper was completed.
[9.8.0] - 2026-06-23 — HR module, ΕΡΓΑΝΗ foundation & full ERP user lifecycle
Added
- New HR module (Business tier). Employee directory, departments, a leave-approval workflow (request → manager approve/reject, with email notifications + per-employee leave balances) and time entries. An HR dashboard shows headcount, who's out today and pending approvals. A new Employee Self-Service ("My HR") area lets staff with a linked account see only their own profile, leave balance, requests and time entries. Time tracking is built ready for the upcoming ΕΡΓΑΝΗ Digital Work Card.
- One-click employee self-service accounts — create and link a self-service login straight from the Employee form; the new account gets the standard set-your-password email.
- Full ERP user lifecycle — Deactivate → Reactivate → Remove (the person's WordPress account is intentionally kept; the last ERP administrator can't be removed).
- ΕΡΓΑΝΗ integration — connection foundation. A new admin-only ΕΡΓΑΝΗ settings page to enter credentials, employer details and Test/Production mode, then verify with Test Connection. Credentials are encrypted at rest. (Submissions arrive in a later release.)
- myDATA transmission notifications — a success/failure toast when transmitting an invoice, plus a native Windows notification in the Flavor ERP Desktop app when its window isn't focused.
Updated
- New public health endpoint for the Flavor ERP Desktop app's first-connection check (identity + version only).
- Developer/destructive admin Tools are now hidden on customer sites unless explicitly enabled — and refuse to run when hidden. Cache, database sync/optimize and the storefront pages helper stay available.
- Clearer database-repair guidance when tables are missing — now points to the visible Sync Database action.
Fixed
- Employees can pick a leave type when requesting leave from self-service (the dropdown was empty for them).
- ΕΡΓΑΝΗ connection — login type is now selectable and the connection-test request matches the official ΕΡΓΑΝΗ guide, resolving a persistent "credentials not correct" error.
- ERP "Assigned To" / "Linked Account" dropdowns no longer come up empty.
[9.7.0] - 2026-06-15 — ERP Role-Based Access Control & faster ERP
Added
- ERP Role-Based Access Control. Each ERP user's role now genuinely controls what they can see and do: Manager, Accountant, Warehouse, Sales, and read-only Viewer each get exactly their own modules; configuration, users and tax (myDATA) stay administrator-only. Site administrators always keep full access.
Updated
- Faster ERP screens for non-administrator roles — removed repeated database lookups that ran on every ERP page load.
Fixed
- The eCommerce admin menu no longer errors on a site without an active license — it shows a clean prompt to activate instead.
- Restore points are now captured before component updates (enabling one-click rollback — see Flavor Core), plus internal cleanup.
[9.6.0] - 2026-06-08 — In-place ERP roles, branded ERP login & a responsive Product editor
Added
- Change an ERP user's role in place. In the ERP app (Settings → Users) you can now pick a new role straight from the users table — no more deactivating and recreating a user to fix a role.
- Standalone, branded ERP login page. An optional clean, Flavor-branded sign-in page for the ERP at
/erp/login(Settings → Login Portal) with your own logo and accent color. Security is unchanged — it still uses WordPress sign-in under the hood, so two-factor, brute-force protection and "forgot password" all keep working.
Updated
- Faster payment-return and barcode lookups on large stores. Order lookups during card-payment returns and product-by-barcode scans now use database indexes instead of scanning every row.
- ERP reliability & performance hardening. Lower memory use when backfilling inventory, much faster warehouse deactivation/deletion on large catalogs, and stricter validation of ERP settings.
Fixed
- The Add/Edit Product screen is now fully responsive from laptop to phone. The side panel becomes a slide-in "Details" drawer, tabs scroll, and the action buttons move to a thumb-friendly bottom bar. The Brand field was rebuilt with a cleaner look, type-ahead search, and inline "create new brand".
- Variable-product attribute values no longer split apart on smaller screens — each value stays an intact chip.
- ERP-only Cost / Cost Source fields are hidden on stores without ERP, for a cleaner Pricing tab on Starter installs.
- ERP "User Management" page fixed — no longer shows "0 users" or white-screens when adding a user.
- Checkout stock accuracy — closed a rare race where two simultaneous orders for the same product could both pass the stock check and oversell.
- Prices are returned cleanly (e.g.
24.44instead of long trailing decimals). - Security: a payment-return token check (NBG) is now constant-time.