Mercur

v2.3.7: Offer conditions, order list filters & security fixes

Oct 8, 2026

Mercur v2.3.7 is a smaller release with one new building block and a batch of fixes.

Offers learn about conditions, so operators can define "new", "refurbished," or "used," and sellers pick one per listing.

The admin order list gets a payment status filter, server-side search in its filters, and smarter search by order number.

Two security fixes close cross-seller gaps in the vendor API and in cart promotions, and payouts no longer call the provider before a row is written.

What's New

Offer conditions

Operators define the physical conditions an offer may be listed under through /admin/offer-conditions (code, label, is_active, rank), and sellers pick an active one via condition_id when creating or updating an offer. Admin, vendor, and store offer responses expose condition.{id,code,label} and filter on condition_id. Deleting a condition in use is refused; deactivating keeps existing offers but blocks new assignments. API only for now, with createOfferConditionsWorkflow /update/delete hooks and offer_condition.* events.

Admin

  • Filter order groups by payment status. The status is computed from payment collections, so GET /admin/order-groups?payment_status=captured matches exactly what the list shows.
  • Search by the numbers operators actually see: 264, #264 or #G258 now match the group's display ID or any child order's display ID.
  • Customer, Store, and Sales channel filters search on the server, so stores with more than 1000 customers or sellers can select any of them.

Security

Cross-seller access in the vendor API

Several vendor API routes let one seller reach another seller's data: fields traversal into other sellers' members, payment details and invite tokens; product detail routes on another seller's drafts; capture of shared cart payments; and offer and inventory body IDs pointing at another seller's items or locations. All of these cross-seller authorization gaps are now closed.

Cart promotions leaking across sellers

Seller promotions are now scoped to the seller's own items on every cart refresh, not only when applied through POST /store/carts/:id/promotions. A vendor promotion without seller-specific target rules, or an automatic one, no longer discounts other sellers' items. If your storefront relied on that, it was a bug.

What's Changed

Core

  • Made payouts briefly pending (breaking) – createPayouts now inserts the row before calling the provider, so payout.created fires for a pending row. Readers that assumed every row is already sent should check status.
  • Added an offer_condition table and offer.condition_id (seeded with a default new condition), and widened the payout status check constraint to accept processing – run migrations before upgrading.

What's Fixed

Admin & Vendor Panel

  • Rebuilt the Variants table on every attribute change in Products → Create.
  • Surfaced product creation errors as a toast instead of a silent 400.
  • Intersected id and seller_id filters on GET /admin/order-groups instead of returning every group.

Core

  • Inserted the payout row before calling the provider, used the payout id as the default idempotency_key, and accepted the processing status in the database.

More product updates

Ready to build?

Read the release notes, then see the product – open the demo, or book a walkthrough on your terms.