Highlights
This release contains breaking changes, so please read the release notes carefully. The breaking changes are all the result of fixing behavior that has not worked as intended until now.
Idempotency in our Workflow Engine
Warning
Breaking change
The idempotent
configuration on workflows no longer retains executions in the database after completion, unless a retention time is specified. Up until now, if the idempotent
flag was set, workflow executions were retained indefinitely, which was never the intention. The intention was to make a workflow idempotent for the duration of its execution, and only longer if the retention time was explicitly configured.
As part of this change, we are enabling the idempotent
flag on all cart workflows to prevent concurrent mutations on cart operations.
Return type of methods in MedusaService
Warning
Breaking change
The return types of update
and create
in MedusaService
have been corrected to properly handle the different shapes of inputs.
The behavior is now as follows:
createT({ ... }): T
createT([{ ... }]): T[]
updateT({ id: "br_1234", name: "Hermes" }): T
updateT([{ id: "br_1234", name: "Hermes" }, { id: "br_4321", name: "Loewe" }]): T[]
updateT({ selector: { country_of_origin: "France" }, data: { language: "French" }}): T[]
Compensating emitEventsStep
Warning
Breaking change
Previously, if the emitEventStep
queued an event and the workflow later failed, the compensating flow would emit that queued event instead of removing it. This caused unexpected behavior during rollback.
With this change, when a workflow is compensated, all queued events emitted in the workflow are cleared. This was the intended behavior from the get-go, but the bug was only discovered recently.
If you want to keep the previous behavior, you can create your own version of the emitEventsStep
without a compensation step.
Manage Shipping Option Types in Admin
Warning
Breaking change
The admin dashboard now supports managing shipping option types, making it easier to categorize options such as Standard and Express.
Key updates:
- Settings: New "Shipping Option Types" page (accessible from "Locations & Shipping")
- Create and update types with label, description, and code
- Shipping option creation flow: Choose a type from a dropdown
- Shipping option update flow: Change a type from a dropdown
This brings shipping option management to the dashboard, aligning it with existing backend support.
The introduction of Shipping Option Types comes with a migration, cleaning up old dummy types from the database. Up until now, we've created dummy types for Shipping Options as part of their creation flow. These types were placeholders, which is why we are now replacing them.
The migration will do the following:
- Delete all Shipping Option Types with code
type-code
from the database - Disassociate these types from Shipping Options
- Create a new Shipping Option Type named "Default" with code
default
- Associate the default type with Shipping Options
This migration will only affect Shipping Options that reference the type-code
type. If you have been using your own types, they will remain as is. On the contrary, if you have been relying on type-code
, this is a breaking change.
Draft Orders
The new Draft Order plugin adds flexible order management directly in Medusa Admin. Store admins can create, edit, and finalize orders through a dedicated UI, while developers gain a new primitive for building custom workflows.
Key features:
- Create and manage draft orders from Medusa Admin
- Support for custom pricing, line items, and shipping methods
- Streamlined handling of B2B and complex sales
The Draft Order plugin is installed by default from version >=2.10.0. It is usable for version >=2.4.0 but requires explicit installation and registration.
Read more in our documentation.
Free shipping Promotions
This release introduces support for free shipping promotions available directly from the admin dashboard. You can apply free shipping to specific Shipping Option Types, e.g., "Standard", but not "Express".
Custom Logger Support
You can now replace the default logger with your own implementation by providing a class that follows the Logger interface.
Example:
// medusa-config.ts
import { MyCustomLogger } from "./custom-logger"
export default defineConfig({
// ...
logger: MyCustomLogger,
})
The logger should implement the Logger interface.
Shipping Option Tax Rates
You can now create tax rates specifically for shipping options within tax regions, similar to product-specific tax rates.
Metadata for Product Tags
The product tag domain now supports metadata, with a UI for creating and managing metadata values.
Features
- feat(dashboard, js-sdk): shipping option type mngmt dashboard by @willbouch in #13208
- feat: view config feature flag by @srindom in #13171
- feat: add settings module by @srindom in #13175
- feat(api): add view configuration API routes by @srindom in #13177
- feat: add column introspection api by @srindom in #13183
- feat(dashboard, core-flows): associate shipping option to type by @willbouch in #13226
- feat(core-flows): Refresh adjustments when editing orders by @olivermrbl in #13189
- feat(dashboard): shipping option tax rate overrides UI by @fPolic in #13260
- feat(dashboard, core-flows, js-sdk, types, medusa): listing order's shipping options by @fPolic in #13242
- feat(dashboard,core,modules): free shipping promotion in dashboard by @willbouch in #13263
- feat(core, event-bus): Compensate emit event step utility by @adrien2p in #13281
- feat(utils): define file config by @carlos-r-l-rodrigues in #13283
- feat: Add Draft Order plugin by @olivermrbl in #13291
- feat(index): $nin and $not operators by @carlos-r-l-rodrigues in #13289
- fix(orchestration): Use the step definition max retries on set step failure by @adrien2p in #13319
- feat: custom logger by @carlos-r-l-rodrigues in #13156
Bugs
- fix(utils): fix promotion case of each allocation not applying its total amount by @riqwan in #13199
- fix(utils): auto generated update method return by @carlos-r-l-rodrigues in #13225
- fix(dashboard): table inclusive date filter by @fPolic in #13053
- fix(dashboard): create product selected inventory item display by @fPolic in #13111
- fix(core-flows, dashboard, types): improve allocation flows on Admin by @fPolic in #12572
- fix(dashboard): zero in float currency inputs by @fPolic in #13267
- fix(dashboard): show fulfilment option on SO edit by @fPolic in #13269
- fix(fulfillment): Geozone constraints builder by @olivermrbl in #13282
- fix(): Cart operation should calculate item prices accounting for quantity by @adrien2p in #13251
- fix(fulfillment): don't cascade shipping option delete to shipping option type by @fPolic in #13280
- fix: Add created_at to workflow execution filtering typings by @sradevski in #13295
- fix(dashboard): handle large resource count in tax rule override edit form by @fPolic in #13297
- fix(medusa): fetching a product without a category with
categories
filed passed by @fPolic in #13020 - fix(core-flows): pass backorder flag when recreating reservations after fulfilment cancelation by @fPolic in #13076
- fix(core-flows): list order shipping options param type by @fPolic in #13316
Documentation
- chore(docs): Generated References (automated) by @github-actions[bot] in #13206
- docs: fix subtotal description in storefront guides by @shahednasser in #13212
- docs: fixes to read-only links + add examples for filtering by relations by @shahednasser in #13218
- docs: add regions supported by Cloud by @shahednasser in #13220
- docs: update create project steps by @shahednasser in #13223
- docs: connect to database updates by @shahednasser in #13224
- docs: fix typos in index modules docs by @tedraykov in #12852
- docs: optimize script to ignore builds by @shahednasser in #13232
- docs: integrate payload guide by @shahednasser in #13162
- docs: migrate UI docs by @shahednasser in #13245
- docs: add missing props to UI components by @shahednasser in #13247
- chore(docs): fix ignore build script by @shahednasser in #13248
- docs: improve file uploads example + add section on overriding body size limit by @shahednasser in #13250
- docs: general fixes to admin tips document by @shahednasser in #13253
- docs: add a section on preview environment URL format by @shahednasser in #13254
- docs: improve examples of selecting fields and relations in the API reference by @shahednasser in #13257
- docs: fixes to payload integration guide by @shahednasser in #13261
- docs: fix examples in Analytics Module docs by @shahednasser in #13259
- docs: fix imports + file names by @shahednasser in #13264
- docs: general fixes to cart and order concept docs by @shahednasser in #13270
- docs: fix comment for shipment.created event by @shahednasser in #13274
- docs: updates to billing and usage guides by @shahednasser in #13222
- docs: fix request example in restaurant marketplace recipe by @shahednasser in #13292
- docs: product builder tutorial by @shahednasser in #13210
- chore: improve ignore build script to ignore branches not starting with docs/ by @shahednasser in #13309
Chores
- chore(docs): Updated API Reference (automated) by @github-actions[bot] in #13207
- chore(docs): Update version in documentation (automated) by @github-actions[bot] in #13204
- chore(types, api): support shipping option type api endpoints by @willbouch in #13191
- chore(docs): Updated UI Reference (automated) by @github-actions[bot] in #13205
- chore(utils): round to zero credit lines by @carlos-r-l-rodrigues in #13200
- chore(locking-redis): default ttl to acquire lock by @carlos-r-l-rodrigues in #13221
- chore(dashboard): migrate location levels table by @fPolic in #12624
- chore(ui): move toast to top right by @fPolic in #13092
- chore(ui): TSDoc updates to UI package by @shahednasser in #13246
- chore(medusa): fetch shipping related attributes by @willbouch in #13244
- chore(pricing): Fix excessive db queries during price sets update by @adrien2p in #13258
- chore: fix TSDocs of shipment.created event by @shahednasser in #13273
- chore(promotion): cleanup old unused promotion codebase by @willbouch in #13294
- chore(core-flows): throw Medusa error for exceptions in the fulfilment flows by @fPolic in #13302
- chore(fulfillment): cleanup old auto-generatred shipping type by @willbouch in #13298
- chore: update TSDocs for new release changes by @shahednasser in #13317
- chore: Revert #13189 by @olivermrbl in #13318
- chore: Enable draft order plugin by default by @olivermrbl in #13314
- chore(core-flows): order payment status fix by @carlos-r-l-rodrigues in #13321
- chore: idempotent cart operations by @carlos-r-l-rodrigues in #13236
- chore(dashboard): move shipping option type page by @willbouch in #13323
Other Changes
- fix(core-flows): fix update tax lines to apply tax rule by product type by @yanchesky in #13202
- docs: how to send notifications to admin dashboard panel by @SteelRazor47 in #13231
- fix: handle missing variants and preserve zero unit_price in prepareLineItems by @almousa1990 in #13179
- Improve German Admin Translations (de.json) by @larsdecker in #13219
- feat(medusa,dashboard): Add metadata UI to product tags domain by @kasperkristensen in #13272
- fix(dashboard): fix translations for polish by @gladius882 in #13266
- fix: Variant / Product Metadata making Product import fail when provided in csv input file by @NicolasGorga in #13304
New Contributors
- @yanchesky made their first contribution in #13202
- @tedraykov made their first contribution in #12852
- @almousa1990 made their first contribution in #13179
- @larsdecker made their first contribution in #13219
- @gladius882 made their first contribution in #13266
- @NicolasGorga made their first contribution in #13304
Full Changelog: v2.9.0...v2.10.0