From d51063919372ba791985ab40d2a7d8940e97690e Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Thu, 28 Aug 2025 18:49:07 +0300 Subject: [PATCH] docs: docs for next release (#13303) * added draft order plugin docs * fix vale error * added note about draft order being optional * add new shipping option - shipping method link * update user guides * generate * fix github icon * changes to shipping option type * document logger * reorder list * fixes * fixes --- .../components/MDXComponents/index.tsx | 3 +- .../DescriptionSection/Events/index.tsx | 5 +- .../Operation/DescriptionSection/index.tsx | 6 +- .../Operation/FeatureFlagNotice/index.tsx | 1 + .../Parameters/Description/index.tsx | 6 +- .../components/Tags/Section/Schema/index.tsx | 6 +- .../components/Tags/Section/index.tsx | 6 +- .../configurations/medusa-config/page.mdx | 22 + .../logging/custom-logger/page.mdx | 133 ++++++ .../debugging-and-testing/logging/page.mdx | 2 + www/apps/book/generated/edit-dates.mjs | 7 +- www/apps/book/generated/sidebar.mjs | 13 +- www/apps/book/public/llms-full.txt | 382 +++++++++++++++++- www/apps/book/sidebar.mjs | 7 + .../cloud/app/draft-order-plugin/page.mdx | 37 -- www/apps/cloud/app/page.mdx | 2 +- .../cloud/components/MDXComponents/index.tsx | 2 - www/apps/cloud/generated/edit-dates.mjs | 3 +- www/apps/cloud/generated/sidebar.mjs | 6 +- www/apps/cloud/next.config.mjs | 6 + www/apps/cloud/sidebar.mjs | 6 +- .../cart/links-to-other-modules/page.mdx | 65 +++ .../links-to-other-modules/page.mdx | 67 +++ .../fulfillment/shipping-option/page.mdx | 32 +- .../order/draft-orders/page.mdx | 112 +++++ .../app/commerce-modules/order/page.mdx | 2 +- .../components/MDXComponents/index.tsx | 2 - www/apps/resources/generated/edit-dates.mjs | 7 +- www/apps/resources/generated/files-map.mjs | 4 + .../generated-commerce-modules-sidebar.mjs | 40 ++ www/apps/resources/sidebars/order-module.mjs | 5 + .../ui/components/MDXComponents/index.tsx | 2 - .../app/orders/draft-orders/create/page.mdx | 62 +++ .../app/orders/draft-orders/manage/page.mdx | 270 +++++++++++++ .../app/orders/draft-orders/page.mdx | 44 ++ www/apps/user-guide/app/orders/page.mdx | 3 +- .../user-guide/app/orders/payments/page.mdx | 32 +- .../app/promotions/campaigns/page.mdx | 2 +- .../user-guide/app/promotions/create/page.mdx | 80 ++-- .../user-guide/app/promotions/manage/page.mdx | 35 +- .../locations-and-shipping/locations/page.mdx | 15 +- .../settings/locations-and-shipping/page.mdx | 5 +- .../shipping-option-types/page.mdx | 107 +++++ .../app/settings/product-tags/page.mdx | 31 +- .../app/settings/tax-regions/page.mdx | 26 +- .../components/MDXComponents/index.tsx | 2 - www/apps/user-guide/generated/edit-dates.mjs | 16 +- www/apps/user-guide/generated/sidebar.mjs | 35 +- www/apps/user-guide/sidebar.mjs | 24 +- .../src/components/MarkdownContent/index.tsx | 3 +- .../src/components/SourceCodeLink/index.tsx | 4 +- www/packages/tags/src/tags/auth.ts | 8 +- www/packages/tags/src/tags/fulfillment.ts | 4 + www/packages/tags/src/tags/order.ts | 12 + www/packages/tags/src/tags/user-guide.ts | 16 + 55 files changed, 1653 insertions(+), 182 deletions(-) create mode 100644 www/apps/book/app/learn/debugging-and-testing/logging/custom-logger/page.mdx delete mode 100644 www/apps/cloud/app/draft-order-plugin/page.mdx create mode 100644 www/apps/resources/app/commerce-modules/order/draft-orders/page.mdx create mode 100644 www/apps/user-guide/app/orders/draft-orders/create/page.mdx create mode 100644 www/apps/user-guide/app/orders/draft-orders/manage/page.mdx create mode 100644 www/apps/user-guide/app/orders/draft-orders/page.mdx create mode 100644 www/apps/user-guide/app/settings/locations-and-shipping/shipping-option-types/page.mdx diff --git a/www/apps/api-reference/components/MDXComponents/index.tsx b/www/apps/api-reference/components/MDXComponents/index.tsx index a39b8c7cda..7a5476cb3a 100644 --- a/www/apps/api-reference/components/MDXComponents/index.tsx +++ b/www/apps/api-reference/components/MDXComponents/index.tsx @@ -2,7 +2,7 @@ import type { MDXComponents } from "mdx/types" import Security from "./Security" import type { OpenAPI } from "types" import H2 from "./H2" -import { Link, MDXComponents as UiMDXComponents } from "docs-ui" +import { MDXComponents as UiMDXComponents } from "docs-ui" export type ScopeType = { specs?: OpenAPI.OpenAPIV3.Document @@ -13,7 +13,6 @@ const getCustomComponents = (scope?: ScopeType): MDXComponents => { return { ...UiMDXComponents, Security: () => , - a: Link, h2: (props: React.HTMLAttributes) =>

, } } diff --git a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Events/index.tsx b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Events/index.tsx index 2520de067d..c1cced590c 100644 --- a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Events/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/Events/index.tsx @@ -36,7 +36,10 @@ const TagsOperationDescriptionSectionEvents = ({ The following events are emitted by the workflow used in this API route. You can listen to and handle these events using a{" "} - + Subscriber diff --git a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/index.tsx b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/index.tsx index 9fb48e734c..e3c9004b81 100644 --- a/www/apps/api-reference/components/Tags/Operation/DescriptionSection/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/DescriptionSection/index.tsx @@ -117,7 +117,11 @@ const TagsOperationDescriptionSection = ({ {operation.externalDocs && ( <> Related guide:{" "} - + {operation.externalDocs.description || "Read More"} diff --git a/www/apps/api-reference/components/Tags/Operation/FeatureFlagNotice/index.tsx b/www/apps/api-reference/components/Tags/Operation/FeatureFlagNotice/index.tsx index 60840d09d9..f3c41fa014 100644 --- a/www/apps/api-reference/components/Tags/Operation/FeatureFlagNotice/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/FeatureFlagNotice/index.tsx @@ -22,6 +22,7 @@ const TagsOperationFeatureFlagNotice = ({ enable its feature flag: {featureFlag} diff --git a/www/apps/api-reference/components/Tags/Operation/Parameters/Description/index.tsx b/www/apps/api-reference/components/Tags/Operation/Parameters/Description/index.tsx index b588fa7061..48ce3eaf48 100644 --- a/www/apps/api-reference/components/Tags/Operation/Parameters/Description/index.tsx +++ b/www/apps/api-reference/components/Tags/Operation/Parameters/Description/index.tsx @@ -59,7 +59,11 @@ const TagOperationParametersDescription = ({ {schema.externalDocs && ( Related guide:{" "} - + {schema.externalDocs.description || "Read More"} diff --git a/www/apps/api-reference/components/Tags/Section/Schema/index.tsx b/www/apps/api-reference/components/Tags/Section/Schema/index.tsx index 8fc95e076c..38571de0bb 100644 --- a/www/apps/api-reference/components/Tags/Section/Schema/index.tsx +++ b/www/apps/api-reference/components/Tags/Section/Schema/index.tsx @@ -4,7 +4,6 @@ import { Suspense, useEffect, useMemo } from "react" import { OpenAPI } from "types" import TagOperationParameters from "../../Operation/Parameters" import { - Badge, CodeBlock, isElmWindow, Link, @@ -112,7 +111,10 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => { Medusa application may support more fields and relations. To view the models in the Medusa application and their relations, visit the{" "} - + Commerce Modules Documentation diff --git a/www/apps/api-reference/components/Tags/Section/index.tsx b/www/apps/api-reference/components/Tags/Section/index.tsx index fcb2651100..d2b0abbf61 100644 --- a/www/apps/api-reference/components/Tags/Section/index.tsx +++ b/www/apps/api-reference/components/Tags/Section/index.tsx @@ -153,7 +153,11 @@ const TagSectionComponent = ({ tag }: TagSectionProps) => { {tag.externalDocs && (

Related guide:{" "} - + {tag.externalDocs.description || "Read More"}

diff --git a/www/apps/book/app/learn/configurations/medusa-config/page.mdx b/www/apps/book/app/learn/configurations/medusa-config/page.mdx index 6336f12997..c9d8d500c6 100644 --- a/www/apps/book/app/learn/configurations/medusa-config/page.mdx +++ b/www/apps/book/app/learn/configurations/medusa-config/page.mdx @@ -39,6 +39,7 @@ The `defineConfig` utility accepts an object having the following properties: - [modules](#module-configurations-modules): Configurations related to registered modules. - [plugins](#plugin-configurations-plugins): Configurations related to registered plugins. - [featureFlags](#feature-flags-featureFlags): Configurations to manage enabled beta features in the Medusa application. +- [logger](#custom-logger-logger): Override the default logger. ### Using Environment Variables @@ -1131,3 +1132,24 @@ After enabling a feature flag, make sure to run migrations, as the feature may i ```bash npx medusa db:migrate ``` + +--- + +## Custom Logger (`logger`) + +The `logger` configuration allows you to override the default [Logger](../../debugging-and-testing/logging/page.mdx) used in the Medusa application with your custom implementation. + +Learn more about creating a custom logger in the [Override Logger](../../debugging-and-testing/logging/custom-logger/page.mdx) chapter. + +The `logger` configuration accepts an instance of a class that extends the `Logger` interface. + +### Example + +```ts title="medusa-config.ts" +import { logger } from "./src/logger/my-logger" + +module.exports = defineConfig({ + // ... + logger, +}) +``` \ No newline at end of file diff --git a/www/apps/book/app/learn/debugging-and-testing/logging/custom-logger/page.mdx b/www/apps/book/app/learn/debugging-and-testing/logging/custom-logger/page.mdx new file mode 100644 index 0000000000..062e99eba6 --- /dev/null +++ b/www/apps/book/app/learn/debugging-and-testing/logging/custom-logger/page.mdx @@ -0,0 +1,133 @@ +export const metadata = { + title: `${pageNumber} Override Logger`, +} + +# {metadata.title} + +In this guide, you'll learn how to override the default [Logger](../page.mdx) in Medusa with your custom implementation. + +## Why Override the Logger? + +Medusa's default `Logger` logs your application's events, errors, and general log messages into the console. However, you might want to customize this behavior for your specific use case. + +For example, you might want to change the logs format, or add additional metadata to your logs. In those cases, it's useful to override the default `Logger` with your custom implementation. + +After overriding the `Logger`, Medusa will use your custom logger whenever it needs to log a message. + +--- + +## How to Override the Logger? + +To override the default `Logger`: + +1. Create a class that extends the `Logger` interface from `@medusajs/framework/types`. +2. Pass the class in the Medusa configurations. + +### Step 1: Create a Custom Logger Class + +To create a custom logger class, create a new file at `src/utils/custom-logger.ts` with the following content: + +```ts title="src/utils/custom-logger.ts" +import { Logger } from "@medusajs/framework/types" + +class MyLogger implements Logger { + panic(data: unknown): void { + console.error("PANIC:", data) + } + shouldLog(level: string): boolean { + // For demonstration, always log + return true + } + setLogLevel(level: string): void { + console.info("Set log level to:", level) + } + unsetLogLevel(): void { + console.info("Unset log level") + } + activity(message: string, config?: unknown): string { + console.log("ACTIVITY:", message, config) + return "activity-id" + } + progress(activityId: string, message: string): void { + console.log(`PROGRESS [${activityId}]:`, message) + } + error(messageOrError: string | Error, error?: Error): void { + if (error) { + console.error("ERROR:", messageOrError, error) + } else { + console.error("ERROR:", messageOrError) + } + } + failure(activityId: string, message: string): unknown { + console.warn(`FAILURE [${activityId}]:`, message) + return null + } + success(activityId: string, message: string): Record { + console.log(`SUCCESS [${activityId}]:`, message) + return { activityId, message } + } + silly(message: string): void { + console.debug("SILLY:", message) + } + debug(message: string): void { + console.debug("DEBUG:", message) + } + verbose(message: string): void { + console.info("VERBOSE:", message) + } + http(message: string): void { + console.info("HTTP:", message) + } + info(message: string): void { + console.info("INFO:", message) + } + warn(message: string): void { + console.warn("WARN:", message) + } + log(...args: unknown[]): void { + console.log(...args) + } +} + +export const logger = new MyLogger() +``` + +You can implement the methods as per your requirements. For simplicity, the above example logs messages to the console with a prefix indicating the log level. + +Notice that you must export an instance of your custom logger class to use it in the Medusa configurations. + + + +You can learn more about the methods in the [Logger](../page.mdx) chapter. + + + +### Step 2: Pass the Custom Logger in Medusa Configurations + +Next, to use the custom logger, set the `logger` configuration in your `medusa-config.ts` file: + +```ts title="medusa-config.ts" +import { logger } from "./src/logger/my-logger" + +module.exports = defineConfig({ + // ... + logger, +}) +``` + +The `logger` configuration accepts an instance of a class that extends the `Logger` interface. + +### Test Custom Logger + +To test that your custom logger is working, start the Medusa application: + +```bash npm2yarn +npm run dev +``` + +The logs will be displayed based on your custom implementation. For example, the above implementation that logs messages to the console will show logs similar to the following: + +```bash +INFO: Watching filesystem to reload dev server on file change +WARN: Local Event Bus installed. This is not recommended for production. +``` diff --git a/www/apps/book/app/learn/debugging-and-testing/logging/page.mdx b/www/apps/book/app/learn/debugging-and-testing/logging/page.mdx index 5fd00694c5..2babdffede 100644 --- a/www/apps/book/app/learn/debugging-and-testing/logging/page.mdx +++ b/www/apps/book/app/learn/debugging-and-testing/logging/page.mdx @@ -10,6 +10,8 @@ In this chapter, you’ll learn how to use Medusa’s logging utility. Medusa provides a `Logger` class with advanced logging functionalities. This includes configuring logging levels or saving logs to a file. +By default, the `Logger` class logs messages to the console. You can also override the default logger with your custom implementation, as explained in the [Override Logger](./custom-logger/page.mdx) guide. + The Medusa application registers the `Logger` class in the Medusa container and each module's container as `logger`. --- diff --git a/www/apps/book/generated/edit-dates.mjs b/www/apps/book/generated/edit-dates.mjs index 00e3e70607..94c1f61e3d 100644 --- a/www/apps/book/generated/edit-dates.mjs +++ b/www/apps/book/generated/edit-dates.mjs @@ -6,7 +6,7 @@ export const generatedEditDates = { "app/learn/fundamentals/modules/commerce-modules/page.mdx": "2025-04-17T08:51:32.723Z", "app/learn/fundamentals/workflows/retry-failed-steps/page.mdx": "2025-03-28T07:15:19.388Z", "app/learn/fundamentals/workflows/workflow-hooks/page.mdx": "2024-12-09T10:44:33.781Z", - "app/learn/debugging-and-testing/logging/page.mdx": "2025-05-30T14:00:20.783Z", + "app/learn/debugging-and-testing/logging/page.mdx": "2025-08-28T15:31:57.879Z", "app/learn/storefront-development/page.mdx": "2024-12-10T09:11:04.993Z", "app/learn/fundamentals/page.mdx": "2024-07-04T17:26:03+03:00", "app/learn/fundamentals/admin-customizations/page.mdx": "2024-10-07T12:41:39.218Z", @@ -111,7 +111,7 @@ export const generatedEditDates = { "app/learn/resources/contribution-guidelines/admin-translations/page.mdx": "2025-02-11T16:57:46.726Z", "app/learn/resources/contribution-guidelines/docs/page.mdx": "2025-08-20T06:41:30.822Z", "app/learn/resources/usage/page.mdx": "2025-02-26T13:35:34.824Z", - "app/learn/configurations/medusa-config/page.mdx": "2025-07-14T09:28:54.302Z", + "app/learn/configurations/medusa-config/page.mdx": "2025-08-28T15:35:36.344Z", "app/learn/configurations/ts-aliases/page.mdx": "2025-07-23T15:32:18.008Z", "app/learn/production/worker-mode/page.mdx": "2025-07-18T15:19:45.352Z", "app/learn/fundamentals/module-links/read-only/page.mdx": "2025-08-15T11:52:13.403Z", @@ -127,5 +127,6 @@ export const generatedEditDates = { "app/learn/fundamentals/generated-types/page.mdx": "2025-07-25T13:17:35.319Z", "app/learn/introduction/from-v1-to-v2/page.mdx": "2025-07-30T08:13:48.592Z", "app/learn/debugging-and-testing/debug-workflows/page.mdx": "2025-07-30T13:45:14.117Z", - "app/learn/fundamentals/data-models/json-properties/page.mdx": "2025-07-31T14:25:01.268Z" + "app/learn/fundamentals/data-models/json-properties/page.mdx": "2025-07-31T14:25:01.268Z", + "app/learn/debugging-and-testing/logging/custom-logger/page.mdx": "2025-08-28T15:37:07.328Z" } \ No newline at end of file diff --git a/www/apps/book/generated/sidebar.mjs b/www/apps/book/generated/sidebar.mjs index fe0ae55afd..10bfe6c14f 100644 --- a/www/apps/book/generated/sidebar.mjs +++ b/www/apps/book/generated/sidebar.mjs @@ -1209,7 +1209,18 @@ export const generatedSidebars = [ "type": "link", "path": "/learn/debugging-and-testing/logging", "title": "Logging", - "children": [], + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "path": "/learn/debugging-and-testing/logging/custom-logger", + "title": "Override Logger", + "children": [], + "chapterTitle": "7.6.1. Override Logger", + "number": "7.6.1." + } + ], "chapterTitle": "7.6. Logging", "number": "7.6." } diff --git a/www/apps/book/public/llms-full.txt b/www/apps/book/public/llms-full.txt index 78adf7de25..4a4b7232e4 100644 --- a/www/apps/book/public/llms-full.txt +++ b/www/apps/book/public/llms-full.txt @@ -109,6 +109,7 @@ The `defineConfig` utility accepts an object having the following properties: - [modules](#module-configurations-modules): Configurations related to registered modules. - [plugins](#plugin-configurations-plugins): Configurations related to registered plugins. - [featureFlags](#feature-flags-featureFlags): Configurations to manage enabled beta features in the Medusa application. +- [logger](#custom-logger-logger): Override the default logger. ### Using Environment Variables @@ -992,6 +993,27 @@ After enabling a feature flag, make sure to run migrations, as the feature may i npx medusa db:migrate ``` +*** + +## Custom Logger (`logger`) + +The `logger` configuration allows you to override the default [Logger](https://docs.medusajs.com/learn/debugging-and-testing/logging/index.html.md) used in the Medusa application with your custom implementation. + +Learn more about creating a custom logger in the [Override Logger](https://docs.medusajs.com/learn/debugging-and-testing/logging/custom-logger/index.html.md) chapter. + +The `logger` configuration accepts an instance of a class that extends the `Logger` interface. + +### Example + +```ts title="medusa-config.ts" +import { logger } from "./src/logger/my-logger" + +module.exports = defineConfig({ + // ... + logger, +}) +``` + # Using TypeScript Aliases @@ -4000,6 +4022,133 @@ Trace span names start with the following keywords based on what it's reporting: - [Integrate Sentry with Medusa](https://docs.medusajs.com/resources/integrations/guides/sentry/index.html.md) +# Override Logger + +In this guide, you'll learn how to override the default [Logger](https://docs.medusajs.com/learn/debugging-and-testing/logging/index.html.md) in Medusa with your custom implementation. + +## Why Override the Logger? + +Medusa's default `Logger` logs your application's events, errors, and general log messages into the console. However, you might want to customize this behavior for your specific use case. + +For example, you might want to change the logs format, or add additional metadata to your logs. In those cases, it's useful to override the default `Logger` with your custom implementation. + +After overriding the `Logger`, Medusa will use your custom logger whenever it needs to log a message. + +*** + +## How to Override the Logger? + +To override the default `Logger`: + +1. Create a class that extends the `Logger` interface from `@medusajs/framework/types`. +2. Pass the class in the Medusa configurations. + +### Step 1: Create a Custom Logger Class + +To create a custom logger class, create a new file at `src/utils/custom-logger.ts` with the following content: + +```ts title="src/utils/custom-logger.ts" +import { Logger } from "@medusajs/framework/types" + +class MyLogger implements Logger { + panic(data: unknown): void { + console.error("PANIC:", data) + } + shouldLog(level: string): boolean { + // For demonstration, always log + return true + } + setLogLevel(level: string): void { + console.info("Set log level to:", level) + } + unsetLogLevel(): void { + console.info("Unset log level") + } + activity(message: string, config?: unknown): string { + console.log("ACTIVITY:", message, config) + return "activity-id" + } + progress(activityId: string, message: string): void { + console.log(`PROGRESS [${activityId}]:`, message) + } + error(messageOrError: string | Error, error?: Error): void { + if (error) { + console.error("ERROR:", messageOrError, error) + } else { + console.error("ERROR:", messageOrError) + } + } + failure(activityId: string, message: string): unknown { + console.warn(`FAILURE [${activityId}]:`, message) + return null + } + success(activityId: string, message: string): Record { + console.log(`SUCCESS [${activityId}]:`, message) + return { activityId, message } + } + silly(message: string): void { + console.debug("SILLY:", message) + } + debug(message: string): void { + console.debug("DEBUG:", message) + } + verbose(message: string): void { + console.info("VERBOSE:", message) + } + http(message: string): void { + console.info("HTTP:", message) + } + info(message: string): void { + console.info("INFO:", message) + } + warn(message: string): void { + console.warn("WARN:", message) + } + log(...args: unknown[]): void { + console.log(...args) + } +} + +export const logger = new MyLogger() +``` + +You can implement the methods as per your requirements. For simplicity, the above example logs messages to the console with a prefix indicating the log level. + +Notice that you must export an instance of your custom logger class to use it in the Medusa configurations. + +You can learn more about the methods in the [Logger](https://docs.medusajs.com/learn/debugging-and-testing/logging/index.html.md) chapter. + +### Step 2: Pass the Custom Logger in Medusa Configurations + +Next, to use the custom logger, set the `logger` configuration in your `medusa-config.ts` file: + +```ts title="medusa-config.ts" +import { logger } from "./src/logger/my-logger" + +module.exports = defineConfig({ + // ... + logger, +}) +``` + +The `logger` configuration accepts an instance of a class that extends the `Logger` interface. + +### Test Custom Logger + +To test that your custom logger is working, start the Medusa application: + +```bash npm2yarn +npm run dev +``` + +The logs will be displayed based on your custom implementation. For example, the above implementation that logs messages to the console will show logs similar to the following: + +```bash +INFO: Watching filesystem to reload dev server on file change +WARN: Local Event Bus installed. This is not recommended for production. +``` + + # Logging In this chapter, you’ll learn how to use Medusa’s logging utility. @@ -4008,6 +4157,8 @@ In this chapter, you’ll learn how to use Medusa’s logging utility. Medusa provides a `Logger` class with advanced logging functionalities. This includes configuring logging levels or saving logs to a file. +By default, the `Logger` class logs messages to the console. You can also override the default logger with your custom implementation, as explained in the [Override Logger](https://docs.medusajs.com/learn/debugging-and-testing/logging/custom-logger/index.html.md) guide. + The Medusa application registers the `Logger` class in the Medusa container and each module's container as `logger`. *** @@ -25945,6 +26096,7 @@ Read-only links are used to query data across modules, but the relations aren't |First Data Model|Second Data Model|Type|Description| |---|---|---|---| |Cart|Customer|Read-only - has one|Learn more| +|ShippingMethod|ShippingOption|Read-only - has one|Learn more| |Order|Cart|Stored - one-to-one|Learn more| |Cart|PaymentCollection|Stored - one-to-one|Learn more| |LineItem|Product|Read-only - has one|Learn more| @@ -25995,6 +26147,48 @@ const { data: carts } = useQueryGraphStep({ *** +## Fulfillment Module + +Medusa defines a read-only link between the `ShippingMethod` data model and the [Fulfillment Module](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/fulfillment/index.html.md)'s `ShippingOption` data model. This means you can retrieve the details of a shipping method's shipping option, but you don't manage the links in a pivot table in the database. The shipping option of a shipping method is determined by the `shipping_option_id` property of the `ShippingMethod` data model. + +This link allows you to retrieve the shipping option that a shipping method was created from. + +This read-only link was added in [Medusa v2.10.0](https://github.com/medusajs/medusa/releases/tag/v2.10.0) + +### Retrieve with Query + +To retrieve the shipping option of a shipping method with [Query](https://docs.medusajs.com/docs/learn/fundamentals/module-links/query/index.html.md), pass `shipping_option.*` in `fields`: + +### query.graph + +```ts +const { data: shippingMethods } = await query.graph({ + entity: "shipping_method", + fields: [ + "shipping_option.*", + ], +}) + +// shippingMethods[0].shipping_option +``` + +### useQueryGraphStep + +```ts +import { useQueryGraphStep } from "@medusajs/medusa/core-flows" + +// ... + +const { data: shippingMethods } = useQueryGraphStep({ + entity: "shipping_method", + fields: [ + "shipping_option.*", + ], +}) + +// shippingMethods[0].shipping_option +``` + ## Order Module The [Order Module](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/index.html.md) provides order-management features. @@ -27479,6 +27673,7 @@ The Fulfillment Module has the following links to other modules: |First Data Model|Second Data Model|Type|Description| |---|---|---|---| +|ShippingMethod|ShippingOption|Read-only - has one|Learn more| |Order|Fulfillment|Stored - one-to-many|Learn more| |Return|Fulfillment|Stored - one-to-many|Learn more| |PriceSet|ShippingOption|Stored - many-to-one|Learn more| @@ -27488,6 +27683,50 @@ The Fulfillment Module has the following links to other modules: *** +## Cart Module + +Medusa defines a read-only link between the `ShippingMethod` data model of the [Cart Module](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/cart/index.html.md) and the `ShippingOption` data model. This means you can retrieve the details of a shipping method's shipping option, but you don't manage the links in a pivot table in the database. The shipping option of a shipping method is determined by the `shipping_option_id` property of the `ShippingMethod` data model. + +This link allows you to retrieve the shipping option that a shipping method was created from. + +This read-only link was added in [Medusa v2.10.0](https://github.com/medusajs/medusa/releases/tag/v2.10.0) + +### Retrieve with Query + +To retrieve the shipping option of a shipping method with [Query](https://docs.medusajs.com/docs/learn/fundamentals/module-links/query/index.html.md), pass `shipping_option.*` in `fields`: + +### query.graph + +```ts +const { data: shippingMethods } = await query.graph({ + entity: "shipping_method", + fields: [ + "shipping_option.*", + ], +}) + +// shippingMethods[0].shipping_option +``` + +### useQueryGraphStep + +```ts +import { useQueryGraphStep } from "@medusajs/medusa/core-flows" + +// ... + +const { data: shippingMethods } = useQueryGraphStep({ + entity: "shipping_method", + fields: [ + "shipping_option.*", + ], +}) + +// shippingMethods[0].shipping_option +``` + +*** + ## Order Module The [Order Module](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/index.html.md) provides order-management functionalities. @@ -28045,11 +28284,11 @@ The Fulfillment Module accepts options for further configurations. Refer to [thi In this document, you’ll learn about shipping options and their rules. -## What’s a Shipping Option? +## What is a Shipping Option? -A shipping option is a way of shipping an item. Each fulfillment provider provides a set of shipping options. For example, a provider may provide a shipping option for express shipping and another for standard shipping. +A shipping option is a way of shipping an item. Each fulfillment provider offers a set of shipping options. For example, a provider may offer a shipping option for express shipping and another for standard shipping. -When the customer places their order, they choose a shipping option to be used to fulfill their items. +When the customer places an order, they choose a shipping option to fulfill their items. A shipping option is represented by the [ShippingOption data model](https://docs.medusajs.com/references/fulfillment/models/ShippingOption/index.html.md). @@ -28057,15 +28296,15 @@ A shipping option is represented by the [ShippingOption data model](https://docs ## Service Zone Restrictions -A shipping option is restricted by a service zone, limiting the locations a shipping option be used in. +A shipping option is restricted by a service zone, which limits the locations where the shipping option can be used. -For example, a fulfillment provider may have a shipping option that can be used in the United States, and another in Canada. +For example, a fulfillment provider may have a shipping option that can be used in the United States and another in Canada. ![A diagram showcasing the relation between shipping options and service zones.](https://res.cloudinary.com/dza7lstvk/image/upload/v1712330831/Medusa%20Resources/shipping-option-service-zone_pobh6k.jpg) -Service zones can be more restrictive, such as restricting to certain cities or province codes. +Service zones can be more restrictive, such as limiting to certain cities or province codes. -The province code is always in lower-case and in [ISO 3166-2 format](https://en.wikipedia.org/wiki/ISO_3166-2). +The province code is always in lowercase and in [ISO 3166-2 format](https://en.wikipedia.org/wiki/ISO_3166-2). ![A diagram showcasing the relation between shipping options, service zones, and geo zones](https://res.cloudinary.com/dza7lstvk/image/upload/v1712331186/Medusa%20Resources/shipping-option-service-zone-city_m5sxod.jpg) @@ -28073,11 +28312,11 @@ The province code is always in lower-case and in [ISO 3166-2 format](https://en. ## Shipping Option Rules -You can restrict shipping options by custom rules, such as the item’s weight or the customer’s group. +You can restrict shipping options by custom rules, such as the item’s weight or the customer group. -You can also restrict a shipping option's price based on specific conditions. For example, you can make a shipping option's price free based on the cart's total. Learn more in the Pricing Module's [Price Rules](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/pricing/price-rules#how-to-set-rules-on-a-price/index.html.md) guide. +You can also restrict a shipping option's price based on specific conditions. For example, you can make a shipping option's price free based on the cart total. Learn more in the Pricing Module's [Price Rules](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/pricing/price-rules#how-to-set-rules-on-a-price/index.html.md) guide. -These rules are represented by the [ShippingOptionRule data model](https://docs.medusajs.com/references/fulfillment/models/ShippingOptionRule/index.html.md). Its properties define the custom rule: +These rules are represented by the [ShippingOptionRule data model](https://docs.medusajs.com/references/fulfillment/models/ShippingOptionRule/index.html.md). Its properties define the custom rules: - `attribute`: The name of a property or table that the rule applies to. For example, `customer_group`. - `operator`: The operator used in the condition. For example: @@ -28093,19 +28332,21 @@ A shipping option can have multiple rules. For example, you can add rules to a s *** -## Shipping Profile and Types +## Shipping Profiles and Types -A shipping option belongs to a type. For example, a shipping option’s type may be `express`, while another `standard`. The type is represented by the [ShippingOptionType data model](https://docs.medusajs.com/references/fulfillment/models/ShippingOptionType/index.html.md). +A shipping option belongs to a type and a profile. -A shipping option also belongs to a shipping profile, as each shipping profile defines the type of items to be shipped in a similar manner. +A shipping option type defines a group of shipping options with shared shipping characteristics. For example, a shipping option’s type may be `express`, while another may be `standard`. The type is represented by the [ShippingOptionType data model](https://docs.medusajs.com/references/fulfillment/models/ShippingOptionType/index.html.md). + +A shipping profile defines a group of items (such as products) that are shipped in a similar manner. For example, the "Standard" shipping profile applies to all products, whereas the "Digital" shipping profile applies to digital products. Shipping profiles are represented by the [ShippingProfile data model](https://docs.medusajs.com/references/fulfillment/models/ShippingProfile/index.html.md). *** ## data Property -When fulfilling an item, you might use a third-party fulfillment provider that requires additional custom data to be passed along from the checkout or order-creation process. +When fulfilling an item, you might use a third-party fulfillment provider that requires additional custom data to be passed along from the checkout or order creation process. -The `ShippingOption` data model has a `data` property. It's an object that stores custom data relevant later when creating and processing a fulfillment. +The `ShippingOption` data model has a `data` property. It's an object that stores custom data relevant for creating and processing a fulfillment later. # Inventory Concepts @@ -29005,6 +29246,105 @@ An order can have multiple transactions. The sum of these transactions must be e Refer to the [Transactions](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/transactions/index.html.md) guide to learn more. +# Draft Orders Plugin + +In this guide, you'll learn about the Draft Orders Plugin and its features. + +The Draft Orders Plugin was initially only available to Cloud users during its early access phase. It is now available for all Medusa users. + +## What is the Draft Orders Plugin? + +The Draft Orders Plugin is a Medusa plugin that allows admin users to create and manage draft orders on behalf of customers from the Medusa Admin. + +The Medusa application already has the foundation to support draft orders, including data models and API routes. This plugin adds a user interface for managing draft orders in the Medusa Admin dashboard. + +The Draft Orders Plugin is especially useful for handling customer support scenarios or when a customer places an order offline, such as over the phone or in-store. + +### Features + +- [Create draft orders from the Medusa Admin.](https://docs.medusajs.com/user-guide/orders/draft-orders/create/index.html.md) +- [Manage items in a draft order, allowing admin users to add, update, or remove items](https://docs.medusajs.com/user-guide/orders/draft-orders/manage#manage-draft-orders-items/index.html.md). +- [Add shipping methods to draft orders.](https://docs.medusajs.com/user-guide/orders/draft-orders/manage#manage-draft-orders-shipping-methods/index.html.md). +- [Associate existing customers with draft orders.](https://docs.medusajs.com/user-guide/orders/draft-orders/manage#manage-draft-orders-customer-details/index.html.md). +- [Convert draft orders to regular orders.](https://docs.medusajs.com/user-guide/orders/draft-orders/manage#convert-draft-order-to-regular-order/index.html.md). + +*** + +## Install the Draft Orders Plugin + +The Draft Orders Plugin is available in all Medusa applications starting v2.10.0. + +For earlier versions, you can install the plugin manually. + +### Prerequisites + +- [Medusa application >= v2.4.0](https://docs.medusajs.com/docs/learn/installation/index.html.md) + +To install the Draft Orders Plugin: + +1. Run the following command in your Medusa application's directory: + +```bash npm2yarn +npm install @medusajs/draft-order +``` + +2. Add the plugin to your `medusa-config.ts` file: + +```ts title="medusa-config.ts" +module.exports = defineConfig({ + // ... + plugins: [ + { + resolve: "@medusajs/draft-order", + options: {}, + }, + ], +}) +``` + +### Test the Draft Orders Plugin + +To test the Draft Orders Plugin, start the Medusa application with the following command: + +```bash npm2yarn +npm run dev +``` + +If you open the Medusa Admin at `localhost:9000/app` and log in, you'll find an "Orders -> Drafts" sidebar item. + +*** + +## Draft Orders User Guides + +To learn how to use the draft order features in the Medusa Admin, refer to the [Draft Orders](https://docs.medusajs.com/user-guide/orders/draft-orders/index.html.md) user guides. + +*** + +## How Draft Orders Work + +A draft order is stored in the database as a regular order. It is represented by the [Order data model](https://docs.medusajs.com/references/order/models/Order/index.html.md) with the following properties: + +- `status`: Set to `draft` to indicate that the order is a draft. +- `is_draft_order`: Set to `true` to indicate that the order is a draft order. + +So, the same [order concepts](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/concepts/index.html.md) apply to draft orders as well. + +### Editing Draft Orders + +Similar to regular orders, draft orders can be [edited](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/edit/index.html.md), allowing admin users to add, update, or remove items, as well as add shipping methods. + +When the order edit is confirmed on the draft order, the changes are applied directly to the draft order and its [version](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/order-versioning/index.html.md) is incremented. + +### Converting Draft Orders to Regular Orders + +Once a draft order is finalized and ready for processing, it can be converted to a regular order. This involves: + +- Changing its `status` property to `pending`. +- Changing its `is_draft_order` property to `false`. + +Admin users can then manage the order like any other regular order, including processing payments and fulfilling items. + + # Order Edit In this document, you'll learn about order edits. @@ -30063,7 +30403,7 @@ Learn more about why modules are isolated in [this documentation](https://docs.m ## Order Features - [Order Management](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/concepts/index.html.md): Store and manage your orders to retrieve, create, cancel, and perform other operations. -- Draft Orders: Allow merchants to create orders on behalf of their customers as draft orders that later are transformed to regular orders. +- [Draft Orders](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/draft-orders/index.html.md): Allow merchants to create orders on behalf of their customers as draft orders that later are transformed to regular orders. - [Apply Promotion Adjustments](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/promotion-adjustments/index.html.md): Apply promotions or discounts to the order's items and shipping methods by adding adjustment lines that are factored into their subtotals. - [Apply Tax Lines](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/tax-lines/index.html.md): Apply tax lines to an order's line items and shipping methods. - [Returns](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/return/index.html.md), [Edits](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/edit/index.html.md), [Exchanges](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/exchange/index.html.md), and [Claims](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/claim/index.html.md): Make [changes](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/order-change/index.html.md) to an order to edit, return, or exchange its items, with [version-based control](https://docs.medusajs.com/Users/shahednasser/medusa/www/apps/resources/app/commerce-modules/order/order-versioning/index.html.md) over the order's timeline. @@ -41493,7 +41833,7 @@ Emitted when a shipment is created for an order. ```ts { - id, // the ID of the shipment + id, // the ID of the fulfillment no_notification, // (boolean) whether to notify the customer } ``` @@ -113061,7 +113401,13 @@ curl -X POST 'http://localhost:9000/restaurants/res_01J5X704WQTFSZMRC7Z6S3YAC7/p "amount": 20 } ], - "manage_inventory": false + "manage_inventory": false, + "options": [ + { + "title": "Default Title", + "values": ["Default Value"] + } + ] } ], "sales_channels": [ diff --git a/www/apps/book/sidebar.mjs b/www/apps/book/sidebar.mjs index 5b5661305b..0c5387d175 100644 --- a/www/apps/book/sidebar.mjs +++ b/www/apps/book/sidebar.mjs @@ -635,6 +635,13 @@ export const sidebars = [ type: "link", path: "/learn/debugging-and-testing/logging", title: "Logging", + children: [ + { + type: "link", + path: "/learn/debugging-and-testing/logging/custom-logger", + title: "Override Logger", + }, + ], }, ], }, diff --git a/www/apps/cloud/app/draft-order-plugin/page.mdx b/www/apps/cloud/app/draft-order-plugin/page.mdx deleted file mode 100644 index 98e181492b..0000000000 --- a/www/apps/cloud/app/draft-order-plugin/page.mdx +++ /dev/null @@ -1,37 +0,0 @@ -export const metadata = { - title: `Draft Order Plugin`, -} - -# {metadata.title} - -In this guide, you'll learn about the Draft Order Plugin add-on available to Cloud users. - -## What is the Draft Order Plugin? - -Draft orders allow admin users to create orders on behalf of customers. They are useful for customer support or when customers place orders offline. - -When you sign up for Cloud, you can access the Draft Order plugin in your deployed Medusa applications. - -The Draft Order Plugin is an add-on to your Cloud projects that provides draft order features in the Medusa Admin dashboard. - ---- - -## Draft Order Plugin Features - -The Draft Order Plugin provides the following features: - -- Create draft orders from the Medusa Admin dashboard. -- Manage items in draft orders, including adding, updating, and removing items. -- Add shipping methods to draft orders. -- Associate the draft order with a customer in your store. -- Convert the draft order to a regular order to complete the purchase. - -![A screenshot of the draft order management interface in the Medusa Admin dashboard](https://res.cloudinary.com/dza7lstvk/image/upload/v1750235297/Cloud/CleanShot_2025-06-18_at_11.27.36_2x_e6mf4v.png) - ---- - -## How to Install the Draft Order Plugin - -The Draft Order Plugin is currently only available for Cloud users. If you're not a Cloud user, [learn how to get started](../page.mdx#sign-up-for-cloud). - -Then, you can contact support for assistance in installing the Draft Order Plugin in your deployed Medusa application. \ No newline at end of file diff --git a/www/apps/cloud/app/page.mdx b/www/apps/cloud/app/page.mdx index 4fe80be0f2..7db3e8c365 100644 --- a/www/apps/cloud/app/page.mdx +++ b/www/apps/cloud/app/page.mdx @@ -25,5 +25,5 @@ Go to [medusajs.com/start](https://medusajs.com/start) and sign up to get starte - **Zero Downtime Deployments**: Medusa rolls out changes to production with zero downtime, never interrupting your users. - **Autoscaling**: Environments scale to meet traffic demands. - **Logging**: Monitor your project's runtime and build logs, so you can easily debug issues in your project. -- **Early Access**: Access new features before they are open-sourced, for example, Gift Cards and Draft Orders. +- **Early Access**: Access new features before they are open-sourced, such as Gift Cards. - **Dedicated Support**: Receive dedicated support from the Medusa team to help you with any issues you may encounter. diff --git a/www/apps/cloud/components/MDXComponents/index.tsx b/www/apps/cloud/components/MDXComponents/index.tsx index 8dd8409eb5..d40f6c616b 100644 --- a/www/apps/cloud/components/MDXComponents/index.tsx +++ b/www/apps/cloud/components/MDXComponents/index.tsx @@ -1,6 +1,5 @@ import type { MDXComponents as MDXComponentsType } from "mdx/types" import { - Link, MDXComponents as UiMdxComponents, InlineThemeImage, InlineIcon, @@ -8,7 +7,6 @@ import { const MDXComponents: MDXComponentsType = { ...UiMdxComponents, - a: Link, InlineThemeImage, InlineIcon, } diff --git a/www/apps/cloud/generated/edit-dates.mjs b/www/apps/cloud/generated/edit-dates.mjs index 7d567cb310..0f16888ce8 100644 --- a/www/apps/cloud/generated/edit-dates.mjs +++ b/www/apps/cloud/generated/edit-dates.mjs @@ -1,5 +1,5 @@ export const generatedEditDates = { - "app/page.mdx": "2025-06-25T08:00:52.728Z", + "app/page.mdx": "2025-08-26T10:31:10.511Z", "app/organization/page.mdx": "2025-06-12T14:43:20.772Z", "app/projects/page.mdx": "2025-08-25T07:23:12.745Z", "app/environments/page.mdx": "2025-06-25T08:00:05.550Z", @@ -9,7 +9,6 @@ export const generatedEditDates = { "app/database/page.mdx": "2025-08-15T15:30:37.814Z", "app/redis/page.mdx": "2025-06-25T07:57:23.246Z", "app/s3/page.mdx": "2025-06-25T07:57:24.832Z", - "app/draft-order-plugin/page.mdx": "2025-06-25T07:57:14.898Z", "app/loyalty-plugin/page.mdx": "2025-06-26T11:11:02.320Z", "app/logs/page.mdx": "2025-06-19T07:44:38.336Z", "app/update-medusa/page.mdx": "2025-06-25T07:57:30.170Z", diff --git a/www/apps/cloud/generated/sidebar.mjs b/www/apps/cloud/generated/sidebar.mjs index 107933757a..93b917a47e 100644 --- a/www/apps/cloud/generated/sidebar.mjs +++ b/www/apps/cloud/generated/sidebar.mjs @@ -147,7 +147,11 @@ export const generatedSidebars = [ "isPathHref": true, "type": "link", "title": "Draft Orders", - "path": "/draft-order-plugin", + "path": "https://docs.medusajs.com/resources/commerce-modules/order/draft-orders", + "badge": { + "text": "Published", + "variant": "blue" + }, "children": [] } ] diff --git a/www/apps/cloud/next.config.mjs b/www/apps/cloud/next.config.mjs index 8cdadd1176..9d09497b64 100644 --- a/www/apps/cloud/next.config.mjs +++ b/www/apps/cloud/next.config.mjs @@ -145,6 +145,12 @@ const nextConfig = { destination: "/billing", permanent: true, }, + { + source: "/cloud/draft-order-plugin", + destination: "/resources/commerce-modules/order/draft-orders", + basePath: false, + permanent: true, + }, ], } diff --git a/www/apps/cloud/sidebar.mjs b/www/apps/cloud/sidebar.mjs index 9536d56c34..41a7320e65 100644 --- a/www/apps/cloud/sidebar.mjs +++ b/www/apps/cloud/sidebar.mjs @@ -100,7 +100,11 @@ export const sidebar = [ { type: "link", title: "Draft Orders", - path: "/draft-order-plugin", + path: "https://docs.medusajs.com/resources/commerce-modules/order/draft-orders", + badge: { + text: "Published", + variant: "blue", + }, }, ], }, diff --git a/www/apps/resources/app/commerce-modules/cart/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/cart/links-to-other-modules/page.mdx index 75a36b246e..037cc0b521 100644 --- a/www/apps/resources/app/commerce-modules/cart/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/cart/links-to-other-modules/page.mdx @@ -61,6 +61,20 @@ Read-only links are used to query data across modules, but the relations aren't [Learn more](#customer-module) + + + [ShippingMethod](/references/cart/models/ShippingMethod) + + + [ShippingOption](/references/fulfillment/models/ShippingOption) in [Fulfillment Module](../../fulfillment/page.mdx) + + + Read-only - has one + + + [Learn more](#fulfillment-module) + + [Order](/references/order/models/Order) in [Order Module](../../order/page.mdx) @@ -211,6 +225,57 @@ const { data: carts } = useQueryGraphStep({ --- +## Fulfillment Module + +Medusa defines a read-only link between the `ShippingMethod` data model and the [Fulfillment Module](../../fulfillment/page.mdx)'s `ShippingOption` data model. This means you can retrieve the details of a shipping method's shipping option, but you don't manage the links in a pivot table in the database. The shipping option of a shipping method is determined by the `shipping_option_id` property of the `ShippingMethod` data model. + +This link allows you to retrieve the shipping option that a shipping method was created from. + + + +This read-only link was added in [Medusa v2.10.0](https://github.com/medusajs/medusa/releases/tag/v2.10.0) + + + +### Retrieve with Query + +To retrieve the shipping option of a shipping method with [Query](!docs!/learn/fundamentals/module-links/query), pass `shipping_option.*` in `fields`: + + + + +```ts +const { data: shippingMethods } = await query.graph({ + entity: "shipping_method", + fields: [ + "shipping_option.*", + ], +}) + +// shippingMethods[0].shipping_option +``` + + + + +```ts +import { useQueryGraphStep } from "@medusajs/medusa/core-flows" + +// ... + +const { data: shippingMethods } = useQueryGraphStep({ + entity: "shipping_method", + fields: [ + "shipping_option.*", + ], +}) + +// shippingMethods[0].shipping_option +``` + + + + ## Order Module The [Order Module](../../order/page.mdx) provides order-management features. diff --git a/www/apps/resources/app/commerce-modules/fulfillment/links-to-other-modules/page.mdx b/www/apps/resources/app/commerce-modules/fulfillment/links-to-other-modules/page.mdx index 8fd9087dfc..218cfa5fec 100644 --- a/www/apps/resources/app/commerce-modules/fulfillment/links-to-other-modules/page.mdx +++ b/www/apps/resources/app/commerce-modules/fulfillment/links-to-other-modules/page.mdx @@ -38,6 +38,20 @@ The Fulfillment Module has the following links to other modules: + + + [ShippingMethod](/references/cart/models/ShippingMethod) in [Cart Module](../../cart/page.mdx) + + + [ShippingOption](/references/fulfillment/models/ShippingOption) + + + Read-only - has one + + + [Learn more](#cart-module) + + [Order](/references/order/models/Order) in [Order Module](../../order/page.mdx) @@ -127,6 +141,59 @@ The Fulfillment Module has the following links to other modules: --- +## Cart Module + +Medusa defines a read-only link between the `ShippingMethod` data model of the [Cart Module](../../cart/page.mdx) and the `ShippingOption` data model. This means you can retrieve the details of a shipping method's shipping option, but you don't manage the links in a pivot table in the database. The shipping option of a shipping method is determined by the `shipping_option_id` property of the `ShippingMethod` data model. + +This link allows you to retrieve the shipping option that a shipping method was created from. + + + +This read-only link was added in [Medusa v2.10.0](https://github.com/medusajs/medusa/releases/tag/v2.10.0) + + + +### Retrieve with Query + +To retrieve the shipping option of a shipping method with [Query](!docs!/learn/fundamentals/module-links/query), pass `shipping_option.*` in `fields`: + + + + +```ts +const { data: shippingMethods } = await query.graph({ + entity: "shipping_method", + fields: [ + "shipping_option.*", + ], +}) + +// shippingMethods[0].shipping_option +``` + + + + +```ts +import { useQueryGraphStep } from "@medusajs/medusa/core-flows" + +// ... + +const { data: shippingMethods } = useQueryGraphStep({ + entity: "shipping_method", + fields: [ + "shipping_option.*", + ], +}) + +// shippingMethods[0].shipping_option +``` + + + + +--- + ## Order Module The [Order Module](../../order/page.mdx) provides order-management functionalities. diff --git a/www/apps/resources/app/commerce-modules/fulfillment/shipping-option/page.mdx b/www/apps/resources/app/commerce-modules/fulfillment/shipping-option/page.mdx index 6ac2ecf7e5..150622fdcd 100644 --- a/www/apps/resources/app/commerce-modules/fulfillment/shipping-option/page.mdx +++ b/www/apps/resources/app/commerce-modules/fulfillment/shipping-option/page.mdx @@ -6,11 +6,11 @@ export const metadata = { In this document, you’ll learn about shipping options and their rules. -## What’s a Shipping Option? +## What is a Shipping Option? -A shipping option is a way of shipping an item. Each fulfillment provider provides a set of shipping options. For example, a provider may provide a shipping option for express shipping and another for standard shipping. +A shipping option is a way of shipping an item. Each fulfillment provider offers a set of shipping options. For example, a provider may offer a shipping option for express shipping and another for standard shipping. -When the customer places their order, they choose a shipping option to be used to fulfill their items. +When the customer places an order, they choose a shipping option to fulfill their items. A shipping option is represented by the [ShippingOption data model](/references/fulfillment/models/ShippingOption). @@ -18,17 +18,17 @@ A shipping option is represented by the [ShippingOption data model](/references/ ## Service Zone Restrictions -A shipping option is restricted by a service zone, limiting the locations a shipping option be used in. +A shipping option is restricted by a service zone, which limits the locations where the shipping option can be used. -For example, a fulfillment provider may have a shipping option that can be used in the United States, and another in Canada. +For example, a fulfillment provider may have a shipping option that can be used in the United States and another in Canada. ![A diagram showcasing the relation between shipping options and service zones.](https://res.cloudinary.com/dza7lstvk/image/upload/v1712330831/Medusa%20Resources/shipping-option-service-zone_pobh6k.jpg) -Service zones can be more restrictive, such as restricting to certain cities or province codes. +Service zones can be more restrictive, such as limiting to certain cities or province codes. -The province code is always in lower-case and in [ISO 3166-2 format](https://en.wikipedia.org/wiki/ISO_3166-2). +The province code is always in lowercase and in [ISO 3166-2 format](https://en.wikipedia.org/wiki/ISO_3166-2). @@ -38,15 +38,15 @@ The province code is always in lower-case and in [ISO 3166-2 format](https://en. ## Shipping Option Rules -You can restrict shipping options by custom rules, such as the item’s weight or the customer’s group. +You can restrict shipping options by custom rules, such as the item’s weight or the customer group. -You can also restrict a shipping option's price based on specific conditions. For example, you can make a shipping option's price free based on the cart's total. Learn more in the Pricing Module's [Price Rules](../../pricing/price-rules/page.mdx#how-to-set-rules-on-a-price) guide. +You can also restrict a shipping option's price based on specific conditions. For example, you can make a shipping option's price free based on the cart total. Learn more in the Pricing Module's [Price Rules](../../pricing/price-rules/page.mdx#how-to-set-rules-on-a-price) guide. -These rules are represented by the [ShippingOptionRule data model](/references/fulfillment/models/ShippingOptionRule). Its properties define the custom rule: +These rules are represented by the [ShippingOptionRule data model](/references/fulfillment/models/ShippingOptionRule). Its properties define the custom rules: - `attribute`: The name of a property or table that the rule applies to. For example, `customer_group`. - `operator`: The operator used in the condition. For example: @@ -62,16 +62,18 @@ A shipping option can have multiple rules. For example, you can add rules to a s --- -## Shipping Profile and Types +## Shipping Profiles and Types -A shipping option belongs to a type. For example, a shipping option’s type may be `express`, while another `standard`. The type is represented by the [ShippingOptionType data model](/references/fulfillment/models/ShippingOptionType). +A shipping option belongs to a type and a profile. -A shipping option also belongs to a shipping profile, as each shipping profile defines the type of items to be shipped in a similar manner. +A shipping option type defines a group of shipping options with shared shipping characteristics. For example, a shipping option’s type may be `express`, while another may be `standard`. The type is represented by the [ShippingOptionType data model](/references/fulfillment/models/ShippingOptionType). + +A shipping profile defines a group of items (such as products) that are shipped in a similar manner. For example, the "Standard" shipping profile applies to all products, whereas the "Digital" shipping profile applies to digital products. Shipping profiles are represented by the [ShippingProfile data model](/references/fulfillment/models/ShippingProfile). --- ## data Property -When fulfilling an item, you might use a third-party fulfillment provider that requires additional custom data to be passed along from the checkout or order-creation process. +When fulfilling an item, you might use a third-party fulfillment provider that requires additional custom data to be passed along from the checkout or order creation process. -The `ShippingOption` data model has a `data` property. It's an object that stores custom data relevant later when creating and processing a fulfillment. +The `ShippingOption` data model has a `data` property. It's an object that stores custom data relevant for creating and processing a fulfillment later. diff --git a/www/apps/resources/app/commerce-modules/order/draft-orders/page.mdx b/www/apps/resources/app/commerce-modules/order/draft-orders/page.mdx new file mode 100644 index 0000000000..50f9690851 --- /dev/null +++ b/www/apps/resources/app/commerce-modules/order/draft-orders/page.mdx @@ -0,0 +1,112 @@ +import { Prerequisites } from "docs-ui" + +export const metadata = { + title: `Draft Orders Plugin`, +} + +# {metadata.title} + +In this guide, you'll learn about the Draft Orders Plugin and its features. + + + +The Draft Orders Plugin was initially only available to Cloud users during its early access phase. It is now available for all Medusa users. + + + +## What is the Draft Orders Plugin? + +The Draft Orders Plugin is a Medusa plugin that allows admin users to create and manage draft orders on behalf of customers from the Medusa Admin. + +The Medusa application already has the foundation to support draft orders, including data models and API routes. This plugin adds a user interface for managing draft orders in the Medusa Admin dashboard. + +The Draft Orders Plugin is especially useful for handling customer support scenarios or when a customer places an order offline, such as over the phone or in-store. + +### Features + +- [Create draft orders from the Medusa Admin.](!user-guide!/orders/draft-orders/create) +- [Manage items in a draft order, allowing admin users to add, update, or remove items](!user-guide!/orders/draft-orders/manage#manage-draft-orders-items). +- [Add shipping methods to draft orders.](!user-guide!/orders/draft-orders/manage#manage-draft-orders-shipping-methods). +- [Associate existing customers with draft orders.](!user-guide!/orders/draft-orders/manage#manage-draft-orders-customer-details). +- [Convert draft orders to regular orders.](!user-guide!/orders/draft-orders/manage#convert-draft-order-to-regular-order). + +--- + +## Install the Draft Orders Plugin + +The Draft Orders Plugin is available in all Medusa applications starting v2.10.0. + +For earlier versions, you can install the plugin manually. + += v2.4.0", + link: "!docs!/learn/installation" + } + ]} +/> + +To install the Draft Orders Plugin: + +1. Run the following command in your Medusa application's directory: + +```bash npm2yarn +npm install @medusajs/draft-order +``` + +2. Add the plugin to your `medusa-config.ts` file: + +```ts title="medusa-config.ts" +module.exports = defineConfig({ + // ... + plugins: [ + { + resolve: "@medusajs/draft-order", + options: {}, + }, + ], +}) +``` + +### Test the Draft Orders Plugin + +To test the Draft Orders Plugin, start the Medusa application with the following command: + +```bash npm2yarn +npm run dev +``` + +If you open the Medusa Admin at `localhost:9000/app` and log in, you'll find an "Orders -> Drafts" sidebar item. + +--- + +## Draft Orders User Guides + +To learn how to use the draft order features in the Medusa Admin, refer to the [Draft Orders](!user-guide!/orders/draft-orders) user guides. + +--- + +## How Draft Orders Work + +A draft order is stored in the database as a regular order. It is represented by the [Order data model](/references/order/models/Order) with the following properties: + +- `status`: Set to `draft` to indicate that the order is a draft. +- `is_draft_order`: Set to `true` to indicate that the order is a draft order. + +So, the same [order concepts](../concepts/page.mdx) apply to draft orders as well. + +### Editing Draft Orders + +Similar to regular orders, draft orders can be [edited](../edit/page.mdx), allowing admin users to add, update, or remove items, as well as add shipping methods. + +When the order edit is confirmed on the draft order, the changes are applied directly to the draft order and its [version](../order-versioning/page.mdx) is incremented. + +### Converting Draft Orders to Regular Orders + +Once a draft order is finalized and ready for processing, it can be converted to a regular order. This involves: + +- Changing its `status` property to `pending`. +- Changing its `is_draft_order` property to `false`. + +Admin users can then manage the order like any other regular order, including processing payments and fulfilling items. \ No newline at end of file diff --git a/www/apps/resources/app/commerce-modules/order/page.mdx b/www/apps/resources/app/commerce-modules/order/page.mdx index 87b8472df9..749cff9f8f 100644 --- a/www/apps/resources/app/commerce-modules/order/page.mdx +++ b/www/apps/resources/app/commerce-modules/order/page.mdx @@ -29,7 +29,7 @@ Learn more about why modules are isolated in [this documentation](!docs!/learn/f ## Order Features - [Order Management](./concepts/page.mdx): Store and manage your orders to retrieve, create, cancel, and perform other operations. -- Draft Orders: Allow merchants to create orders on behalf of their customers as draft orders that later are transformed to regular orders. +- [Draft Orders](./draft-orders/page.mdx): Allow merchants to create orders on behalf of their customers as draft orders that later are transformed to regular orders. - [Apply Promotion Adjustments](./promotion-adjustments/page.mdx): Apply promotions or discounts to the order's items and shipping methods by adding adjustment lines that are factored into their subtotals. - [Apply Tax Lines](./tax-lines/page.mdx): Apply tax lines to an order's line items and shipping methods. - [Returns](./return/page.mdx), [Edits](./edit/page.mdx), [Exchanges](./exchange/page.mdx), and [Claims](./claim/page.mdx): Make [changes](./order-change/page.mdx) to an order to edit, return, or exchange its items, with [version-based control](./order-versioning/page.mdx) over the order's timeline. diff --git a/www/apps/resources/components/MDXComponents/index.tsx b/www/apps/resources/components/MDXComponents/index.tsx index 8e4d9b55eb..e4f4a98df0 100644 --- a/www/apps/resources/components/MDXComponents/index.tsx +++ b/www/apps/resources/components/MDXComponents/index.tsx @@ -1,6 +1,5 @@ import type { MDXComponents as MDXComponentsType } from "mdx/types" import { - Link, MDXComponents as UiMdxComponents, TypeList, WorkflowDiagram, @@ -19,7 +18,6 @@ import { EventHeader } from "../EventHeader" const MDXComponents: MDXComponentsType = { ...UiMdxComponents, - a: Link, TypeList, WorkflowDiagram, CommerceModuleSections, diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs index c122fabf22..ea2fed0530 100644 --- a/www/apps/resources/generated/edit-dates.mjs +++ b/www/apps/resources/generated/edit-dates.mjs @@ -24,7 +24,7 @@ export const generatedEditDates = { "app/commerce-modules/fulfillment/fulfillment-provider/page.mdx": "2025-05-20T07:51:40.707Z", "app/commerce-modules/fulfillment/item-fulfillment/page.mdx": "2025-08-21T14:58:42.730Z", "app/commerce-modules/fulfillment/module-options/page.mdx": "2025-08-21T15:00:29.183Z", - "app/commerce-modules/fulfillment/shipping-option/page.mdx": "2025-04-24T09:21:52.540Z", + "app/commerce-modules/fulfillment/shipping-option/page.mdx": "2025-08-28T09:40:47.086Z", "app/commerce-modules/fulfillment/page.mdx": "2025-05-20T07:51:40.707Z", "app/commerce-modules/inventory/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/inventory/_events/page.mdx": "2024-07-03T19:27:13+03:00", @@ -41,7 +41,7 @@ export const generatedEditDates = { "app/commerce-modules/order/return/page.mdx": "2025-02-26T11:22:49.675Z", "app/commerce-modules/order/tax-lines/page.mdx": "2024-10-09T10:22:49.335Z", "app/commerce-modules/order/transactions/page.mdx": "2024-10-09T10:23:36.485Z", - "app/commerce-modules/order/page.mdx": "2025-04-17T08:48:15.314Z", + "app/commerce-modules/order/page.mdx": "2025-08-26T09:21:49.780Z", "app/commerce-modules/payment/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/payment/_events/page.mdx": "2024-07-03T19:27:13+03:00", "app/commerce-modules/payment/module-options/page.mdx": "2024-10-15T12:51:40.574Z", @@ -6568,5 +6568,6 @@ export const generatedEditDates = { "app/how-to-tutorials/tutorials/invoice-generator/page.mdx": "2025-08-04T00:00:00.000Z", "app/how-to-tutorials/tutorials/product-builder/page.mdx": "2025-08-14T11:21:18.409Z", "app/integrations/guides/payload/page.mdx": "2025-08-21T05:24:11.537Z", - "references/js_sdk/admin/Client/methods/js_sdk.admin.Client.getToken/page.mdx": "2025-08-14T12:59:55.678Z" + "references/js_sdk/admin/Client/methods/js_sdk.admin.Client.getToken/page.mdx": "2025-08-14T12:59:55.678Z", + "app/commerce-modules/order/draft-orders/page.mdx": "2025-08-26T09:21:49.780Z" } \ No newline at end of file diff --git a/www/apps/resources/generated/files-map.mjs b/www/apps/resources/generated/files-map.mjs index 65e53763cd..8fcafb1358 100644 --- a/www/apps/resources/generated/files-map.mjs +++ b/www/apps/resources/generated/files-map.mjs @@ -287,6 +287,10 @@ export const filesMap = [ "filePath": "/www/apps/resources/app/commerce-modules/order/concepts/page.mdx", "pathname": "/commerce-modules/order/concepts" }, + { + "filePath": "/www/apps/resources/app/commerce-modules/order/draft-orders/page.mdx", + "pathname": "/commerce-modules/order/draft-orders" + }, { "filePath": "/www/apps/resources/app/commerce-modules/order/edit/page.mdx", "pathname": "/commerce-modules/order/edit" diff --git a/www/apps/resources/generated/generated-commerce-modules-sidebar.mjs b/www/apps/resources/generated/generated-commerce-modules-sidebar.mjs index 3c4e890141..fbbcdfbb0f 100644 --- a/www/apps/resources/generated/generated-commerce-modules-sidebar.mjs +++ b/www/apps/resources/generated/generated-commerce-modules-sidebar.mjs @@ -3490,6 +3490,14 @@ const generatedgeneratedCommerceModulesSidebarSidebar = { "path": "https://docs.medusajs.com/user-guide/orders/fulfillments", "children": [] }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Manage Shipping Option Types", + "path": "https://docs.medusajs.com/user-guide/settings/shipping-option-types", + "children": [] + }, { "loaded": true, "isPathHref": true, @@ -6034,6 +6042,14 @@ const generatedgeneratedCommerceModulesSidebarSidebar = { "title": "Order Versioning", "children": [] }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "path": "/commerce-modules/order/draft-orders", + "title": "Draft Orders", + "children": [] + }, { "loaded": true, "isPathHref": true, @@ -6198,6 +6214,22 @@ const generatedgeneratedCommerceModulesSidebarSidebar = { "sort_sidebar": "alphabetize", "description": "Learn how to utilize and manage Order features in the Medusa Admin dashboard.", "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Create Draft Order", + "path": "https://docs.medusajs.com/user-guide/orders/draft-orders/create", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Draft Orders", + "path": "https://docs.medusajs.com/user-guide/orders/draft-orders", + "children": [] + }, { "loaded": true, "isPathHref": true, @@ -6206,6 +6238,14 @@ const generatedgeneratedCommerceModulesSidebarSidebar = { "path": "https://docs.medusajs.com/user-guide/orders/edit", "children": [] }, + { + "loaded": true, + "isPathHref": true, + "type": "ref", + "title": "Manage Draft Order", + "path": "https://docs.medusajs.com/user-guide/orders/draft-orders/manage", + "children": [] + }, { "loaded": true, "isPathHref": true, diff --git a/www/apps/resources/sidebars/order-module.mjs b/www/apps/resources/sidebars/order-module.mjs index ac3c053228..9508591aeb 100644 --- a/www/apps/resources/sidebars/order-module.mjs +++ b/www/apps/resources/sidebars/order-module.mjs @@ -42,6 +42,11 @@ export const orderSidebar = [ path: "/commerce-modules/order/order-versioning", title: "Order Versioning", }, + { + type: "link", + path: "/commerce-modules/order/draft-orders", + title: "Draft Orders", + }, { type: "link", path: "/commerce-modules/order/return", diff --git a/www/apps/ui/components/MDXComponents/index.tsx b/www/apps/ui/components/MDXComponents/index.tsx index 8dd8409eb5..d40f6c616b 100644 --- a/www/apps/ui/components/MDXComponents/index.tsx +++ b/www/apps/ui/components/MDXComponents/index.tsx @@ -1,6 +1,5 @@ import type { MDXComponents as MDXComponentsType } from "mdx/types" import { - Link, MDXComponents as UiMdxComponents, InlineThemeImage, InlineIcon, @@ -8,7 +7,6 @@ import { const MDXComponents: MDXComponentsType = { ...UiMdxComponents, - a: Link, InlineThemeImage, InlineIcon, } diff --git a/www/apps/user-guide/app/orders/draft-orders/create/page.mdx b/www/apps/user-guide/app/orders/draft-orders/create/page.mdx new file mode 100644 index 0000000000..19c9765db8 --- /dev/null +++ b/www/apps/user-guide/app/orders/draft-orders/create/page.mdx @@ -0,0 +1,62 @@ +--- +sidebar_position: 9 +sidebar_label: "Create Draft Order" +tags: + - user guide + - order +products: + - order +--- + +export const metadata = { + title: `Create Draft Orders in Medusa Admin`, +} + +# {metadata.title} + +In this guide, you'll learn how to create draft orders in the Medusa Admin. + + + +If you're using a version earlier than v2.10.0, you must [install the Draft Orders Plugin manually](!resources!/commerce-modules/order/draft-orders). Your technical team should handle the plugin installation. + + + +## When to Create a Draft Order + +You should create a draft order in the following scenarios: + +- When handling customer support requests that require creating an order on behalf of the customer. +- When processing orders that are taken offline, such as over the phone or in-store. +- When a customer wants to place an order but needs to finalize details later. + +You can create the draft order and convert it to a regular order once it is ready for processing. + +--- + +## Create a Draft Order + +To create a draft order: + +1. Go to Orders -> Drafts. +2. Click on the Create button at the top right. +3. In the form that opens, enter the following information: + - **Region**: Choose the region for the draft order. This determines the currency and tax rules applied to the order. + - **Sales Channel**: Select the sales channel for the draft order. This defines where the order is being placed, affects which inventory items are available, and determines which shipping options are applicable to the order. + - **Customer** (optional): Select an existing customer that the draft order belongs to. You can also set the customer at a later point or not set it at all. + - **Email**: Set the customer's email address. The customer may receive order updates at this email. + - **Shipping Address**: Enter the shipping address details for the draft order, or select an existing address if the customer is set. + - **Billing Address**: Either set the billing address to be the same as the shipping address or enter a different billing address. +4. Once you're done, click the Save button. + +The draft order will be created, and you will be redirected to the draft order's details page. + +![Draft order form](https://res.cloudinary.com/dza7lstvk/image/upload/v1756194728/User%20Guide/CleanShot_2025-08-26_at_10.51.58_2x_imrw09.png) + +--- + +## Next Steps: Manage Items and Shipping Methods + +After creating the draft order, you can add items to the order and manage its shipping methods. + +Learn how to do that in the [Manage Draft Order Details](../manage/page.mdx) guide. \ No newline at end of file diff --git a/www/apps/user-guide/app/orders/draft-orders/manage/page.mdx b/www/apps/user-guide/app/orders/draft-orders/manage/page.mdx new file mode 100644 index 0000000000..4af2b31649 --- /dev/null +++ b/www/apps/user-guide/app/orders/draft-orders/manage/page.mdx @@ -0,0 +1,270 @@ +--- +sidebar_position: 9 +sidebar_label: "Manage Draft Order" +tags: + - user guide + - order +products: + - order +--- + +import { + ArrowUpRightOnBox, + EllipsisHorizontal, + Plus, + PencilSquare, + XMark +} from "@medusajs/icons" + +export const metadata = { + title: `Manage Draft Order Details in Medusa Admin`, +} + +# {metadata.title} + +In this guide, you'll learn how to manage draft order details in the Medusa Admin. + + + +If you're using a version earlier than v2.10.0, you must [install the Draft Orders Plugin manually](!resources!/commerce-modules/order/draft-orders). Your technical team should handle the plugin installation. + + + +## View Draft Order Details + +To view the details of a draft order: + +1. Go to Orders -> Drafts. +2. Click on the draft order you want to view. + +This will open the draft order's details page, which is divided into several sections. + +### Summary Section + +The Summary section includes a summary of the items the customer purchased, as well as totals related to taxes, shipping, and more. Use this section to get a quick overview of the draft order, [convert it to a regular order](#convert-draft-order-to-regular-order), or [manage its items](#manage-draft-orders-items). + +![Order Summary](https://res.cloudinary.com/dza7lstvk/image/upload/v1756195258/User%20Guide/CleanShot_2025-08-26_at_11.00.44_2x_pay32p.png) + +### Customer Section + +The Customer section shows the customer’s details, including their contact information and shipping address. Use this section to view and [edit the customer’s details pertaining to the order](#manage-draft-orders-customer-details). + +![Customer Section](https://res.cloudinary.com/dza7lstvk/image/upload/v1756196430/User%20Guide/CleanShot_2025-08-26_at_11.03.51_2x_snez5u.png) + +### Activity Section + +The Activity section of the draft order details page shows a summary of the changes made to the draft order. That includes updates to items and shipping methods. + +![Activity Section](https://res.cloudinary.com/dza7lstvk/image/upload/v1756196547/User%20Guide/CleanShot_2025-08-26_at_11.21.53_2x_m2wxe8.png) + +### Shipping Section + +The Shipping section shows the draft order's shipping details, including the shipping methods chosen for each shipping profile associated with the draft order's items. Use this section to view and [manage the shipping methods for the draft order](#manage-draft-orders-shipping-methods). + +![Shipping Section](https://res.cloudinary.com/dza7lstvk/image/upload/v1756196678/User%20Guide/CleanShot_2025-08-26_at_11.24.26_2x_vbv6gs.png) + +## Metadata Section + +The Metadata section allows you to view and [manage custom metadata associated with the draft order](#manage-draft-orders-metadata). Metadata can be useful for storing additional information about the order that is not covered by the default fields. + +### JSON Section + +The JSON section is useful for developers to view the raw order data in JSON format. Developers can use this section to debug and troubleshoot issues related to the order. + +To view the JSON structure, click the icon. + +--- + +## Edit Draft Order's Sales Channel + +To edit the sales channel of a draft order: + +1. Go to the draft order's details page. +2. In the first section displaying the order's number and region, click the icon at the right. +3. Select "Edit sales channel" from the dropdown menu. +4. In the side window that opens, select the new sales channel from the dropdown. +5. Click the Save button. + +![Edit Sales Channel form](https://res.cloudinary.com/dza7lstvk/image/upload/v1756196930/User%20Guide/CleanShot_2025-08-26_at_11.28.40_2x_mptkto.png) + +--- + +## Manage Draft Order's Items + +To add, edit, or remove items from a draft order: + +1. Go to the draft order's details page. +2. In the Summary section, click on the icon at the right. +3. Select "Edit items" from the dropdown menu. +4. In the form that opens: + - To add an item, click the button at the right of the "Items" section. From the dropdown, you can either choose: + - **Add items**: Add existing product variants to the draft order. This will open the product variant selection window. + - **Add custom item**: Add a custom item that's only available in this draft order. This will open a form to enter the item's title, price, and quantity. + - To edit an existing item, click the button in the item's row. This will allow you to change the item's quantity and price. + - To remove an item, click the button in the item's row, then set the item's quantity to zero. This will remove the item from the draft order. +5. Once you're done, click the "Save" button. + +The items in the Summary section will be updated accordingly. + +![Draft Order Items Form](https://res.cloudinary.com/dza7lstvk/image/upload/v1756197277/User%20Guide/CleanShot_2025-08-26_at_11.34.21_2x_zkngzx.png) + +--- + +## Manage Draft Order's Promotions + +To add or remove promotions applied to the draft order: + +1. Go to the draft order's details page. +2. In the Summary section, click on the icon at the right. +3. Select "Edit promotions" from the dropdown menu. +4. In the side window that opens: + - To add a promotion, choose it from the dropdown menu. + - To remove a promotion, click the icon next to the promotion you want to remove. +5. Once you're done, click the "Save" button. + +The Summary section will be updated accordingly with the discount changes. + +![Draft Order Promotions Form](https://res.cloudinary.com/dza7lstvk/image/upload/v1756197906/User%20Guide/CleanShot_2025-08-26_at_11.44.08_2x_ekecht.png) + +--- + +## Manage Draft Order's Shipping Methods + +To manage the shipping methods of a draft order: + +1. Go to the draft order's details page. +2. In the Shipping section, click on the "Add shipping" or "Edit shipping" button. +3. In the form that opens, you can perform the following steps to manage the shipping methods of every shipping profile: + - To add a shipping option, click the "Add shipping option" button for the shipping profile. + - In the form that opens, set the following information: + - **Location**: Choose the location to ship the items from. This will affect the available shipping options. + - **Shipping option**: After choosing a location, select a shipping option from that location that will be used to ship the items. + - **Custom amount**: (optional) If you want to override the price of the shipping option, you can set a custom amount. + - **Items to ship**: This section only shows you which items this shipping option ships. You cannot edit this section. + - Once you're done, click the "Add" button. + - To edit the shipping option of a shipping profile, click the icon at the right of the shipping option and choose "Edit shipping option" from the dropdown. You can edit the location, shipping option, and custom amount. + - To remove a shipping option from the draft order, click the icon at the right of the shipping option and choose "Remove shipping option" from the dropdown. +4. Once you're done managing the shipping methods, click the "Save" button. + +The Shipping section will be updated accordingly. + +![Draft Order Shipping Form](https://res.cloudinary.com/dza7lstvk/image/upload/v1756197813/User%20Guide/CleanShot_2025-08-26_at_11.43.20_2x_hkhuib.png) + +--- + +## Manage Draft Order's Customer Details + +### Transfer Draft Order to Another Customer + +If you've associated the draft order with a customer in your store, you can transfer the draft order to another existing customer. + +To transfer the draft order to another customer: + +1. Go to the draft order's details page. +2. In the Customer section, click on the icon at the right. +3. Choose "Transfer ownership" from the dropdown menu. +4. In the side window that opens, choose the customer to transfer the draft order to in the "New customer" field. +5. Once you're done, click the "Save" button. + +![Transfer ownership form for draft order](https://res.cloudinary.com/dza7lstvk/image/upload/v1756198151/User%20Guide/CleanShot_2025-08-26_at_11.48.44_2x_jztl1a.png) + +### Edit Email + +The draft order has an associated email address that is used to send order updates to the customer. + +To edit the email address associated with a draft order: + +1. Go to the draft order's details page. +2. In the Customer section, click on the icon at the right. +3. Choose "Edit email" from the dropdown menu. +4. In the side window that opens, enter the new email address in the "Email" field. +5. Once you're done, click the "Save" button. + +Updates related to the order will be sent to the new email address. + +![Edit email in draft order form](https://res.cloudinary.com/dza7lstvk/image/upload/v1756198151/User%20Guide/CleanShot_2025-08-26_at_11.48.33_2x_b5in62.png) + +--- + +## Edit Draft Order's Shipping Address + +To edit the shipping address used for a draft order: + +1. Go to the draft order's details page. +2. In the Customer section, click on the icon at the right. +3. Choose "Edit shipping address" from the dropdown menu. +4. In the side window that opens, you can update the shipping address details, including the country, first and last names, company, address lines, city, state, postal code, and phone number. +5. Once you're done, click the "Save" button. + +![Edit shipping address in draft order form](https://res.cloudinary.com/dza7lstvk/image/upload/v1756198303/User%20Guide/CleanShot_2025-08-26_at_11.51.29_2x_iu8pfb.png) + +--- + +## Edit Draft Order's Billing Address + +To edit the billing address used for a draft order: + +1. Go to the draft order's details page. +2. In the Customer section, click on the icon at the right. +3. Choose "Edit billing address" from the dropdown menu. +4. In the side window that opens, you can update the billing address details, including the country, first and last names, company, address lines, city, state, postal code, and phone number. +5. Once you're done, click the "Save" button. + +![Edit billing address in draft order form](https://res.cloudinary.com/dza7lstvk/image/upload/v1756198303/User%20Guide/CleanShot_2025-08-26_at_11.51.29_2x_iu8pfb.png) + +--- + +## Manage Draft Order's Metadata + +Metadata is custom data that can be associated with the draft order in key-value pairs. This is usually used by developers for custom integrations or to store additional information about the draft order. + +When the draft order is converted to an order, the metadata will be carried over to the order. + +To edit the draft order's metadata: + +1. Click the icon at the right of the "Metadata" section. +2. In the side window that opens: + - Manage the key-value pairs in the table. + - To add a new row of key-value pairs before or after a row: + - Hover over the row and click the icon at its right. + - Choose "Insert row above" or "Insert row below" from the dropdown. + - To delete a row of key-value pairs: + - Hover over the row and click the icon at its right. + - Choose "Delete row" from the dropdown. +3. Once you're done, click the Save button. + +--- + +## Convert Draft Order to Regular Order + +Once you're done managing the draft order and it is ready to be processed, you can convert it to a regular order. + + + +This action can't be undone. If you convert the draft order to a regular order by mistake, you can [cancel the order](../../manage/page.mdx#cancel-an-order). + + + +To convert the draft order to a regular order: + +1. Go to the draft order's details page. +2. In the Summary section of the draft order's details page, click the "Convert to order" button. +3. Confirm converting the draft order by clicking the "Confirm" button in the pop-up. + +You'll then be redirected to the order's details page. Learn more about it in the [Manage Orders](../../manage/page.mdx) guide. + +--- + +## Delete Draft Order + + + +Deleting a draft order is irreversible. + + + +To delete a draft order: + +1. Go to the draft order's details page. +2. In the first section displaying the order's number and region, click the icon at the right. +3. Choose "Delete draft order" from the dropdown menu. \ No newline at end of file diff --git a/www/apps/user-guide/app/orders/draft-orders/page.mdx b/www/apps/user-guide/app/orders/draft-orders/page.mdx new file mode 100644 index 0000000000..321c0e37fe --- /dev/null +++ b/www/apps/user-guide/app/orders/draft-orders/page.mdx @@ -0,0 +1,44 @@ +--- +sidebar_position: 9 +sidebar_label: "Draft Orders" +tags: + - user guide + - order +products: + - order +--- + +export const metadata = { + title: `Draft Orders in Medusa Admin`, +} + +# {metadata.title} + + + +If you're using a version earlier than v2.10.0, you must [install the Draft Orders Plugin manually](!resources!/commerce-modules/order/draft-orders). Your technical team should handle the plugin installation. + + + +The Draft Orders section of the Medusa Admin allows you to create and manage draft orders on behalf of customers. + +Draft orders are useful for handling customer support scenarios or when a customer places an order offline, such as over the phone or in-store. + +You can view the list of available draft orders in your commerce store by clicking on Orders -> Drafts from the sidebar menu. + +![Draft Orders List](https://res.cloudinary.com/dza7lstvk/image/upload/v1756190283/User%20Guide/CleanShot_2025-08-26_at_09.32.13_2x_tmueho.png) + +In the list, you can see draft order details such as the ID, date, customer, sales channel, and region. You can also search, filter, and sort the orders to find the specific draft order you are looking for. + + + +Find tips for using lists effectively in [this guide](../../tips/lists/page.mdx). + + + +--- + +## Manage Draft Orders + +- [Create Draft Orders](./create/page.mdx) +- [Manage Draft Orders](./manage/page.mdx) \ No newline at end of file diff --git a/www/apps/user-guide/app/orders/page.mdx b/www/apps/user-guide/app/orders/page.mdx index 0b80abd902..7a1474040c 100644 --- a/www/apps/user-guide/app/orders/page.mdx +++ b/www/apps/user-guide/app/orders/page.mdx @@ -35,7 +35,8 @@ Find tips to use lists effectively in [this guide](../tips/lists/page.mdx). - [Manage Order Details](./manage/page.mdx) - [Manage Order’s Payment](./payments/page.mdx) - [Manage Order’s Fulfillment](./fulfillments/page.mdx) +- [Edit Order Items](./edit/page.mdx) - [Manage Order Returns](./returns/page.mdx) - [Manage Order Claims](./claims/page.mdx) - [Manage Order Exchanges](./exchanges/page.mdx) - \ No newline at end of file +- [Manage Draft Orders](./draft-orders/page.mdx) \ No newline at end of file diff --git a/www/apps/user-guide/app/orders/payments/page.mdx b/www/apps/user-guide/app/orders/payments/page.mdx index 0d3ad11658..72f05806de 100644 --- a/www/apps/user-guide/app/orders/payments/page.mdx +++ b/www/apps/user-guide/app/orders/payments/page.mdx @@ -91,22 +91,9 @@ To capture an order’s payment: --- -## Handling Outstanding Amounts - -After making changes to an order, such as [editing its items](../edit/page.mdx) or [creating an exchange](../exchanges/page.mdx), there may be outstanding amounts (to be captured from the customer or returned) that are in the Summary section. - -![Outstanding amount in Summary](https://res.cloudinary.com/dza7lstvk/image/upload/v1739801684/User%20Guide/Screenshot_2025-02-17_at_4.14.05_PM_qmw7gr.png) - -If the outstanding amount is negative, it means you owe the customer a [refund](#refund-payment). - -Otherwise, a positive outstanding amount means there are additional payments required from the customer. You can handle it by either: - -1. [Mark the order as paid manually](#mark-outstanding-amount-as-paid); -2. Or [copy a payment link](#copy-payment-link-for-additional-payment). - ## Refund Payment -If you've made changes to an order, such as return or exchange items, you can refund a previously-captured payment if there's an outstanding amount. +If you've made changes to an order, such as return or exchange items, that resulted in a negative outstanding amount, you can refund a previously-captured payment. Refunding the payment triggers its processing with the chosen payment provider, such as Stripe. @@ -116,7 +103,7 @@ Refunding payments is irreversible. -To refund an order’s outstanding amount: +To refund an order’s negative outstanding amount: 1. Open the order's details page. 2. Scroll to the Payment section. @@ -132,6 +119,21 @@ Once the payment is refunded, the customer will receive a notification about the ![Refund Payment Form](https://res.cloudinary.com/dza7lstvk/image/upload/v1739550855/User%20Guide/Screenshot_2025-02-14_at_6.34.01_PM_l9evmh.png) +--- + +## Handling Positive Outstanding Amounts + +An order may have a positive outstanding amount either after making changes to it, or if it was created as a [draft order](../draft-orders/page.mdx). + +A positive outstanding amount indicates that the customer needs to pay an additional amount to complete the order. + +![Outstanding amount in Summary](https://res.cloudinary.com/dza7lstvk/image/upload/v1739801684/User%20Guide/Screenshot_2025-02-17_at_4.14.05_PM_qmw7gr.png) + +You can handle it by either: + +1. [Marking the order as paid manually](#mark-outstanding-amount-as-paid); +2. Or [copying a payment link](#copy-payment-link-for-additional-payment). + ### Mark Outstanding Amount as Paid By marking a positive outstanding amount as paid, you're capturing the payment without processing it through the associated payment provider. Instead, you handle capturing the payment outside of Medusa. diff --git a/www/apps/user-guide/app/promotions/campaigns/page.mdx b/www/apps/user-guide/app/promotions/campaigns/page.mdx index c3327a7601..f5d6b0afa6 100644 --- a/www/apps/user-guide/app/promotions/campaigns/page.mdx +++ b/www/apps/user-guide/app/promotions/campaigns/page.mdx @@ -53,7 +53,7 @@ To create a campaign: - Optionally set an end date in the "End date" field. Promotions in this campaign are expired after this date. - You can set a campaign budget of the following types: - **Usage**: How many times the promotions in the campaign can be used. Once the number of times exceed the limit, the campaign and its promotions expire. - - **Spend**: The total amount that can be discounted by the promotions in the campaign. Once the total amount discounted exceeds the limit, the campaign and its promotions expire. This is not applicable to "Buy X Get Y" promotions. + - **Spend**: The total amount that can be discounted by the promotions in the campaign. Once the total amount discounted exceeds the limit, the campaign and its promotions expire. This is not applicable to "Buy X Get Y" or "Free Shipping" promotions. - If you chose the **Spend** type, select the currency of the limit in the "Currency" field. - When adding promotions to the campaign later, promotions that discount a fixed amount can only be added if the currency matches the campaign budget's currency. - In the Limit field, you can set a campaign budget limit based on the type you chose. diff --git a/www/apps/user-guide/app/promotions/create/page.mdx b/www/apps/user-guide/app/promotions/create/page.mdx index 268b89c515..43fe08528f 100644 --- a/www/apps/user-guide/app/promotions/create/page.mdx +++ b/www/apps/user-guide/app/promotions/create/page.mdx @@ -32,10 +32,11 @@ In the first step of creating a promotion, you need to specify the type of the p 3. **Percentage off product**: Discount a percentage off the amount of products matching custom and dynamic conditions. 4. **Percentage off order**: Discount a percentage off an order's total. 5. **Buy X Get Y**: When the customer buys X quantity of a product, they get Y quantity for free. For example, buy 3 shirts get 1 for free. +6. **Free Shipping**: Offer free shipping on orders that meet certain conditions. Once you've selected the type, click on the Continue button. -![Create Promotion Form First Step](https://res.cloudinary.com/dza7lstvk/image/upload/v1739894084/User%20Guide/Screenshot_2025-02-18_at_5.54.25_PM_irp2ax.png) +![Create Promotion Form First Step](https://res.cloudinary.com/dza7lstvk/image/upload/v1756368023/User%20Guide/CleanShot_2025-08-28_at_11.00.07_2x_nptdyk.png) --- @@ -63,12 +64,11 @@ If you chose the "Amount off Products" promotion type in the first section, fill - **Sales Channel**: The customer must be / must not be placing the order from the specified sales channels. - Select the operator of the condition: - **In**: The customer's value for the chosen attribute must belong to the specified values. - - **Equals**: The customer's value for the chosen attribute must be the same as the specified value. - **Not In**: The customer's value for the chosen attribute must not belong to the specified values. - Select the value of the attribute. - For example, if you want to allow only customers belonging to the VIP group to use this promotion: - Set the Attribute to Customer Group. - - Set the Operator to In or Equals. + - Set the Operator to In. - Set the Value to the VIP customer group. ![Who can use this section](https://res.cloudinary.com/dza7lstvk/image/upload/v1739898104/User%20Guide/Screenshot_2025-02-18_at_7.01.14_PM_wvskll.png) @@ -84,12 +84,11 @@ If you chose the "Amount off Products" promotion type in the first section, fill - **Product Tag**: The promotion applies / doesn't apply to the products belonging to the specified tag(s). - Select the operator of the condition: - **In**: The value of the item in the cart must belong to the specified values. - - **Equals**: The value of the item in the cart must equal the specified values. - **Not In**: The value of the item in the cart must not belong to the specified values. - Select the value of the attribute. - For example, if you want to apply the promotion on products in the "Shirts" category: - Set the Attribute to Product Category. - - Set the Operator to In or Equals. + - Set the Operator to In. - Set the Value to the Shirts product category. 9. Once you're done, click Next and move on to the [next step](#step-3-campaign). @@ -115,12 +114,11 @@ If you chose the "Amount off Order" promotion type in the first section, fill ou - **Sales Channel**: The customer must be / must not be placing the order from the specified sales channels. - Select the operator of the condition: - **In**: The customer's value for the chosen attribute must belong to the specified values. - - **Equals**: The customer's value for the chosen attribute must be the same as the specified value. - **Not In**: The customer's value for the chosen attribute must not belong to the specified values. - Select the value of the attribute. - For example, if you want to allow only customers belonging to the VIP group to use this promotion: - Set the Attribute to Customer Group. - - Set the Operator to In or Equals. + - Set the Operator to In. - Set the Value to the VIP customer group. ![Who can use this code form](https://res.cloudinary.com/dza7lstvk/image/upload/v1739898239/User%20Guide/Screenshot_2025-02-18_at_7.03.46_PM_iawubi.png) @@ -147,12 +145,11 @@ If you chose the "Percentage off Product" promotion type in the first section, f - **Currency Code**: The currency code that the customer must / must not be placing the order in. - Select the operator of the condition: - **In**: The customer's value for the chosen attribute must belong to the specified values. - - **Equals**: The customer's value for the chosen attribute must be the same as the specified value. - **Not In**: The customer's value for the chosen attribute must not belong to the specified values. - Select the value of the attribute. - For example, if you want to allow only customers belonging to the VIP group to use this promotion: - Set the Attribute to Customer Group. - - Set the Operator to In or Equals. + - Set the Operator to In. - Set the Value to the VIP customer group. ![Who can use this code section](https://res.cloudinary.com/dza7lstvk/image/upload/v1739898340/User%20Guide/Screenshot_2025-02-18_at_7.05.27_PM_yircnf.png) @@ -168,12 +165,11 @@ If you chose the "Percentage off Product" promotion type in the first section, f - **Product Tag**: The promotion applies / doesn't apply to the products belonging to the specified tag(s). - Select the operator of the condition: - **In**: The value of the item in the cart must belong to the specified values. - - **Equals**: The value of the item in the cart must equal the specified values. - **Not In**: The value of the item in the cart must not belong to the specified values. - Select the value of the attribute. - For example, if you want to apply the promotion on products in the "Shirts" category: - Set the Attribute to Product Category. - - Set the Operator to In or Equals. + - Set the Operator to In. - Set the Value to the Shirts product category. 9. Once you're done, click Next and move on to the [next step](#step-3-campaign). @@ -198,12 +194,11 @@ If you chose the "Percentage off Order" promotion type in the first section, fil - **Currency Code**: The currency code that the customer must / must not be placing the order in. - Select the operator of the condition: - **In**: The customer's value for the chosen attribute must belong to the specified values. - - **Equals**: The customer's value for the chosen attribute must be the same as the specified value. - **Not In**: The customer's value for the chosen attribute must not belong to the specified values. - Select the value of the attribute. - For example, if you want to allow only customers belonging to the VIP group to use this promotion: - Set the Attribute to Customer Group. - - Set the Operator to In or Equals. + - Set the Operator to In. - Set the Value to the VIP customer group. ![Who can use this code section](https://res.cloudinary.com/dza7lstvk/image/upload/v1739898478/User%20Guide/Screenshot_2025-02-18_at_7.07.46_PM_eriyxm.png) @@ -219,7 +214,7 @@ If you chose the "Buy X Get Y" promotion type in the first section, fill out the - **Promotion code**: The customer must enter the promotion's code during checkout for the promotion to apply. - **Automatic**: The promotion is applied automatically if the customer's cart matches the promotion's conditions. 2. For the Status, choose Draft if you don't want to allow customers to use the promotion yet, or Active otherwise. -3. In the Code field, enter the promotion's code. It must be a code that doesn't have spaces. For example, `50OFF`. +3. In the Code field, enter the promotion's code. It must be a code that doesn't have spaces. For example, `BUY3GET1`. 4. In the "Who can use this code?" section, you'll specify the conditions that must be met for the promotion to be applicable for a customer's cart. To add a condition, click on the "Add condition" button. For each condition: - Select the attribute in the first field. This is the attribute that the condition applies to. It can be: - **Customer Group**: The customer must belong / not belong to the specified customer group(s). @@ -229,12 +224,11 @@ If you chose the "Buy X Get Y" promotion type in the first section, fill out the - **Currency Code**: The currency code that the customer must / must not be placing the order in. - Select the operator of the condition: - **In**: The customer's value for the chosen attribute must belong to the specified values. - - **Equals**: The customer's value for the chosen attribute must be the same as the specified value. - **Not In**: The customer's value for the chosen attribute must not belong to the specified values. - Select the value of the attribute. - For example, if you want to allow only customers belonging to the VIP group to use this promotion: - Set the Attribute to Customer Group. - - Set the Operator to In or Equals. + - Set the Operator to In. - Set the Value to the VIP customer group. ![Who can use this code section](https://res.cloudinary.com/dza7lstvk/image/upload/v1739898542/User%20Guide/Screenshot_2025-02-18_at_7.08.45_PM_nh5iw4.png) @@ -250,16 +244,12 @@ If you chose the "Buy X Get Y" promotion type in the first section, fill out the - **Product Tag**: The promotion applies / doesn't apply to the products belonging to the specified tag(s). - Select the operator of the condition: - **In**: The value of the item in the cart must belong to the specified values. - - **Equals**: The value of the item in the cart must equal the specified values. - **Not In**: The value of the item in the cart must not belong to the specified values. - Select the value of the attribute. - For example, if you don't want the promotion to apply to products in the "Shirt" category: - Set the Attribute to Product Category. - Set the Operator to "Not In". - Set the Value to the "Shirt" category. - -![What needs to be in cart to unlock promotion section](https://res.cloudinary.com/dza7lstvk/image/upload/v1739898589/User%20Guide/Screenshot_2025-02-18_at_7.09.31_PM_xzj8ro.png) - 6. In the "What items will the promotion be applied to?" section, you'll specify the Buy Y part (for example, "get 1 free shirt"): - You must set the quantity of items that the customer gets out of the promotion. For example, for the "Buy 3 shirts get 1 for free", you set the quantity to one. - You must set the products tht the customer gets out of the promotion for free. @@ -271,7 +261,6 @@ If you chose the "Buy X Get Y" promotion type in the first section, fill out the - **Product Tag**: The promotion applies / doesn't apply to the products belonging to the specified tag(s). - Select the operator of the condition: - **In**: The value of the item in the cart must belong to the specified values. - - **Equals**: The value of the item in the cart must equal the specified values. - **Not In**: The value of the item in the cart must not belong to the specified values. - Select the value of the attribute. - For example, if you don't want the promotion to offer products in the "Shirt" category: @@ -280,7 +269,50 @@ If you chose the "Buy X Get Y" promotion type in the first section, fill out the - Set the Value to the "Shirt" category. 7. Once you're done, click Next and move on to the [next step](#step-3-campaign). -![What items will the promotion be applied to section](https://res.cloudinary.com/dza7lstvk/image/upload/v1739898642/User%20Guide/Screenshot_2025-02-18_at_7.10.28_PM_rl3dkp.png) +### f. Free Shipping + + + +Free shipping promotions were added in [Medusa v2.10.0](https://github.com/medusajs/medusa/releases/tag/v2.10.0). + + + +If you chose the "Free Shipping" promotion type in the first section, fill out the following in the Details step: + +1. For the Method, choose how you want the promotion to be applied: + - **Promotion code**: The customer must enter the promotion's code during checkout for the promotion to apply. + - **Automatic**: The promotion is applied automatically if the customer's cart matches the promotion's conditions. +2. For the Status, choose Draft if you don't want to allow customers to use the promotion yet, or Active otherwise. +3. In the Code field, enter the promotion's code. It must be a code that doesn't have spaces. For example, `FREESHIPPING`. +4. In the "Who can use this code?" section, you'll specify the conditions that must be met for the promotion to be applicable for a customer's cart. To add a condition, click on the "Add condition" button. For each condition: + - Select the attribute in the first field. This is the attribute that the condition applies to. It can be: + - **Customer Group**: The customer must belong / not belong to the specified customer group(s). + - **Region**: The customer's region must belong / not belong to the specified region(s). + - **Country**: The customer's country, which is determined through their shipping address, must belong / not belong to the specified countries. + - **Sales Channel**: The customer must / must not be placing the order from the specified sales channels. + - **Currency Code**: The currency code that the customer must / must not be placing the order in. + - Select the operator of the condition: + - **In**: The customer's value for the chosen attribute must belong to the specified values. + - **Not In**: The customer's value for the chosen attribute must not belong to the specified values. + - Select the value of the attribute. + - For example, if you want to allow only customers belonging to the VIP group to use this promotion: + - Set the Attribute to Customer Group. + - Set the Operator to In or Equals. + - Set the Value to the VIP customer group. +5. In the "What shipping methods will the promotion be applied to?" section, you'll specify the required conditions related to the cart's shipping method. To add a condition, click on the "Add condition" button. For each condition: + - Select the attribute in the first field. This is the attribute that the condition applies to. It can be: + - **Shipping Option Type**: The promotion applies / doesn't apply to shipping methods whose underlying shipping option is of the specified type(s). + - Select the operator of the condition: + - **In**: The value of the shipping method in the cart must belong to the specified values. + - **Not In**: The value of the shipping method in the cart must not belong to the specified values. + - Select the value of the attribute. + - For example, if you want to apply the promotion on shipping methods in the "Express" shipping option type: + - Set the Attribute to Shipping Option Type. + - Set the Operator to In. + - Set the Value to the "Express" shipping option type. +6. Once you're done, click Next and move on to the [next step](#step-3-campaign). + +![What shipping methods will the promotion be applied to section](https://res.cloudinary.com/dza7lstvk/image/upload/v1756368838/User%20Guide/CleanShot_2025-08-28_at_11.13.29_2x_rdcivr.png) --- @@ -306,10 +338,8 @@ If you selected a new campaign, you need to fill out the following to create a c 4. Under the campaign budget, you can add limits that automatically expires the campaign, which means promotions in that campaign can't be used anymore. - For Type, you can choose to set the budget either based on: - **Usage**: How many times the promotions in the campaign can be used. Once the number of times exceed the limit, the campaign and its promotions expire. - - **Spend**: The total amount that can be discounted by the promotions in the campaign. Once the total amount discounted exceeds the limit, the campaign and its promotions expire. This is disabled if you select the "Buy X Get Y" promotion type. + - **Spend**: The total amount that can be discounted by the promotions in the campaign. Once the total amount discounted exceeds the limit, the campaign and its promotions expire. This is disabled if you select the "Buy X Get Y" or "Free Shipping" promotion types. - In the Limit field, enter the budget limit based on the chosen type. 5. Once you're done, click on the Save button. -![Create campaign form](https://res.cloudinary.com/dza7lstvk/image/upload/v1739897668/User%20Guide/Screenshot_2025-02-18_at_6.53.46_PM_gfhp9l.png) - You can now [manage the promotion](../manage/page.mdx) you created. \ No newline at end of file diff --git a/www/apps/user-guide/app/promotions/manage/page.mdx b/www/apps/user-guide/app/promotions/manage/page.mdx index 8456e9d045..2ac51e8707 100644 --- a/www/apps/user-guide/app/promotions/manage/page.mdx +++ b/www/apps/user-guide/app/promotions/manage/page.mdx @@ -77,8 +77,8 @@ To edit a promotion's general details: 4. In the side window that opens: - You can change the promotion's status to either **Draft**, **Active**, or **Inactive**. Inactive is useful if the promotion was originally active but you want to expire it. - You can edit the promotion's method (whether it's applied manually or automatically) and code. - - You can change how the amount is discounted, either by a fixed amount or a percentage. You can also change the discounted amount. - - You can change how the promotion is applied, either on every applicable item or across all items in the cart. + - Based on the promotion's type, you can change how the amount is discounted, either by a fixed amount or a percentage. You can also change the discounted amount. + - Based on the promotion's type, you can change how the promotion is applied, either on every applicable item or across all items in the cart. - For example, if your promotion discounts an amount from applicable products in a cart, choosing **Each** applies the discount on each applicable product, whereas **Across** applies the discount across all applicable products. 5. Once you're done, click the Save button. @@ -102,12 +102,11 @@ To edit who can use the promotion: - **Currency Code**: The currency code that the customer must / must not be placing the order in. - Select the operator of the condition: - **In**: The customer's value for the chosen attribute must belong to the specified values. - - **Equals**: The customer's value for the chosen attribute must be the same as the specified value. - **Not In**: The customer's value for the chosen attribute must not belong to the specified values. - Select the value of the attribute. - For example, if you want to allow only customers belonging to the B2B group to use this promotion: - Set the Attribute to Customer Group. - - Set the Operator to In or Equals. + - Set the Operator to In. - Set the Value to the B2B customer group. 5. Once you're done, click the Save button. @@ -187,6 +186,34 @@ To edit the "Buy X" part of the promotion: --- +## Edit the Shipping Methods the Promotion Applies To + + + +Free shipping promotions were added in [Medusa v2.10.0](https://github.com/medusajs/medusa/releases/tag/v2.10.0). + + + +For "Free Shipping" promotions, you can edit the required conditions for the promotion to be applicable on a cart's shipping methods. + +To edit the shipping methods the promotion applies to: + +1. Go to the promotion's details page. +2. Click the icon at the top right of the "What shipping methods will the promotion be applied to?" section. +3. Choose Edit from the dropdown. +4. In the side window, you can edit the required conditions for the promotion to be applicable on a cart's shipping methods. You can also add new conditions by clicking the "Add condition" button. For each condition: + - Select the attribute in the first field. This is the attribute that the condition applies to. It can be: + - **Shipping Option Type**: The promotion applies / doesn't apply to shipping methods whose underlying shipping option is of the specified type(s). + - Select the operator of the condition: + - **In**: The value of the shipping method in the cart must belong to the specified values. + - **Not In**: The value of the shipping method in the cart must not belong to the specified values. + - Select the value of the attribute. +5. Once you're done, click the Save button. + +![Edit shipping methods condition form](https://res.cloudinary.com/dza7lstvk/image/upload/v1756370174/User%20Guide/CleanShot_2025-08-28_at_11.35.57_2x_fjvmwe.png) + +--- + ## Add Promotion to Campaign If you created a promotion without a campaign, you can add it to an existing campaign from its details page. diff --git a/www/apps/user-guide/app/settings/locations-and-shipping/locations/page.mdx b/www/apps/user-guide/app/settings/locations-and-shipping/locations/page.mdx index fd3e09efa9..aa2c00551b 100644 --- a/www/apps/user-guide/app/settings/locations-and-shipping/locations/page.mdx +++ b/www/apps/user-guide/app/settings/locations-and-shipping/locations/page.mdx @@ -125,14 +125,15 @@ To create a shipping option: - If you chose Fixed, you'll set the price in the next step of the form. - If you choose Calculated and the fulfillment provider you choose doesn't support calculated prices, the shipping option creation will fail. - In the Name field, enter a name for the shipping option. Customers will see this option during checkout. - - In the Shipping Profile field, choose the shipping profile that this option can be used for. Only products belonging to this shipping profile can be shipped with this shipping option. + - In the Shipping Profile field, choose the [shipping profile](../shipping-profiles/page.mdx) that this option can be used for. Only products belonging to this shipping profile can be shipped with this shipping option. + - In the Shipping Option Type field, choose the [shipping option type](../shipping-option-types/page.mdx) that this option belongs to. Shipping option types are useful to group similar shipping options together, allowing you to apply promotions at a group level. - In the Fulfillment Provider field, choose the fulfillment provider that will handle shipping orders using this option. - If you don't find the fulfillment provider you're looking for, make sure it's [added to the location](#manage-fulfillment-providers). - In the Fulfillment Option field, choose a fulfillment option from the fulfillment provider. For example, UPS may provide express or standard fulfillment options. - If you're unsure about which fulfillment option to choose, contact your technical team for assistance based on the integrated [fulfillment service](!resources!/commerce-modules/fulfillment/fulfillment-provider). - If you don't want this shipping option to be used by customers during checkout, disable the "Enable in store" toggle. This is useful if you're creating a shipping option that's only used internally. -![Create shipping option form step 1](https://res.cloudinary.com/dza7lstvk/image/upload/v1739982940/User%20Guide/Screenshot_2025-02-19_at_6.30.28_PM_cteij2.png) +![Create shipping option form step 1](https://res.cloudinary.com/dza7lstvk/image/upload/v1756372367/User%20Guide/CleanShot_2025-08-28_at_12.12.31_2x_pecprx.png) If you chose a "Calculated" price type, you can click the "Save" button to create the shipping option. Otherwise click Continue to proceed to the Prices step. @@ -235,10 +236,16 @@ To edit a shipping option's details: 1. Go to the location's details page. 2. In the "Pickup" or "Shipping" sections, find the shipping option and click on the icon at its right. 3. Choose "Edit option" from the dropdown. -4. In the side window that opens, you can edit the shipping option's price type, name, shipping profile, and whether it's enabled in store for customers to use. +4. In the side window that opens, you can edit the shipping option's price type, name, shipping profile, shipping option type, and whether it's enabled in store for customers to use. 5. Once you're done, click the Save button. -![Edit shipping option details form](https://res.cloudinary.com/dza7lstvk/image/upload/v1739984284/User%20Guide/Screenshot_2025-02-19_at_6.57.23_PM_k9z5wq.png) + + +You can't edit a shipping option's fulfillment provider or fulfillment option after its creation. + + + +![Edit shipping option details form](https://res.cloudinary.com/dza7lstvk/image/upload/v1756372512/User%20Guide/CleanShot_2025-08-28_at_12.14.55_2x_sr391l.png) ### Edit Shipping Option Prices diff --git a/www/apps/user-guide/app/settings/locations-and-shipping/page.mdx b/www/apps/user-guide/app/settings/locations-and-shipping/page.mdx index 78dcb26dc8..a0c7cda498 100644 --- a/www/apps/user-guide/app/settings/locations-and-shipping/page.mdx +++ b/www/apps/user-guide/app/settings/locations-and-shipping/page.mdx @@ -27,9 +27,11 @@ A stock location: A shipping profile groups similar products that require a different way of fulfillment. For example, fragile products are fulfilled differently than normal products. You can then provide shipping options specific for products that belong to the Fragile shipping profile. +A shipping option type groups shipping options with similar characteristics. For example, you can group all express shipping options together and apply a promotion to all of them at once. + To view location and shipping settings, go to Settings → Locations & Shipping. -![Location & shipping settings](https://res.cloudinary.com/dza7lstvk/image/upload/v1739980281/User%20Guide/Screenshot_2025-02-19_at_5.51.00_PM_yiczmt.png) +![Location & shipping settings](https://res.cloudinary.com/dza7lstvk/image/upload/v1756389687/User%20Guide/CleanShot_2025-08-28_at_17.00.53_2x_kymfeh.png) --- @@ -37,3 +39,4 @@ To view location and shipping settings, go to Settings → Locations & Shipping. - [Manage Locations](./locations/page.mdx) - [Manage Shipping Profiles](./shipping-profiles/page.mdx) +- [Manage Shipping Option Types](./shipping-option-types/page.mdx) \ No newline at end of file diff --git a/www/apps/user-guide/app/settings/locations-and-shipping/shipping-option-types/page.mdx b/www/apps/user-guide/app/settings/locations-and-shipping/shipping-option-types/page.mdx new file mode 100644 index 0000000000..28581d9f86 --- /dev/null +++ b/www/apps/user-guide/app/settings/locations-and-shipping/shipping-option-types/page.mdx @@ -0,0 +1,107 @@ +--- +sidebar_position: 9 +sidebar_label: "Manage Shipping Option Types" +tags: + - user guide + - fulfillment +products: + - fulfillment +--- + +import { EllipsisHorizontal } from "@medusajs/icons" + +export const metadata = { + title: `Manage Shipping Option Types in Medusa Admin`, +} + +# {metadata.title} + +In this guide, you’ll learn what shipping option types are and how to manage them in the Medusa Admin. + + + +The settings page for Shipping Option Types was added in [Medusa v2.10.0](https://github.com/medusajs/medusa/releases/tag/v2.10.0). + + + +## What is a Shipping Option Type? + +A shipping option type is a classification of shipping options that share similar characteristics. For example, you can have a shipping option type for "Standard Shipping" and another for "Express Shipping". + +Shipping option types help you organize and manage your shipping options. They also allow you to set promotions for specific types of shipping options. + +By default, Medusa comes with two shipping option types: "Standard" and "Express". You can manage these types or create new ones to better fit your business needs. + +--- + +## View Shipping Option Types + +To view shipping option types in your store: + +1. Go to Settings → Location & Shipping. +2. In the Shipping Configuration section, click on Shipping Option Types. + +Here, you can see a list of all the shipping option types you have set up in your store. You can also search, filter, and sort the shipping option types to find the one you are looking for. + +![Shipping Option Types list](https://res.cloudinary.com/dza7lstvk/image/upload/v1756371450/User%20Guide/CleanShot_2025-08-28_at_11.57.16_2x_utjzqs.png) + +--- + +## Create Shipping Option Type + +To create a shipping option type: + +1. Go to Settings → Location & Shipping. +2. In the Shipping Configuration section, click on Shipping Option Types. +3. Click the Create button at the top right. +4. In the form that opens, enter the following information: + - **Label**: The name of the shipping option type that can be displayed to customers. For example, "Same Day". + - **Code**: A unique identifier for the shipping option type. For example, `same_day`. + - **Description**: A brief description of the shipping option type. This is optional but can be helpful to provide more context about the type. For example, "Delivery within the same day". +5. Once you're done, click the Create button at the bottom right. + +![Create shipping option type form](https://res.cloudinary.com/dza7lstvk/image/upload/v1756371811/User%20Guide/CleanShot_2025-08-28_at_12.02.05_2x_fg66gh.png) + +--- + +## View Shipping Option Type Details + +To view the details of a shipping option type: + +1. Go to Settings → Shipping Option Types. +2. Click on the shipping option type you want to view. + +This opens the shipping option type's details page, where you can also manage the shipping option type. + +![Shipping Option Type details page](https://res.cloudinary.com/dza7lstvk/image/upload/v1756371925/User%20Guide/CleanShot_2025-08-28_at_12.05.14_2x_se4xzx.png) + +--- + +## Edit Shipping Option Type Details + +To edit the details of a shipping option type: + +1. Go to the shipping option type's details page. +2. Click the button in the top right corner of the first section. +3. Select "Edit" from the dropdown menu. +4. In the side window that opens, you can edit the shipping option type's label, code, and description. +5. Once you're done, click the Save button. + +![Edit shipping option type form](https://res.cloudinary.com/dza7lstvk/image/upload/v1756372034/User%20Guide/CleanShot_2025-08-28_at_12.07.01_2x_xqk3vk.png) + +--- + +## Delete Shipping Option Type + + + +Deleting a shipping option type is irreversible. + + + +To delete a shipping option type: + +1. Go to the shipping option type's details page. +2. Click the button in the top right corner of the first section. +3. Select "Delete" from the dropdown menu. +4. Confirm the deletion of the shipping option type in the pop-up. diff --git a/www/apps/user-guide/app/settings/product-tags/page.mdx b/www/apps/user-guide/app/settings/product-tags/page.mdx index d64503571d..1b9bb75013 100644 --- a/www/apps/user-guide/app/settings/product-tags/page.mdx +++ b/www/apps/user-guide/app/settings/product-tags/page.mdx @@ -7,7 +7,7 @@ products: - product --- -import { EllipsisHorizontal } from "@medusajs/icons" +import { EllipsisHorizontal, ArrowUpRightOnBox, EllipsisVertical } from "@medusajs/icons" export const metadata = { title: `Manage Product Tags in Medusa Admin`, @@ -47,9 +47,9 @@ To view the details of a product tag: 1. Go to Settings → Product Tags. 2. Click on a product tag from the list. -This opens the product tag's details page where you can also manage the product tag. +This opens the product tag's details page where you can also manage the product tag and its metadata. -![Product tag details](https://res.cloudinary.com/dza7lstvk/image/upload/v1739979858/User%20Guide/Screenshot_2025-02-19_at_5.43.53_PM_ujve6x.png) +![Product tag details](https://res.cloudinary.com/dza7lstvk/image/upload/v1756372959/User%20Guide/CleanShot_2025-08-28_at_12.21.57_2x_op9es5.png) --- @@ -73,6 +73,31 @@ You can manage the tag of a product in the [product's details page](../../produc --- +## Manage Product Tag Metadata + + + +Management of product tag metadata was added in [Medusa v2.10.0](https://github.com/medusajs/medusa/releases/tag/v2.10.0). + + + +Metadata is custom data that can be associated with the product tag in key-value pairs. This is usually used by developers for custom integrations or to store additional information about the product tag. + +To edit the product tag's metadata: + +1. Click the icon at the right of the "Metadata" section. +2. In the side window that opens: + - Manage the key-value pairs in the table. + - To add a new row of key-value pairs before or after a row: + - Hover over the row and click the icon at its right. + - Choose "Insert row above" or "Insert row below" from the dropdown. + - To delete a row of key-value pairs: + - Hover over the row and click the icon at its right. + - Choose "Delete row" from the dropdown. +3. Once you're done, click the Save button. + +--- + ## Delete Product Tag diff --git a/www/apps/user-guide/app/settings/tax-regions/page.mdx b/www/apps/user-guide/app/settings/tax-regions/page.mdx index ba0d4ff40b..fff06975de 100644 --- a/www/apps/user-guide/app/settings/tax-regions/page.mdx +++ b/www/apps/user-guide/app/settings/tax-regions/page.mdx @@ -20,9 +20,9 @@ In this guide, you'll learn what tax regions are and how to manage them. ## What is a Tax Region? -A Tax Region represents a geographical area where you have to apply specific tax rates. For example, if you operate in the United States and Canada, you might have different tax rates for each country, and even in different states or provinces of each country. +A Tax Region represents a geographical area where you must apply specific tax rates. For example, if you operate in the United States and Canada, you might have different tax rates for each country, and even in different states or provinces within each country. -In this case, you can create a tax region for each country you operate in and set up [sublevel tax regions](#sublevel-tax-regions) for each state or province in the country. +In this case, you can create a tax region for each country you operate in and set up [sublevel tax regions](#sublevel-tax-regions) for each state or province within the country. Each tax region has its own tax rate, and you can override the default tax rate in a region for specific products or product types. @@ -58,7 +58,7 @@ To view the details of a tax region: 1. Go to Settings → Tax Regions. 2. Click on a tax region from the list. -This opens the tax region's details page where you can also manage the tax region. +This opens the tax region's details page, where you can also manage the tax region. ![Tax region details](https://res.cloudinary.com/dza7lstvk/image/upload/v1746796437/User%20Guide/Screenshot_2025-05-09_at_4.13.06_PM_m23ili.png) @@ -80,10 +80,10 @@ To edit a tax region: ## Edit Default Tax Rate -To edit the default tax rate of the region: +To edit the default tax rate of a region: 1. Go to the tax region's details page. -2. In the first section, you'll find details of the default tax rate, including its tax rate and code. Click on the icon at its right. +2. In the first section, you'll find details of the default tax rate, including its tax rate and code. Click the icon at its right. ![The icon to click on](https://res.cloudinary.com/dza7lstvk/image/upload/v1739974452/User%20Guide/Screenshot_2025-02-19_at_4.13.51_PM_zclvnp.png) @@ -97,7 +97,7 @@ To edit the default tax rate of the region: ## Manage Tax Rate Overrides -You can override the default tax rate of a region for specific products or product types. This is useful when you have different tax rates for certain products or product types in a region. +You can override the default tax rate of a region for specific products, product types, or shipping options. This is useful if you have different tax rates for certain products or shipping options in a region. You can override tax rates for tax regions and [sublevel tax regions](#sublevel-tax-regions). @@ -110,9 +110,9 @@ To create a tax rate override for a product or product type in a tax region: 3. In the form that opens: - Enter the tax override's name, rate, and code in their respective fields. - If the override should be combined with the default tax rate, enable the "Combinable" toggle. - - Under the "Targets" section, you can select which products or product types this override applies to. You can add a target by clicking "Add target". For each target: - - Choose the target type (Product or Product Type). - - Choose the product or product types that the override applies to, based on the target type you chose. + - Under the "Targets" section, you can select the target of this override. You can add a target by clicking "Add target". For each target: + - Choose the target type (Product, Product Type, or Shipping Option). + - Choose the product, product type, or shipping option that the override applies to, based on the target type you chose. 4. Once you're done, click the Save button. ![Create tax rate override form](https://res.cloudinary.com/dza7lstvk/image/upload/v1739974979/User%20Guide/Screenshot_2025-02-19_at_4.22.43_PM_jup0sn.png) @@ -148,11 +148,11 @@ To delete a tax rate override: ## Sublevel Tax Regions -Tax regions for some countries like the United States have a States, Province, or Cantons section in the tax region details page. Here, you can add sublevel regions for the country. +Tax regions for some countries, like the United States, have a States, Province, or Cantons section in the tax region details page. Here, you can add sublevel regions for the country. ![Sublevel regions section](https://res.cloudinary.com/dza7lstvk/image/upload/v1739975474/User%20Guide/Screenshot_2025-02-19_at_4.30.57_PM_ogjlp2.png) -You can also enable it for other countries that don't show this section by default. For those countries, you'll find a note at the top of the page where you can enable the sublevel regions. +You can also enable it for other countries that don't show this section by default. For those countries, you'll find a note at the top of the page where you can enable sublevel regions. ![Enable sublevel regions alert](https://res.cloudinary.com/dza7lstvk/image/upload/v1739971332/User%20Guide/Screenshot_2025-02-19_at_3.21.51_PM_mbm8lr.png) @@ -168,7 +168,7 @@ To create a sublevel tax region in a tax region: - If the country supports a sublevel by default, you'll find an input to select a state, province, or canton. - If the country doesn't support a sublevel by default, you'll find an input to enter the lower-case [ISO 3166-2 code](https://en.wikipedia.org/wiki/ISO_3166-2) of the sublevel. - Under the "Default tax rate" section, you can optionally enter a name, tax rate, and tax code in their respective fields. - - If the tax region's rates should be combined with the parent's rates, enable the "Combinable" toggle. + - If the sublevel tax region's rates should be combined with the parent's rates, enable the "Combinable" toggle. 4. Once you're done, click the Save button. ![Create sublevel region form](https://res.cloudinary.com/dza7lstvk/image/upload/v1739971762/User%20Guide/Screenshot_2025-02-19_at_3.29.09_PM_cpwi4e.png) @@ -180,7 +180,7 @@ To view the details of a sublevel tax region: 1. Go to the tax region's details page. 2. Under the "Sublevels" section or its equivalent, click on a sublevel tax region. -This opens the sublevel tax region's details page where you can also manage the sublevel tax region. +This opens the sublevel tax region's details page, where you can also manage the sublevel tax region. ![Sublevel tax region details page](https://res.cloudinary.com/dza7lstvk/image/upload/v1739974129/User%20Guide/Screenshot_2025-02-19_at_4.08.33_PM_i2v219.png) diff --git a/www/apps/user-guide/components/MDXComponents/index.tsx b/www/apps/user-guide/components/MDXComponents/index.tsx index 8dd8409eb5..d40f6c616b 100644 --- a/www/apps/user-guide/components/MDXComponents/index.tsx +++ b/www/apps/user-guide/components/MDXComponents/index.tsx @@ -1,6 +1,5 @@ import type { MDXComponents as MDXComponentsType } from "mdx/types" import { - Link, MDXComponents as UiMdxComponents, InlineThemeImage, InlineIcon, @@ -8,7 +7,6 @@ import { const MDXComponents: MDXComponentsType = { ...UiMdxComponents, - a: Link, InlineThemeImage, InlineIcon, } diff --git a/www/apps/user-guide/generated/edit-dates.mjs b/www/apps/user-guide/generated/edit-dates.mjs index 287da7d641..2639de97ec 100644 --- a/www/apps/user-guide/generated/edit-dates.mjs +++ b/www/apps/user-guide/generated/edit-dates.mjs @@ -5,11 +5,11 @@ export const generatedEditDates = { "app/settings/sales-channels/page.mdx": "2025-05-30T13:31:09.754Z", "app/settings/users/page.mdx": "2025-05-30T13:31:29.991Z", "app/page.mdx": "2025-02-26T14:18:27.755Z", - "app/settings/page.mdx": "2025-02-19T15:46:09.018Z", + "app/settings/page.mdx": "2025-08-28T13:59:06.712Z", "app/products/export/page.mdx": "2025-07-31T14:29:30.511Z", "app/settings/return-reasons/page.mdx": "2025-05-30T13:31:05.596Z", "app/settings/regions/page.mdx": "2025-05-30T13:30:59.228Z", - "app/orders/page.mdx": "2025-05-30T13:28:32.793Z", + "app/orders/page.mdx": "2025-08-26T09:21:49.782Z", "app/settings/users/invites/page.mdx": "2025-08-01T11:25:25.130Z", "app/settings/developer/page.mdx": "2025-02-25T15:11:55.392Z", "app/settings/profile/page.mdx": "2025-05-30T13:30:55.079Z", @@ -31,7 +31,7 @@ export const generatedEditDates = { "app/products/collections/page.mdx": "2025-05-30T13:29:05.948Z", "app/customers/manage/page.mdx": "2025-07-31T14:28:07.889Z", "app/discounts/create/page.mdx": "2024-05-03T17:36:38+03:00", - "app/orders/payments/page.mdx": "2025-07-31T14:28:56.252Z", + "app/orders/payments/page.mdx": "2025-08-26T09:54:18.417Z", "app/discounts/page.mdx": "2024-05-03T17:36:38+03:00", "app/orders/exchanges/page.mdx": "2025-05-30T13:27:55.646Z", "app/products/create/page.mdx": "2025-05-30T13:29:24.876Z", @@ -47,13 +47,17 @@ export const generatedEditDates = { "app/price-lists/manage/page.mdx": "2025-05-30T13:28:47.929Z", "app/price-lists/page.mdx": "2025-05-30T13:28:53.668Z", "app/settings/tax-regions/page.mdx": "2025-05-30T13:31:21.021Z", - "app/settings/locations-and-shipping/locations/page.mdx": "2025-07-31T14:31:03.081Z", - "app/settings/locations-and-shipping/page.mdx": "2025-05-30T13:30:41.759Z", + "app/settings/locations-and-shipping/locations/page.mdx": "2025-08-28T14:06:20.266Z", + "app/settings/locations-and-shipping/page.mdx": "2025-08-28T14:01:34.185Z", "app/settings/locations-and-shipping/shipping-profiles/page.mdx": "2025-05-30T13:30:37.452Z", "app/settings/product-tags/page.mdx": "2025-05-30T13:30:46.705Z", "app/settings/product-types/page.mdx": "2025-05-30T13:30:50.623Z", "app/settings/developer/publishable-api-keys/page.mdx": "2025-05-30T13:30:19.734Z", "app/settings/developer/secret-api-keys/page.mdx": "2025-05-30T13:30:23.919Z", "app/settings/developer/workflows/page.mdx": "2025-02-25T15:52:48.349Z", - "app/reset-password/page.mdx": "2025-05-30T13:30:13.055Z" + "app/reset-password/page.mdx": "2025-05-30T13:30:13.055Z", + "app/orders/draft-orders/create/page.mdx": "2025-08-26T09:34:53.621Z", + "app/orders/draft-orders/manage/page.mdx": "2025-08-26T09:47:17.568Z", + "app/orders/draft-orders/page.mdx": "2025-08-26T09:31:53.784Z", + "app/settings/locations-and-shipping/shipping-option-types/page.mdx": "2025-08-28T14:03:13.999Z" } \ No newline at end of file diff --git a/www/apps/user-guide/generated/sidebar.mjs b/www/apps/user-guide/generated/sidebar.mjs index bd95d8c9bc..2f38d6af50 100644 --- a/www/apps/user-guide/generated/sidebar.mjs +++ b/www/apps/user-guide/generated/sidebar.mjs @@ -127,6 +127,31 @@ export const generatedSidebars = [ "title": "Manage Claims", "path": "/orders/claims", "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "Draft Orders", + "path": "/orders/draft-orders", + "children": [ + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "Create Draft Order", + "path": "/orders/draft-orders/create", + "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "Manage Draft Order", + "path": "/orders/draft-orders/manage", + "children": [] + } + ] } ] }, @@ -461,9 +486,17 @@ export const generatedSidebars = [ "loaded": true, "isPathHref": true, "type": "link", - "title": "Manage Shipping Profiles", + "title": "Shipping Profiles", "path": "/settings/locations-and-shipping/shipping-profiles", "children": [] + }, + { + "loaded": true, + "isPathHref": true, + "type": "link", + "title": "Shipping Option Types", + "path": "/settings/locations-and-shipping/shipping-option-types", + "children": [] } ] }, diff --git a/www/apps/user-guide/sidebar.mjs b/www/apps/user-guide/sidebar.mjs index 90cb0f447e..6a55e4bff3 100644 --- a/www/apps/user-guide/sidebar.mjs +++ b/www/apps/user-guide/sidebar.mjs @@ -66,6 +66,23 @@ export const sidebar = [ title: "Manage Claims", path: "/orders/claims", }, + { + type: "link", + title: "Draft Orders", + path: "/orders/draft-orders", + children: [ + { + type: "link", + title: "Create Draft Order", + path: "/orders/draft-orders/create", + }, + { + type: "link", + title: "Manage Draft Order", + path: "/orders/draft-orders/manage", + }, + ], + }, ], }, { @@ -283,9 +300,14 @@ export const sidebar = [ }, { type: "link", - title: "Manage Shipping Profiles", + title: "Shipping Profiles", path: "/settings/locations-and-shipping/shipping-profiles", }, + { + type: "link", + title: "Shipping Option Types", + path: "/settings/locations-and-shipping/shipping-option-types", + }, ], }, { diff --git a/www/packages/docs-ui/src/components/MarkdownContent/index.tsx b/www/packages/docs-ui/src/components/MarkdownContent/index.tsx index 70692b0b81..87e6ed7e71 100644 --- a/www/packages/docs-ui/src/components/MarkdownContent/index.tsx +++ b/www/packages/docs-ui/src/components/MarkdownContent/index.tsx @@ -3,7 +3,7 @@ import ReactMarkdown, { Options as ReactMarkdownOptions, Components, } from "react-markdown" -import { MDXComponents, Link } from "@/components" +import { MDXComponents } from "@/components" import clsx from "clsx" export type MarkdownContentProps = ReactMarkdownOptions & { @@ -32,7 +32,6 @@ export const MarkdownContent = ({ ) }, - a: Link, } } {...props} diff --git a/www/packages/docs-ui/src/components/SourceCodeLink/index.tsx b/www/packages/docs-ui/src/components/SourceCodeLink/index.tsx index 290124ef8b..ed45887774 100644 --- a/www/packages/docs-ui/src/components/SourceCodeLink/index.tsx +++ b/www/packages/docs-ui/src/components/SourceCodeLink/index.tsx @@ -1,8 +1,8 @@ import React from "react" import { Link } from "../Link" import { Badge } from "../Badge" -import { Github } from "@medusajs/icons" import clsx from "clsx" +import { GithubIcon } from "../Icons/Github" type SourceCodeLinkProps = { link: string @@ -29,7 +29,7 @@ export const SourceCodeLink = ({ className="inline-flex hover:bg-medusa-tag-neutral-bg-hover cursor-pointer" childrenWrapperClassName="inline-flex flex-row gap-[3px] items-center" > - {icon || } + {icon || } {text || "Source Code"} diff --git a/www/packages/tags/src/tags/auth.ts b/www/packages/tags/src/tags/auth.ts index f0f3fddff3..e5599e5e32 100644 --- a/www/packages/tags/src/tags/auth.ts +++ b/www/packages/tags/src/tags/auth.ts @@ -1,12 +1,12 @@ export const auth = [ - { - "title": "Reset Password", - "path": "https://docs.medusajs.com/user-guide/reset-password" - }, { "title": "Create Actor Type", "path": "https://docs.medusajs.com/resources/commerce-modules/auth/create-actor-type" }, + { + "title": "Reset Password", + "path": "https://docs.medusajs.com/user-guide/reset-password" + }, { "title": "Implement Phone Authentication", "path": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/phone-auth" diff --git a/www/packages/tags/src/tags/fulfillment.ts b/www/packages/tags/src/tags/fulfillment.ts index f5f86a1b09..941290e46c 100644 --- a/www/packages/tags/src/tags/fulfillment.ts +++ b/www/packages/tags/src/tags/fulfillment.ts @@ -15,6 +15,10 @@ export const fulfillment = [ "title": "Manage Shipping Profiles", "path": "https://docs.medusajs.com/user-guide/settings/locations-and-shipping/shipping-profiles" }, + { + "title": "Manage Shipping Option Types", + "path": "https://docs.medusajs.com/user-guide/settings/shipping-option-types" + }, { "title": "Shipping Option Price Rules", "path": "https://docs.medusajs.com/resources/commerce-modules/pricing/price-rules" diff --git a/www/packages/tags/src/tags/order.ts b/www/packages/tags/src/tags/order.ts index 893c14f66d..bde57f1217 100644 --- a/www/packages/tags/src/tags/order.ts +++ b/www/packages/tags/src/tags/order.ts @@ -3,6 +3,18 @@ export const order = [ "title": "Manage Order Claims", "path": "https://docs.medusajs.com/user-guide/orders/claims" }, + { + "title": "Create Draft Order", + "path": "https://docs.medusajs.com/user-guide/orders/draft-orders/create" + }, + { + "title": "Manage Draft Order", + "path": "https://docs.medusajs.com/user-guide/orders/draft-orders/manage" + }, + { + "title": "Draft Orders", + "path": "https://docs.medusajs.com/user-guide/orders/draft-orders" + }, { "title": "Edit Order Items", "path": "https://docs.medusajs.com/user-guide/orders/edit" diff --git a/www/packages/tags/src/tags/user-guide.ts b/www/packages/tags/src/tags/user-guide.ts index e5db7852a6..18c886f142 100644 --- a/www/packages/tags/src/tags/user-guide.ts +++ b/www/packages/tags/src/tags/user-guide.ts @@ -27,6 +27,18 @@ export const userGuide = [ "title": "Manage Order Claims", "path": "https://docs.medusajs.com/user-guide/orders/claims" }, + { + "title": "Create Draft Order", + "path": "https://docs.medusajs.com/user-guide/orders/draft-orders/create" + }, + { + "title": "Manage Draft Order", + "path": "https://docs.medusajs.com/user-guide/orders/draft-orders/manage" + }, + { + "title": "Draft Orders", + "path": "https://docs.medusajs.com/user-guide/orders/draft-orders" + }, { "title": "Edit Order Items", "path": "https://docs.medusajs.com/user-guide/orders/edit" @@ -175,6 +187,10 @@ export const userGuide = [ "title": "Manage Sales Channels", "path": "https://docs.medusajs.com/user-guide/settings/sales-channels" }, + { + "title": "Manage Shipping Option Types", + "path": "https://docs.medusajs.com/user-guide/settings/shipping-option-types" + }, { "title": "Manage Store", "path": "https://docs.medusajs.com/user-guide/settings/store"