26.7.3
·
164 commits
to main
since this release
Immutable
release. Only release title and notes can be modified.
Maho 26.7.3 is a maintenance release for the 26.7 line: fixes backported from main, plus one larger backport that completes the REST/GraphQL API surface.
Creating Maho is a massive effort that requires all the help possible, please join our sponsorship program.
It will make all the difference in the world!

Maho rocks! 🚀
https://mahocommerce.com
https://demo.mahocommerce.com
🐛 Fixes
- Fixed composite SKU in Purchase events and tax-exclusive prices in Meta Pixel and GA4 tracking: purchase events sent the order item's composite SKU (which never matches Meta Commerce / Google Merchant Center feeds) and monetary values excluded tax; all tracked prices are now tax-inclusive.
- Added missing REST/GraphQL API fields, operations, and store-scoped reads/writes across all resources: an audit against the old M1 SOAP surface restored everything never carried over (special price date ranges, MSRP, full invoice documents with create/capture/void/cancel, group prices, and much more) and gave the API a real multi-store contract, with token store allowlists now enforced at the data layer. Note for multi-store installs: a product PUT without
?store=now updates global values instead of silently writing default-store overrides. - Fixed composite SKU sent in analytics events for products with custom options: quote-based events (view_cart, begin_checkout, add/remove-from-cart) appended custom option suffixes to SKUs; tracking now always sends the raw catalog SKU, resolved to the selected variant for configurables.
- Fixed password hash upgrade on login so admin, customer and API credentials move to bcrypt: every password Maho wrote was salted SHA256 and imported OpenMage bcrypt hashes were downgraded on first login; hashes now upgrade to bcrypt on the next successful login.
- Added encryption health checks and fixed logins crashing on stores still running mcrypt-compat:
./maho health-checknow verifies the encryption key and stored encrypted data (catching the two silent OpenMage-migration failure modes), and stores using the mcrypt compatibility module no longer crash on login after the bcrypt upgrade change. - Fixed the gift card admin ACL resource: restricted admin roles with full gift card permissions were denied access to gift card PDF printing, emailing, and gift card product creation.
- Fixed
GET /api/rest/v2/stores/currenciesreturning 500 once any currency rate is saved: the database returns DECIMAL rates as strings, which the strictly-typed float DTO rejected with a fatal error. - Fixed a media stat failure throwing a TypeError instead of reporting a null size: a file vanishing between upload and stat crashed the CMS media API instead of returning a null size.
- Stopped putting the admin form key in every navigation URL: a form key scraped from an address bar, Referer header, screenshot or access log was enough to forge a POST to any admin action; state-changing GET links now use secure URL generation, form keys are compared in constant time, and credit memo cancel/void gained the token check they never had.
- Fixed cart and product APIs mixing base-currency and quote-currency values in one response: on stores whose display currency differs from the website base currency, item prices, shipping method prices and gift card amounts disagreed with the totals; all non-
base*money fields are now consistently in quote/display currency. - Fixed REST shipment creation never persisting qty_shipped: shipments created via REST or GraphQL never wrote
qty_shipped, so orders could be shipped repeatedly and invoiced orders never reached the complete state.
Full changelog: 26.7.2...26.7.3