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
2024-12-26 10:32:16 +02:00
committed by GitHub
parent c8f9938865
commit ebca8fed28
112 changed files with 9465 additions and 7731 deletions
@@ -1,463 +0,0 @@
import { CodeTabs, CodeTab } from "docs-ui"
export const metadata = {
title: `Examples of the Cart Module`,
}
# {metadata.title}
In this guide, youll find common examples of how you can use the Cart Module in your application.
<Note>
You should only use the Cart Module's main service when implementing complex customizations. For common cases, check out [available workflows instead](../../../medusa-workflows-reference/page.mdx).
</Note>
## Create a Cart
<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(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const cartModuleService = req.scope.resolve(
Modules.CART
)
const cart = await cartModuleService.createCarts({
currency_code: "usd",
shipping_address: {
address_1: "1512 Barataria Blvd",
country_code: "us",
},
items: [
{
title: "Shirt",
unit_price: 1000,
quantity: 1,
},
],
})
res.json({ cart })
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import { initialize as initializeCartModule } from "@medusajs/medusa/cart"
export async function POST(request: Request) {
const cartModuleService = await initializeCartModule()
const cart = await cartModuleService.createCarts({
currency_code: "usd",
shipping_address: {
address_1: "1512 Barataria Blvd",
country_code: "us",
},
items: [
{
title: "Shirt",
unit_price: 1000,
quantity: 1,
},
],
})
return NextResponse.json({
cart,
})
}
```
</CodeTab>
</CodeTabs>
---
## Retrieve Cart by ID
<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(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const cartModuleService = req.scope.resolve(
Modules.CART
)
const cart = await cartModuleService.retrieveCart("cart_123")
res.json({ cart })
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import { initialize as initializeCartModule } from "@medusajs/medusa/cart"
export async function GET(request: Request) {
const cartModuleService = await initializeCartModule()
const cart = await cartModuleService.retrieveCart("cart_123")
return NextResponse.json({
cart,
})
}
```
</CodeTab>
</CodeTabs>
---
## Add Item to Cart
<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(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const cartModuleService = req.scope.resolve(
Modules.CART
)
const lineItem = await cartModuleService.addLineItems({
cart_id: "cart_123",
title: "Shirt",
quantity: 2,
unit_price: 5000,
})
res.json({
line_item: lineItem,
})
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import { initialize as initializeCartModule } from "@medusajs/medusa/cart"
export async function POST(request: Request) {
const cartModuleService = await initializeCartModule()
const lineItem = await cartModuleService.addLineItems({
cart_id: "cart_123",
title: "Shirt",
quantity: 2,
unit_price: 5000,
})
return NextResponse.json({
line_item: lineItem,
})
}
```
</CodeTab>
</CodeTabs>
---
## Add Shipping Method to Cart
<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(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const cartModuleService = req.scope.resolve(
Modules.CART
)
const shippingMethod = await cartModuleService.addShippingMethods({
cart_id: "cart_123",
name: "Custom shipping",
amount: 1000,
})
res.json({
shipping_method: shippingMethod,
})
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import { initialize as initializeCartModule } from "@medusajs/medusa/cart"
export async function POST(request: Request) {
const cartModuleService = await initializeCartModule()
const shippingMethod = await cartModuleService.addShippingMethods({
cart_id: "cart_123",
name: "Custom shipping",
amount: 1000,
})
return NextResponse.json({
shipping_method: shippingMethod,
})
}
```
</CodeTab>
</CodeTabs>
---
## Add Item Adjustment Line
<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(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const cartModuleService = req.scope.resolve(
Modules.CART
)
const itemAdjustment = await cartModuleService.addLineItemAdjustments({
item_id: "cali_123",
amount: 500,
code: "50%OFF",
})
res.json({
adjustment: itemAdjustment,
})
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import { initialize as initializeCartModule } from "@medusajs/medusa/cart"
export async function POST(request: Request) {
const cartModuleService = await initializeCartModule()
const itemAdjustment = await cartModuleService.addLineItemAdjustments({
item_id: "cali_123",
amount: 500,
code: "50%OFF",
})
return NextResponse.json({
adjustment: itemAdjustment,
})
}
```
</CodeTab>
</CodeTabs>
---
## Add Shipping Method Adjustment Line
<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(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const cartModuleService = req.scope.resolve(
Modules.CART
)
const shippingMethodAdjustment =
await cartModuleService.addShippingMethodAdjustments({
shipping_method_id: "casm_123",
amount: 500,
code: "FREESHIPPING",
})
res.json({
adjustment: shippingMethodAdjustment,
})
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import { initialize as initializeCartModule } from "@medusajs/medusa/cart"
export async function POST(request: Request) {
const cartModuleService = await initializeCartModule()
const shippingMethodAdjustment =
await cartModuleService.addShippingMethodAdjustments({
shipping_method_id: "casm_123",
amount: 500,
code: "FREESHIPPING",
})
return NextResponse.json({
adjustment: shippingMethodAdjustment,
})
}
```
</CodeTab>
</CodeTabs>
---
## Remove Line Item from Cart
<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 DELETE(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const cartModuleService = req.scope.resolve(
Modules.CART
)
await cartModuleService.deleteLineItems(["cali_123"])
res.status(200)
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { NextResponse } from "next/server"
import { initialize as initializeCartModule } from "@medusajs/medusa/cart"
export async function DELETE(request: Request) {
const cartModuleService = await initializeCartModule()
await cartModuleService.deleteLineItems(["cali_123"])
}
```
</CodeTab>
</CodeTabs>
---
## Remove Shipping Method from Cart
<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 DELETE(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const cartModuleService = req.scope.resolve(
Modules.CART
)
await cartModuleService.deleteShippingMethods(["casm_123"])
res.status(200)
}
```
</CodeTab>
<CodeTab label="Next.js App Router" value="nextjs">
```ts
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { Modules } from "@medusajs/framework/utils"
export async function DELETE(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const cartModuleService = req.scope.resolve(
Modules.CART
)
await cartModuleService.deleteShippingMethods(["casm_123"])
res.status(200)
}
```
</CodeTab>
</CodeTabs>
---
## More Examples
The [Cart Module's main service reference](/references/cart) provides a reference to all the methods available for use with examples for each.
@@ -44,8 +44,8 @@ To retrieve the customer of a cart with [Query](!docs!/learn/fundamentals/module
const { data: carts } = await query.graph({
entity: "cart",
fields: [
"customer.*"
]
"customer.*",
],
})
// carts.order
@@ -62,8 +62,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
const { data: carts } = useQueryGraphStep({
entity: "cart",
fields: [
"customer.*"
]
"customer.*",
],
})
// carts.order
@@ -93,8 +93,8 @@ To retrieve the order of a cart with [Query](!docs!/learn/fundamentals/module-li
const { data: carts } = await query.graph({
entity: "cart",
fields: [
"order.*"
]
"order.*",
],
})
// carts.order
@@ -111,8 +111,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
const { data: carts } = useQueryGraphStep({
entity: "cart",
fields: [
"order.*"
]
"order.*",
],
})
// carts.order
@@ -186,8 +186,8 @@ To retrieve the payment collection of a cart with [Query](!docs!/learn/fundament
const { data: carts } = await query.graph({
entity: "cart",
fields: [
"payment_collection.*"
]
"payment_collection.*",
],
})
// carts.payment_collection
@@ -204,8 +204,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
const { data: carts } = useQueryGraphStep({
entity: "cart",
fields: [
"payment_collection.*"
]
"payment_collection.*",
],
})
// carts.payment_collection
@@ -283,8 +283,8 @@ To retrieve the product, pass `product.*` in `fields`.
const { data: lineItems } = await query.graph({
entity: "line_item",
fields: [
"variant.*"
]
"variant.*",
],
})
// lineItems.variant
@@ -301,8 +301,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
const { data: lineItems } = useQueryGraphStep({
entity: "line_item",
fields: [
"variant.*"
]
"variant.*",
],
})
// lineItems.variant
@@ -340,8 +340,8 @@ To retrieve the promotion of a line item adjustment, pass `promotion.*` in `fiel
const { data: carts } = await query.graph({
entity: "cart",
fields: [
"promotions.*"
]
"promotions.*",
],
})
// carts.promotions
@@ -358,8 +358,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
const { data: carts } = useQueryGraphStep({
entity: "cart",
fields: [
"promotions.*"
]
"promotions.*",
],
})
// carts.promotions
@@ -429,8 +429,8 @@ To retrieve the region of a cart with [Query](!docs!/learn/fundamentals/module-l
const { data: carts } = await query.graph({
entity: "cart",
fields: [
"region.*"
]
"region.*",
],
})
// carts.region
@@ -447,8 +447,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
const { data: carts } = useQueryGraphStep({
entity: "cart",
fields: [
"region.*"
]
"region.*",
],
})
// carts.region
@@ -474,8 +474,8 @@ To retrieve the sales channel of a cart with [Query](!docs!/learn/fundamentals/m
const { data: carts } = await query.graph({
entity: "cart",
fields: [
"sales_channel.*"
]
"sales_channel.*",
],
})
// carts.sales_channel
@@ -492,8 +492,8 @@ import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
const { data: carts } = useQueryGraphStep({
entity: "cart",
fields: [
"sales_channel.*"
]
"sales_channel.*",
],
})
// carts.sales_channel
@@ -6,120 +6,165 @@ export const metadata = {
# {metadata.title}
The Cart Module provides cart-related features in your Medusa and Node.js applications.
In this section of the documentation, you will find resources to learn more about the Cart Module and how to use it in your application.
## How to Use Cart Module's Service
Medusa has cart related features available out-of-the-box through the Cart 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 Cart Module.
You can use the Cart Module's main service by resolving from the Medusa container the resource `Modules.CART`.
<Note>
Learn more about why modules are isolated in [this documentation](!docs!/learn/fundamentals/modules/isolation).
</Note>
## Cart Features
- [Cart Management](./concepts/page.mdx): Store and manage carts, including their addresses, line items, shipping methods, and more.
- [Apply Promotion Adjustments](./promotions/page.mdx): Apply promotions or discounts to line 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 line items and shipping methods.
- [Cart Scoping](./links-to-other-modules/page.mdx): When used in the Medusa application, Medusa creates links to other commerce modules, scoping a cart to a sales channel, region, and a customer.
---
## How to Use the Cart 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.CART", "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-cart.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 cartModuleService = container.resolve(
Modules.CART
)
const createCartStep = createStep(
"create-cart",
async ({}, { container }) => {
const cartModuleService = container.resolve(Modules.CART)
const carts = await cartModuleService.listCarts()
})
const cart = await cartModuleService.createCarts({
currency_code: "usd",
shipping_address: {
address_1: "1512 Barataria Blvd",
country_code: "us",
},
items: [
{
title: "Shirt",
unit_price: 1000,
quantity: 1,
},
],
})
return new StepResponse({ cart }, cart.id)
},
async (cartId, { container }) => {
if (!cartId) {
return
}
const cartModuleService = container.resolve(Modules.CART)
await cartModuleService.deleteCarts([cartId])
}
)
export const createCartWorkflow = createWorkflow(
"create-cart",
() => {
const { cart } = createCartStep()
return new WorkflowResponse({
cart,
})
}
)
```
</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 { createCartWorkflow } from "../../workflows/create-cart"
export async function GET(
req: MedusaRequest,
res: MedusaResponse
): Promise<void> {
const cartModuleService = req.scope.resolve(
Modules.CART
)
) {
const { result } = await createCartWorkflow(req.scope)
.run()
res.json({
carts: await cartModuleService.listCarts(),
})
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 { createCartWorkflow } 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 createCartWorkflow(container)
.run()
export default async function subscriberHandler({ container }: SubscriberArgs) {
const cartModuleService = container.resolve(
Modules.CART
)
console.log(result)
}
const carts = await cartModuleService.listCarts()
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 { createCartWorkflow } from "../workflows/create-cart"
export default async function myCustomJob(
container: MedusaContainer
) {
const { result } = await createCartWorkflow(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
### Cart Management
Store and manage carts, including their addresses, line items, shipping methods, and more.
```ts
const cart = await cartModuleService.createCarts({
currency_code: "usd",
shipping_address: {
address_1: "1512 Barataria Blvd",
country_code: "us",
},
items: [
{
title: "Shirt",
unit_price: 1000,
quantity: 1,
},
],
})
```
### Apply Promotions
Apply promotions or discounts to line items and shipping methods by adding adjustment lines that are factored into their subtotals.
```ts
const lineAdjustments = await cartModuleService.addLineItemAdjustments({
item_id: "cali_123",
code: "50OFF",
amount: 500,
})
const shippingAdjustments =
await cartModuleService.addShippingMethodAdjustments({
shipping_method_id: "casm_123",
code: "FREESHIPPING",
amount: 1000,
})
```
### Cart Context and Scoping
A cart is scoped to a sales channel, region, and a customer.
The Medusa application links the Cart Module to each of their respective modules, providing features like:
- Checking product availability in a sales channel.
- Retrieving pricing per region.
- Applying promotions based on the customer's group.
<CommerceModuleSections name="Cart" />