docs: revise commerce modules overview pages (#10738)

* revise API Key Module overview

* revise auth module

* support ref sidebar items

* remove examples

* revise cart module

* revise currency

* revise customer module

* revise fulfillment module

* revise inventory module

* revise order module

* revise payment

* revise pricing module

* revise product module

* revise promotion module

* revise region module

* revise sales channel module

* revise stock location module

* revise store module

* revise tax module

* revise user module

* lint content + fix snippets
This commit is contained in:
Shahed Nasser authored and GitHub committed 2024-12-26 10:32:16 +02:00
1 parent c8f9938865
commit ebca8fed28
112 files changed
+9465 -7731

No files matched your search

@@ -1,261 +0,0 @@
import { CodeTabs, CodeTab } from "docs-ui"
export const metadata = {
title: `Examples of the Promotion Module`,
}
# {metadata.title}
In this document, you’ll find common examples of how you can use the Promotion Module in your application.
<Note>
You should only use the Promotion Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx).
</Note>
## Create a Promotion
<CodeTabs groupId="app-type">
<CodeTab label="Medusa API Router" value="medusa">
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { Modules } from "@medusajs/framework/utils"
export async function POST(
request: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const promotionModuleService = request.scope.resolve(
Modules.PROMOTION
)
const promotion = await promotionModuleService.createPromotions({
code: "10%OFF",
type: "standard",
application_method: {
type: "percentage",
target_type: "order",
value: "10",
currency_code: "usd",
},
})
res.json({ promotion })
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import { initialize as initializePromotionModule } from "@medusajs/medusa/promotion"
export async function POST(request: Request) {
const promotionModuleService = await initializePromotionModule()
const body = await request.json()
const promotion = await promotionModuleService.createPromotions({
code: "10%OFF",
type: "standard",
application_method: {
type: "percentage",
target_type: "order",
value: "10",
currency_code: "usd",
},
})
return NextResponse.json({ promotion })
}
```
</CodeTab>
</CodeTabs>
---
## Create a Campaign
<CodeTabs groupId="app-type">
<CodeTab label="Medusa API Router" value="medusa">
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { Modules } from "@medusajs/framework/utils"
export async function POST(
request: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const promotionModuleService = request.scope.resolve(
Modules.PROMOTION
)
const campaign = await promotionModuleService.createCampaigns({
name: "Summer Discounts",
campaign_identifier: "G-123445",
starts_at: new Date("2024-05-02"),
ends_at: new Date("2024-07-20"),
})
res.json({ campaign })
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import { initialize as initializePromotionModule } from "@medusajs/medusa/promotion"
export async function POST(request: Request) {
const promotionModuleService = await initializePromotionModule()
const body = await request.json()
const campaign = await promotionModuleService.createCampaigns({
name: "Summer Discounts",
campaign_identifier: "G-123445",
starts_at: new Date("2024-05-02"),
ends_at: new Date("2024-07-20"),
})
return NextResponse.json({ campaign })
}
```
</CodeTab>
</CodeTabs>
---
## Create a Promotion with Flexible Rules
<CodeTabs groupId="app-type">
<CodeTab label="Medusa API Router" value="medusa">
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { Modules } from "@medusajs/framework/utils"
export async function POST(
request: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const promotionModuleService = request.scope.resolve(
Modules.PROMOTION
)
const promotion = await promotionModuleService.createPromotions({
code: "10%OFF",
type: "standard",
application_method: {
type: "percentage",
target_type: "order",
value: "10",
currency_code: "usd",
},
rules: [
{
attribute: "customer_group_id",
operator: "eq",
values: ["VIP"],
},
],
})
res.json({ promotion })
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import { initialize as initializePromotionModule } from "@medusajs/medusa/promotion"
export async function POST(request: Request) {
const promotionModuleService = await initializePromotionModule()
const promotion = await promotionModuleService.createPromotions({
code: "10%OFF",
type: "standard",
application_method: {
type: "percentage",
target_type: "order",
value: "10",
currency_code: "usd",
},
rules: [
{
attribute: "customer_group_id",
operator: "eq",
values: ["VIP"],
},
],
})
return NextResponse.json({ promotion })
}
```
</CodeTab>
</CodeTabs>
---
## List Promotions
<CodeTabs groupId="app-type">
<CodeTab label="Medusa API Router" value="medusa">
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { Modules } from "@medusajs/framework/utils"
export async function GET(
request: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const promotionModuleService = request.scope.resolve(
Modules.PROMOTION
)
res.json({
promotions: await promotionModuleService.listPromotions(),
})
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import { initialize as initializePromotionModule } from "@medusajs/medusa/promotion"
export async function GET(request: Request) {
const promotionModuleService = await initializePromotionModule()
return NextResponse.json({
promotions: await promotionModuleService.listPromotions(),
})
}
```
</CodeTab>
</CodeTabs>
---
## More Examples
The [Promotion Module's main service reference](/references/promotion) provides a reference to all the methods available for use with examples for each.
@@ -49,8 +49,8 @@ To retrieve the line item adjustments of a promotion, pass `line_item_adjustment
const { data: promotions } = await query.graph({
entity: "promotion",
fields: [
"carts.*"
]
"carts.*",
],
})
// promotions.carts
@@ -67,8 +67,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
const { data: promotions } = useQueryGraphStep({
entity: "promotion",
fields: [
"carts.*"
]
"carts.*",
],
})
// promotions.carts
@@ -140,8 +140,8 @@ To retrieve the orders a promotion is applied on with [Query](!docs!/learn/funda
const { data: promotions } = await query.graph({
entity: "promotion",
fields: [
"orders.*"
]
"orders.*",
],
})
// promotions.orders
@@ -158,8 +158,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
const { data: promotions } = useQueryGraphStep({
entity: "promotion",
fields: [
"orders.*"
]
"orders.*",
],
})
// promotions.orders
@@ -6,130 +6,161 @@ export const metadata = {
# {metadata.title}
The Promotion Module provides promotion-related features in your Medusa and Node.js applications.
In this section of the documentation, you will find resources to learn more about the Promotion Module and how to use it in your application.
## How to Use the Promotion Module's Service
Medusa has promotion related features available out-of-the-box through the Promotion Module. A [module](!docs!/learn/fundamentals/modules) is a standalone package that provides features for a single domain. Each of Medusa's commerce features are placed in commerce modules, such as this Promotion Module.
You can use the Promotion Module's main service by resolving from the Medusa container the resource `Modules.PROMOTION`.
<Note>
Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation).
</Note>
## Promotion Features
- [Discount Functionalities](./concepts/page.mdx): A promotion discounts an amount or percentage of a cart's items, shipping methods, or the entire order.
- [Flexible Promotion Rules](./concepts/page.mdx#flexible-rules): A promotion has rules that restricts when the promotion is applied.
- [Campaign Management](./campaign/page.mdx): A campaign combines promotions under the same conditions, such as start and end dates, and budget configurations.
- [Apply Promotion on Carts and Orders](./actions/page.mdx): Apply promotions on carts and orders to discount items, shipping methods, or the entire order.
---
## How to Use the Promotion Module
In your Medusa application, you build flows around commerce modules. A flow is built as a [Workflow](!docs!/learn/fundamentals/workflows), which is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism.
You can build custom workflows and steps. You can also re-use Medusa's workflows and steps, which are provided by the `@medusajs/medusa/core-flows` package.
For example:
<CodeTabs groupId="resource-type">
<CodeTab label="Workflow Step" value="workflow-step">
export const highlights = [
["12", "Modules.PROMOTION", "Resolve the module in a step."]
]
```ts title="src/workflows/hello-world/step1.ts"
import { createStep } from "@medusajs/framework/workflows-sdk"
```ts title="src/workflows/create-promotion.ts" highlights={highlights}
import {
createWorkflow,
WorkflowResponse,
createStep,
StepResponse,
} from "@medusajs/framework/workflows-sdk"
import { Modules } from "@medusajs/framework/utils"
const step1 = createStep("step-1", async (_, { container }) => {
const promotionModuleService = container.resolve(
Modules.PROMOTION
)
const createPromotionStep = createStep(
"create-promotion",
async ({}, { container }) => {
const promotionModuleService = container.resolve(Modules.PROMOTION)
const promotions = await promotionModuleService.listPromotions()
})
const promotion = await promotionModuleService.createPromotions({
code: "10%OFF",
type: "standard",
application_method: {
type: "percentage",
target_type: "order",
value: 10,
currency_code: "usd",
},
})
return new StepResponse({ promotion }, promotion.id)
},
async (promotionId, { container }) => {
if (!promotionId) {
return
}
const promotionModuleService = container.resolve(Modules.PROMOTION)
await promotionModuleService.deletePromotions(promotionId)
}
)
export const createPromotionWorkflow = createWorkflow(
"create-promotion",
() => {
const { promotion } = createPromotionStep()
return new WorkflowResponse({
promotion,
})
}
)
```
</CodeTab>
<CodeTab label="API Route" value="api-route">
You can then execute the workflow in your custom API routes, scheduled jobs, or subscribers:
```ts title="src/api/store/custom/route.ts"
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { Modules } from "@medusajs/framework/utils"
<CodeTabs group="resource-types">
<CodeTab label="API Route" value="api-route">
```ts title="src/api/workflow/route.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports"
import type {
MedusaRequest,
MedusaResponse,
} from "@medusajs/framework/http"
import { createPromotionWorkflow } from "../../workflows/create-cart"
export async function GET(
request: MedusaRequest,
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const promotionModuleService = request.scope.resolve(
Modules.PROMOTION
)
) {
const { result } = await createPromotionWorkflow(req.scope)
.run()
res.json({
promotions: await promotionModuleService.listPromotions(),
})
res.send(result)
}
```
</CodeTab>
<CodeTab label="Subscriber" value="subscribers">
<CodeTab label="Subscriber" value="subscriber">
```ts title="src/subscribers/user-created.ts" highlights={[["11"], ["12"]]} collapsibleLines="1-6" expandButtonLabel="Show Imports"
import {
type SubscriberConfig,
type SubscriberArgs,
} from "@medusajs/framework"
import { createPromotionWorkflow } from "../workflows/create-cart"
```ts title="src/subscribers/custom-handler.ts"
import { SubscriberArgs } from "@medusajs/framework"
import { Modules } from "@medusajs/framework/utils"
export default async function handleUserCreated({
event: { data },
container,
}: SubscriberArgs<{ id: string }>) {
const { result } = await createPromotionWorkflow(container)
.run()
export default async function subscriberHandler({ container }: SubscriberArgs) {
const promotionModuleService = container.resolve(
Modules.PROMOTION
)
console.log(result)
}
const promotions = await promotionModuleService.listPromotions()
export const config: SubscriberConfig = {
event: "user.created",
}
```
</CodeTab>
<CodeTab label="Scheduled Job" value="scheduled-job">
```ts title="src/jobs/run-daily.ts" highlights={[["7"], ["8"]]}
import { MedusaContainer } from "@medusajs/framework/types"
import { createPromotionWorkflow } from "../workflows/create-cart"
export default async function myCustomJob(
container: MedusaContainer
) {
const { result } = await createPromotionWorkflow(container)
.run()
console.log(result)
}
export const config = {
name: "run-once-a-day",
schedule: `0 0 * * *`,
}
```
</CodeTab>
</CodeTabs>
Learn more about workflows in [this documentation](!docs!/learn/fundamentals/workflows).
---
## Features
### Discount Functionalities
A promotion discounts an amount or percentage of a cart's items, shipping methods, or the entire order.
The Promotion Module allows you to store and manage promotions.
```ts
const promotion = await promotionModuleService.createPromotions({
code: "10%OFF",
type: "standard",
application_method: {
type: "percentage",
target_type: "order",
value: "10",
currency_code: "usd",
},
})
```
### Flexible Promotion Rules
A promotion has rules that restricts when it's applied.
For example, you can create a promotion that's only applied to VIP customers.
```ts
const promotion = await promotionModuleService.createPromotions({
code: "10%OFF",
type: "standard",
application_method: {
type: "percentage",
target_type: "order",
value: "10",
currency_code: "usd",
},
rules: [
{
attribute: "customer_group_id",
operator: "eq",
values: ["VIP"],
},
],
})
```
### Campaign Management
A campaign combines promotions under the same conditions, such as start and end dates.
A campaign can also have an identifier for tracking purposes, such as tracking through tools like Google Analytics.
```ts
const campaign = await promotionModuleService.createCampaigns({
name: "Summer Discounts",
campaign_identifier: "G-123445",
starts_at: new Date("2024-05-02"),
ends_at: new Date("2024-07-20"),
})
```
<CommerceModuleSections name="Promotion" />