v2.10.0

medusajs/medusav2.10.0Aug 28, 2025by olivermrbl

AI Summary

Introduces Draft Orders, Free shipping promotions, and Shipping Option Types. Includes breaking changes related to workflow idempotency and service return types.

Key Highlights

  • Draft Orders plugin
  • Free shipping promotions
  • Shipping Option Types management
  • Custom Logger support
  • Shipping Option Tax Rates

Breaking Changes

  • Idempotency configuration retention behavior changed
  • MedusaService create/update return types corrected
  • emitEventsStep compensation behavior changed
  • Shipping Option Types migration (dummy types removed)

New Features

  • Shipping option type management dashboard
  • View configuration feature flag
  • Settings module
  • View configuration API routes
  • Column introspection API
  • Free shipping promotion in dashboard

Full Release Notes

<!-- 
![2-10-0](https://gh-release-images.s3.eu-north-1.amazonaws.com/v2-10-0.png)

# v2.10.0: Draft Orders, Free shipping promotion, and Shipping Option Types

This release introduces Draft Orders, Free shipping promotions, and Shipping Option Types.

CMS_BREAK -->

## 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:
```ts
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:
```ts
// medusa-config.ts
import { MyCustomLogger } from "./custom-logger"

export default defineConfig({
  // ...
  logger: MyCustomLogger,
})
```

The logger should implement the [Logger interface](https://github.com/medusajs/medusa/blob/a1949a3c4d079e04233d80edd09f56248d711f41/packages/core/types/src/logger/index.ts#L1-L18).

### 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 https://github.com/medusajs/medusa/pull/13208
* feat: view config feature flag by @srindom in https://github.com/medusajs/medusa/pull/13171
* feat: add settings module by @srindom in https://github.com/medusajs/medusa/pull/13175
* feat(api): add view configuration API routes by @srindom in https://github.com/medusajs/medusa/pull/13177
* feat: add column introspection api by @srindom in https://github.com/medusajs/medusa/pull/13183
* feat(dashboard, core-flows): associate shipping option to type by @willbouch in https://github.com/medusajs/medusa/pull/13226
* feat(core-flows): Refresh adjustments when editing orders by @olivermrbl in https://github.com/medusajs/medusa/pull/13189
* feat(dashboard): shipping option tax rate overrides UI by @fPolic in https://github.com/medusajs/medusa/pull/13260
* feat(dashboard, core-flows, js-sdk, types, medusa): listing order's shipping options by @fPolic in https://github.com/medusajs/medusa/pull/13242
* feat(dashboard,core,modules): free shipping promotion in dashboard by @willbouch in https://github.com/medusajs/medusa/pull/13263
* feat(core, event-bus): Compensate emit event step utility by @adrien2p in https://github.com/medusajs/medusa/pull/13281
* feat(utils): define file config by @carlos-r-l-rodrigues in https://github.com/medusajs/medusa/pull/13283
* feat: Add Draft Order plugin by @olivermrbl in https://github.com/medusajs/medusa/pull/13291
* feat(index): $nin and $not operators by @carlos-r-l-rodrigues in https://github.com/medusajs/medusa/pull/13289
* fix(orchestration): Use the step definition max retries on set step failure by @adrien2p in https://github.com/medusajs/medusa/pull/13319
* feat: custom logger by @carlos-r-l-rodrigues in https://github.com/medusajs/medusa/pull/13156

## Bugs
* fix(utils): fix promotion case of each allocation not applying its total amount by @riqwan in https://github.com/medusajs/medusa/pull/13199
* fix(utils): auto generated update method return by @carlos-r-l-rodrigues in https://github.com/medusajs/medusa/pull/13225
* fix(dashboard): table inclusive date filter by @fPolic in https://github.com/medusajs/medusa/pull/13053
* fix(dashboard): create product selected inventory item display by @fPolic in https://github.com/medusajs/medusa/pull/13111
* fix(core-flows, dashboard, types): improve allocation flows on Admin by @fPolic in https://github.com/medusajs/medusa/pull/12572
* fix(dashboard): zero in float currency inputs by @fPolic in https://github.com/medusajs/medusa/pull/13267
* fix(dashboard): show fulfilment option on SO edit by @fPolic in https://github.com/medusajs/medusa/pull/13269
* fix(fulfillment): Geozone constraints builder by @olivermrbl in https://github.com/medusajs/medusa/pull/13282
* fix(): Cart operation should calculate item prices accounting for quantity by @adrien2p in https://github.com/medusajs/medusa/pull/13251
* fix(fulfillment): don't cascade shipping option delete to shipping option type by @fPolic in https://github.com/medusajs/medusa/pull/13280
* fix: Add created_at to workflow execution filtering typings by @sradevski in https://github.com/medusajs/medusa/pull/13295
* fix(dashboard): handle large resource count in tax rule override edit form by @fPolic in https://github.com/medusajs/medusa/pull/13297
* fix(medusa): fetching a product without a category with `categories` filed passed by @fPolic in https://github.com/medusajs/medusa/pull/13020
* fix(core-flows): pass backorder flag when recreating reservations after fulfilment cancelation by @fPolic in https://github.com/medusajs/medusa/pull/13076
* fix(core-flows): list order shipping options param type by @fPolic in https://github.com/medusajs/medusa/pull/13316

## Documentation
* chore(docs): Generated References (automated) by @github-actions[bot] in https://github.com/medusajs/medusa/pull/13206
* docs: fix subtotal description in storefront guides by @shahednasser in https://github.com/medusajs/medusa/pull/13212
* docs: fixes to read-only links + add examples for filtering by relations by @shahednasser in https://github.com/medusajs/medusa/pull/13218
* docs: add regions supported by Cloud by @shahednasser in https://github.com/medusajs/medusa/pull/13220
* docs: update create project steps by @shahednasser in https://github.com/medusajs/medusa/pull/13223
* docs: connect to database updates by @shahednasser in https://github.com/medusajs/medusa/pull/13224
* docs: fix typos in index modules docs by @tedraykov in https://github.com/medusajs/medusa/pull/12852
* docs: optimize script to ignore builds by @shahednasser in https://github.com/medusajs/medusa/pull/13232
* docs: integrate payload guide by @shahednasser in https://github.com/medusajs/medusa/pull/13162
* docs: migrate UI docs by @shahednasser in https://github.com/medusajs/medusa/pull/13245
* docs: add missing props to UI components by @shahednasser in https://github.com/medusajs/medusa/pull/13247
* chore(docs): fix ignore build script by @shahednasser in https://github.com/medusajs/medusa/pull/13248
* docs: improve file uploads example + add section on overriding body size limit by @shahednasser in https://github.com/medusajs/medusa/pull/13250
* docs: general fixes to admin tips document by @shahednasser in https://github.com/medusajs/medusa/pull/13253
* docs: add a section on preview environment URL format by @shahednasser in https://github.com/medusajs/medusa/pull/13254
* docs: improve examples of selecting fields and relations in the API reference by @shahednasser in https://github.com/medusajs/medusa/pull/13257
* docs: fixes to payload integration guide by @shahednasser in https://github.com/medusajs/medusa/pull/13261
* docs: fix examples in Analytics Module docs by @shahednasser in https://github.com/medusajs/medusa/pull/13259
* docs: fix imports + file names by @shahednasser in https://github.com/medusajs/medusa/pull/13264
* docs: general fixes to cart and order concept docs by @shahednasser in https://github.com/medusajs/medusa/pull/13270
* docs: fix comment for shipment.created event by @shahednasser in https://github.com/medusajs/medusa/pull/13274
* docs: updates to billing and usage guides by @shahednasser in https://github.com/medusajs/medusa/pull/13222
* docs: fix request example in restaurant marketplace recipe by @shahednasser in https://github.com/medusajs/medusa/pull/13292
* docs: product builder tutorial by @shahednasser in https://github.com/medusajs/medusa/pull/13210
* chore: improve ignore build script to ignore branches not starting with docs/ by @shahednasser in https://github.com/medusajs/medusa/pull/13309

## Chores
* chore(docs): Updated API Reference (automated) by @github-actions[bot] in https://github.com/medusajs/medusa/pull/13207
* chore(docs): Update version in documentation (automated) by @github-actions[bot] in https://github.com/medusajs/medusa/pull/13204
* chore(types, api): support shipping option type api endpoints by @willbouch in https://github.com/medusajs/medusa/pull/13191
* chore(docs): Updated UI Reference (automated) by @github-actions[bot] in https://github.com/medusajs/medusa/pull/13205
* chore(utils): round to zero credit lines by @carlos-r-l-rodrigues in https://github.com/medusajs/medusa/pull/13200
* chore(locking-redis): default ttl to acquire lock by @carlos-r-l-rodrigues in https://github.com/medusajs/medusa/pull/13221
* chore(dashboard): migrate location levels table by @fPolic in https://github.com/medusajs/medusa/pull/12624
* chore(ui): move toast to top right by @fPolic in https://github.com/medusajs/medusa/pull/13092
* chore(ui): TSDoc updates to UI package by @shahednasser in https://github.com/medusajs/medusa/pull/13246
* chore(medusa): fetch shipping related attributes by @willbouch in https://github.com/medusajs/medusa/pull/13244
* chore(pricing): Fix excessive db queries during price sets update by @adrien2p in https://github.com/medusajs/medusa/pull/13258
* chore: fix TSDocs of shipment.created event by @shahednasser in https://github.com/medusajs/medusa/pull/13273
* chore(promotion): cleanup old unused promotion codebase by @willbouch in https://github.com/medusajs/medusa/pull/13294
* chore(core-flows): throw Medusa error for exceptions in the fulfilment flows by @fPolic in https://github.com/medusajs/medusa/pull/13302
* chore(fulfillment): cleanup old auto-generatred shipping type by @willbouch in https://github.com/medusajs/medusa/pull/13298
* chore: update TSDocs for new release changes by @shahednasser in https://github.com/medusajs/medusa/pull/13317
* chore: Revert #13189 by @olivermrbl in https://github.com/medusajs/medusa/pull/13318
* chore: Enable draft order plugin by default by @olivermrbl in https://github.com/medusajs/medusa/pull/13314
* chore(core-flows): order payment status fix by @carlos-r-l-rodrigues in https://github.com/medusajs/medusa/pull/13321
* chore: idempotent cart operations by @carlos-r-l-rodrigues in https://github.com/medusajs/medusa/pull/13236
* chore(dashboard): move shipping option type page by @willbouch in https://github.com/medusajs/medusa/pull/13323
### Other Changes
* fix(core-flows): fix update tax lines to apply tax rule by product type by @yanchesky in https://github.com/medusajs/medusa/pull/13202
* docs: how to send notifications to admin dashboard panel by @SteelRazor47 in https://github.com/medusajs/medusa/pull/13231
* fix: handle missing variants and preserve zero unit_price in prepareLineItems by @almousa1990 in https://github.com/medusajs/medusa/pull/13179
* Improve German Admin Translations (de.json) by @larsdecker in https://github.com/medusajs/medusa/pull/13219
* feat(medusa,dashboard): Add metadata UI to product tags domain by @kasperkristensen in https://github.com/medusajs/medusa/pull/13272
* fix(dashboard): fix translations for polish by @gladius882 in https://github.com/medusajs/medusa/pull/13266
* fix: Variant / Product Metadata making Product import fail when provided in csv input file by @NicolasGorga in https://github.com/medusajs/medusa/pull/13304

## New Contributors
* @yanchesky made their first contribution in https://github.com/medusajs/medusa/pull/13202
* @tedraykov made their first contribution in https://github.com/medusajs/medusa/pull/12852
* @almousa1990 made their first contribution in https://github.com/medusajs/medusa/pull/13179
* @larsdecker made their first contribution in https://github.com/medusajs/medusa/pull/13219
* @gladius882 made their first contribution in https://github.com/medusajs/medusa/pull/13266
* @NicolasGorga made their first contribution in https://github.com/medusajs/medusa/pull/13304

**Full Changelog**: https://github.com/medusajs/medusa/compare/v2.9.0...v2.10.0