v2.4.0: Stripe & Magento 2 Connectors + seller regions
Mercur v2.4.0 connects to more of the outside world.
- Payouts move to a thin core module + new Stripe Connector.
- New Magento 2 Connector lets an external storefront sell marketplace offers.
- Operators can assign sellers to regions.
- The panels get a layout composer and deeper extension points.
- Checkout and vendor lists get a performance pass.
Medusa was bumped to version 2.22.0, which requires Node 22.22+. This release has breaking changes, so please read What's Changed before you upgrade.
What's New
Stripe Connector
Core payouts are now shaped like Medusa's payment module: one provider per marketplace, one payout per seller order, and one payout_reversal per later refund. An order that isn't ready goes on_hold and is re-decided on the next run.
Core still schedules nothing. @mercurjs/stripe-connector-plugin brings the operations: seven scheduled jobs, settlements that net payouts, reversals and adjustments per seller and currency, operator adjustments, capture validation and failed-operation alerts.
Operators get Integrations → Stripe and Settings → Stripe, plus widgets on the seller and order pages. Vendors get their own Stripe page. If you use @mercurjs/payout-stripe-connect today, see What's Changed for the migration.
Magento 2 Connector
@mercurjs/magento2-connector-plugin lets a Magento 2 storefront sell marketplace offers while Mercur keeps sellers, split orders, commissions, and payouts. It ships HMAC-signed webhooks with retries and redelivery, and an external payment provider that authorizes at checkout and captures when Magento invoices the order.
Storefront refunds are mirrored onto the Mercur order, and there's an admin screen at /settings/magento. The Magento side is the separate mercurjs/magento2-connector Composer package.
Read the Magento 2 Connector announcement to explore more.
Regions
Operators decide which regions a seller operates in from the region page, the seller page, or Create Seller. Vendors see and price only in their assigned regions, and the offer grids get one column per region.
Admin keeps full visibility of prices across all regions. New sellers get the store's default region, and existing sellers have no regions until you assign them.
Layout composer
Admin product detail and vendor offer detail now render through a LayoutComposer that uses Medusa's entry IDs. Plugins, the Medusa project, and the host app are ordered layers where later wins, and any layer can contribute routes, widgets, layouts/, _layouts.ts and _navigation.ts.
Custom-fields configs can also hide, replace, or add columns and fields on embedded tables, spreadsheet grids, and built-in form fields, using the existing list and forms keys.
Vendor onboarding
Each onboarding step is now a tab of the seller onboarding form zone, so you can add, remove, reorder, or mark steps optional from a custom-fields config. The store handle is now required, with a live check against the new GET /vendor/sellers/handle-availability.
Going back after a failed Finish no longer wipes what the user typed.
Offer conditions
Operators manage conditions under Settings → Offer Conditions, and vendors pick one when creating or editing an offer.
Lead time defaults
Lead time gets its UI and a marketplace-wide default, set in Settings → Marketplace, on the store, and on the offer. GET /store/offers returns effective_leadtime_to_ship, resolved from offer to store to marketplace.
Telemetry
Mercur now sends anonymous telemetry from your server. It's on by default and prints nothing at boot, and it helps us see how many installations exist, which versions they run, and whether they keep running.
The server sends a startup event and a daily heartbeat with a random installation ID, versions, runtime, OS and infrastructure details, feature flags, and one-time milestones such as the first approved seller or first paid payout. Marketplace counts are sent as range buckets, never exact numbers. Only first-party plugins are named, custom ones are just counted, and each event says whether the install was seeded with demo data.
Every CLI command now reports its name, flag names, exit code, and duration, with flag values redacted unless they're a boolean or a fixed choice. The CLI stops sending blocks.json contents, aliasPrefix, CPU model and email, and the email prompt is gone.
Opt out with MERCUR_DISABLE_TELEMETRY, DO_NOT_TRACK or withMercur({ projectConfig: { mercur: { telemetry: false } } }). Telemetry is also off in CI, under NODE_ENV=test and in worker processes. Set MERCUR_TELEMETRY_DEBUG=true to print payloads instead of sending them.
Every event and property is listed on the telemetry docs page.
Storefront
- Added a cart drawer that opens instantly, optimistic cart edits, and a quantity picker on the product page, so pages no longer wait on the cart.
- Made
POST /store/carts/:id/completereturn the seller orders.
Core
- Added an
offerPricesUpsertedhook, plus previous values, snapshots, andupdated_byon the other offer hooks. - Added
getStatisticson the seller and offer modules, withGET /admin/sellers/statisticsandGET /admin/offers/statistics. - Added a
deleted_atfilter andwith_deletedon admin offers and sellers, so a delta sync can see removals. - Added
order_group.metadata, copied fromcart.metadata. - Added
is_replayon thepaymentRefundedhook.
What's Changed
Admin & Vendor Panel
- Made sellers region-scoped (breaking) –
GET /vendor/regionsnow returns assigned regions only,GET /vendor/regions/:idreturns 404 for the others, and a vendor offer or shipping price on an unassigned region returns 400. Set a default region under Settings → Store for new sellers, then link existing ones from the seller page or withPOST /admin/sellers/:id/regionsand{ "add": ["reg_…"] }. - Changed the seller lead time default (breaking) – new sellers no longer default to a lead time of 2. They start at
nulland use the marketplace default from Settings → Marketplace. Existing sellers keep their current value, including 2, and clearing a store's lead time moves it to the marketplace default. If you ran the migration on a v2.3.9 canary, it cleared values of 2, so those sellers need them set again. - Scoped
GET /vendor/paymentsthrough the order's payment collection (breaking), so shared, uncaptured cart-stage payments are not listed. - Pushed vendor list seller scoping into SQL
EXISTSsubqueries instead ofid INlists that grow with lifetime volume.
Storefront
- Moved the storefront to Next 16 with Cache Components (breaking) – every route has a prerendered shell, the default first page of a listing sits in the HTML, and catalog reads are cached. Catalog prices are fetched anonymously, so customer-group price lists no longer show on catalog pages (the cart still applies them), and canonical and structured-data URLs now come from
NEXT_PUBLIC_BASE_URL. - Removed
orders.items.variant.productfrom store order groups (breaking) – asking for it explicitly returns 400. Useorders.items.product_handleandorders.items.product_title.
Core
- Bumped Medusa to 2.22.0 (breaking) – it drops Node 20 and requires Node 22.22+. To pick up the October 2026 Node.js security releases, we recommend Node 24.22.1+, or 22.23.4+ if you stay on Node 22.
- Removed
@mercurjs/payout-stripe-connect(breaking) – install@mercurjs/stripe-connector-pluginand point the payout module at@mercurjs/stripe-connector-plugin/providers/payout-stripe-connect. If you also adopt the plugin's payment provider, addpp_stripe-connector_<id>to your regions. - Changed the payout module API (breaking) –
createPayoutWorkflowis replaced bycreateOrderPayoutsWorkflow. OnIPayoutProvider,createPayoutAccountbecomescreateAccount, andretrieveAccountandreversePayoutare now required.PayoutStatus.CANCELEDbecomesABORTED, and existing rows are migrated. - Made offers honour the product–seller allowlist (breaking) –
createOffersWorkflownow refuses a product restricted to other sellers or rejected by the operator. Products with no link stay open to every seller. - Restructured the payout tables, added the
region_sellerlink,order_group.metadata, a telemetry table and list indexes, and madeseller.default_leadtime_to_shipnullable – run migrations before upgrading. - Loaded the commission rate table once per checkout, and added list indexes on order groups, offers, payouts, reviews and commission rules.
What's Fixed
Admin & Vendor Panel
- Refetched admin and vendor product lists on search, filter, and sort.
- Kept the date filter popover open while typing a custom date.
- Loaded plugin extensions in the panels' ESM build, which silently started without them.
- Fixed the 500 on
GET /admin/products?sku=. - Stopped Edit prices on a vendor offer from wiping every price when saved before regions loaded.
- Added status, bank payout, and period end filters to vendor Stripe settlements.
Storefront
- Confirmed offer stock against the cart's total demand per inventory item, so buyers learn at add-to-cart rather than at checkout.
- Subtracted reserved stock from availability on
GET /store/offers. - Returned
items.offeranditems.offer.selleron store cart routes, so carts group by the right seller. - Stopped
GET /store/order-groupsreturning 400 withoutfields, which crashed the storefront's order page. - Ignored an empty
currency_codeonPOST /store/carts.
Core
- Allocated cart credit lines across split orders, so the credit-covered part no longer shows as owed. Fully credit-covered orders still stay on hold for payout.
- Compensated commission lines, payment captures, and links when checkout is canceled after completion, so no marketplace records stay behind.
- Fixed checkout lock units: timeouts passed in milliseconds meant a lock wait of about 8 hours and a TTL of about 33. Concurrent completion under
processPaymentWorkflowis now locked too. - Fixed in-place updates of quantity-tiered offer prices never completing.
- Emitted
product.publishedwhen an admin publishes a product.
Other
- Set the store default region in the seed, so seeded installs can create priced sellers.
- Cleared peer-dependency warnings on fresh installs by aligning tiptap and pinning
@opentelemetry/api. - Rewrote the architecture page and the platform module docs, with new figures.
- Split use cases into standalone marketplace and marketplace inside a store.
- Split the Magento 2 integration into focused pages and added a demo video.
- Pointed legacy redirects to existing pages.
More product updates
Ready to build?
Read the release notes, then see the product – open the demo, or book a walkthrough on your terms.


