Skip to main content
Mercur is configured through the standard Medusa config file. withMercur() wraps defineConfig() and wires the marketplace layer in — you pass it the same shape you would pass to Medusa, plus one Mercur-specific field.

withMercur()

medusa-config.ts
import { loadEnv } from "@medusajs/framework/utils"
import { withMercur } from "@mercurjs/core"

loadEnv(process.env.NODE_ENV || "development", process.cwd())

module.exports = withMercur({
  projectConfig: {
    databaseUrl: process.env.DATABASE_URL,
    redisUrl: process.env.REDIS_URL,
    http: {
      storeCors: process.env.STORE_CORS!,
      adminCors: process.env.ADMIN_CORS!,
      vendorCors: process.env.VENDOR_CORS!, // Mercur-specific
      authCors: process.env.AUTH_CORS!,
      jwtSecret: process.env.JWT_SECRET,
      cookieSecret: process.env.COOKIE_SECRET,
    },
  },
  featureFlags: {
    seller_registration: true,
  },
  modules: [
    // your modules and providers
  ],
})
The option surface is Medusa’s InputConfigWithArrayModules extended with:
OptionTypePurpose
projectConfig.http.vendorCorsstringCORS origins for the Vendor API (/vendor/*) — the only Mercur-specific option

What withMercur applies

BehaviorDetail
Registers the core pluginAppends @mercurjs/core to plugins unless already present
Registers RBACAppends the @medusajs/medusa/rbac module and forces featureFlags.rbac = true, so vendor role scoping works out of the box
Disables the Medusa adminadmin.disable defaults to true — Mercur ships its own dashboards
Adjusts core middlewaresReplaces the Medusa middlewares that Mercur overrides (e.g. collections with media)
Everything you pass is otherwise forwarded to defineConfig() unchanged, so any valid Medusa configuration remains valid here.

Environment variables

The starter (apps/api and projects created with create-mercur-app) reads:
VariablePurposeDefault
DATABASE_URLPostgres connection string— (required)
REDIS_URLRedis for cache, event bus, workflow engine, lockingredis://localhost:6379
STORE_CORSStorefront CORS origins— (required)
ADMIN_CORSAdmin panel CORS origins— (required)
VENDOR_CORSVendor panel CORS origins— (required)
AUTH_CORSAuth endpoint CORS origins— (required)
JWT_SECRETJWT signing secretsupersecret (change in production)
COOKIE_SECRETCookie signing secretsupersecret (change in production)
FILE_BACKEND_URLPublic origin baked into uploaded file URLshttp://localhost:9000/static
MERCUR_VENDOR_URLVendor dashboard base URL used in member invite links"" — can also be set via the seller module’s vendor_url option
NODE_ENVEnvironment selectiondevelopment

Dashboard modules

The admin and vendor dashboards are served by two UI modules:
modules: [
  {
    resolve: "@mercurjs/core/modules/admin-ui",
    options: { appDir: "./admin", path: "/dashboard" },
  },
  {
    resolve: "@mercurjs/core/modules/vendor-ui",
    options: { appDir: "./vendor", path: "/seller" },
  },
]
OptionTypePurpose
disablebooleanSkip serving this dashboard from the API process
pathstringMount path (e.g. /dashboard, /seller)
appDirstringDirectory of the dashboard Vite app
viteDevServerPort / viteDevServerHostnumber / stringDev-mode proxy target (host defaults to localhost)

Stripe Connect payout provider

Register @mercurjs/payout-stripe-connect as a provider of the payout module:
{
  resolve: "@mercurjs/core/modules/payout",
  options: {
    providers: [
      {
        resolve: "@mercurjs/payout-stripe-connect",
        id: "stripe-connect",
        options: {
          apiKey: process.env.STRIPE_SECRET_KEY,
          webhookSecret: process.env.STRIPE_WEBHOOK_SECRET,
        },
      },
    ],
  },
}
OptionTypeDefaultPurpose
apiKeystring— (required)Stripe secret key
webhookSecretstring— (required)Verifies incoming Stripe webhook signatures
accountValidation.detailsSubmittedbooleantrueRequire onboarding details submitted before the account is active
accountValidation.chargesEnabledbooleantrueRequire charges enabled
accountValidation.payoutsEnabledbooleantrueRequire payouts enabled
accountValidation.noOutstandingRequirementsbooleantrueTreat pending Stripe requirements as restricted
accountValidation.requiredCapabilitiesstring[][]Stripe capabilities that must be active
The payout module itself also accepts scheduling options (authorizationWindowMs, sellerActionWindowMs, captureSafetyBufferMs, requiredFulfillmentStatus) — see the Payout module reference.

Search provider

The search module needs no configuration — when no provider is given, the built-in in-memory Orama provider registers automatically. To use a custom provider:
{
  resolve: "@mercurjs/core/modules/search",
  options: {
    provider: {
      resolve: "./src/providers/my-search-provider",
      id: "my-search",
      options: { /* provider options */ },
    },
  },
}
The provider must extend AbstractSearchProvider — see the Search module reference.

Next steps

Installation

Stripe Connect integration