docs: add details on updating a cart's customer (#10226)
Should be merged after releasing v2.0.5 Closes DX-1096
This commit is contained in:
@@ -233,7 +233,7 @@ export const GET = async (
|
||||
const b = req.validatedQuery.b as number
|
||||
|
||||
res.json({
|
||||
sum: a + b
|
||||
sum: a + b,
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
@@ -149,7 +149,7 @@ class HelloModuleService {
|
||||
data: {
|
||||
id: "123",
|
||||
// other data payload
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -167,7 +167,7 @@ export const depsHighlight = [
|
||||
]
|
||||
|
||||
```ts title="medusa-config.ts" highlights={depsHighlight}
|
||||
import { Modules } from '@medusajs/framework/utils'
|
||||
import { Modules } from "@medusajs/framework/utils"
|
||||
|
||||
module.exports = defineConfig({
|
||||
// ...
|
||||
@@ -175,10 +175,10 @@ module.exports = defineConfig({
|
||||
{
|
||||
resolve: "./src/modules/hello",
|
||||
dependencies: [
|
||||
Modules.EVENT_BUS
|
||||
]
|
||||
}
|
||||
]
|
||||
Modules.EVENT_BUS,
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ const { data: productCustoms } = await query.graph({
|
||||
take: 5,
|
||||
skip: 0,
|
||||
},
|
||||
});
|
||||
})
|
||||
```
|
||||
|
||||
In the object passed to the `graph` method:
|
||||
@@ -318,9 +318,9 @@ export default defineMiddlewares({
|
||||
defaults: [
|
||||
"id",
|
||||
"name",
|
||||
"products.*"
|
||||
"products.*",
|
||||
],
|
||||
isList: true
|
||||
isList: true,
|
||||
}
|
||||
),
|
||||
],
|
||||
@@ -371,7 +371,7 @@ export const GET = async (
|
||||
|
||||
const { data: myCustoms } = await query.graph({
|
||||
entity: "my_custom",
|
||||
...req.remoteQueryConfig
|
||||
...req.remoteQueryConfig,
|
||||
})
|
||||
|
||||
res.json({ my_customs: myCustoms })
|
||||
|
||||
@@ -106,7 +106,7 @@ const myWorkflow = createWorkflow(
|
||||
const today = new Date()
|
||||
|
||||
return new WorkflowResponse({
|
||||
today
|
||||
today,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -117,7 +117,7 @@ const myWorkflow = createWorkflow(
|
||||
const today = transform({}, () => new Date())
|
||||
|
||||
return new WorkflowResponse({
|
||||
today
|
||||
today,
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
@@ -16,7 +16,7 @@ Each workflow step must have a unique ID, which is the ID passed as a first para
|
||||
|
||||
```ts
|
||||
const useQueryGraphStep = createStep(
|
||||
"use-query-graph",
|
||||
"use-query-graph"
|
||||
// ...
|
||||
)
|
||||
```
|
||||
@@ -29,13 +29,13 @@ const helloWorkflow = createWorkflow(
|
||||
() => {
|
||||
const { data: products } = useQueryGraphStep({
|
||||
entity: "product",
|
||||
fields: ["id"]
|
||||
fields: ["id"],
|
||||
})
|
||||
|
||||
// ERROR OCCURS HERE: A STEP HAS THE SAME ID AS ANOTHER IN THE WORKFLOW
|
||||
const { data: customers } = useQueryGraphStep({
|
||||
entity: "customer",
|
||||
fields: ["id"]
|
||||
fields: ["id"],
|
||||
})
|
||||
}
|
||||
)
|
||||
@@ -63,13 +63,13 @@ const helloWorkflow = createWorkflow(
|
||||
() => {
|
||||
const { data: products } = useQueryGraphStep({
|
||||
entity: "product",
|
||||
fields: ["id"]
|
||||
fields: ["id"],
|
||||
})
|
||||
|
||||
// ✓ No error occurs, the step has a different ID.
|
||||
const { data: customers } = useQueryGraphStep({
|
||||
entity: "customer",
|
||||
fields: ["id"]
|
||||
fields: ["id"],
|
||||
}).config({ name: "fetch-customers" })
|
||||
}
|
||||
)
|
||||
|
||||
@@ -54,8 +54,8 @@ export default async function orderPlacedHandler({
|
||||
await sendOrderConfirmationWorkflow(container)
|
||||
.run({
|
||||
input: {
|
||||
id: data.id
|
||||
}
|
||||
id: data.id,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -133,8 +133,8 @@ export const loaderHighlights = [
|
||||
|
||||
```ts title="src/modules/mongo/loaders/connection.ts" highlights={loaderHighlights}
|
||||
import { LoaderOptions } from "@medusajs/framework/types"
|
||||
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
|
||||
import { asValue } from "awilix";
|
||||
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
|
||||
import { asValue } from "awilix"
|
||||
import { MongoClient } from "mongodb"
|
||||
|
||||
type ModuleOptions = {
|
||||
@@ -144,7 +144,7 @@ type ModuleOptions = {
|
||||
|
||||
export default async function mongoConnectionLoader({
|
||||
container,
|
||||
options
|
||||
options,
|
||||
}: LoaderOptions<ModuleOptions>) {
|
||||
if (!options.connection_url) {
|
||||
throw new Error(`[MONGO MDOULE]: connection_url option is required.`)
|
||||
@@ -187,10 +187,10 @@ module.exports = defineConfig({
|
||||
resolve: "./src/modules/mongo",
|
||||
options: {
|
||||
connection_url: process.env.MONGO_CONNECTION_URL,
|
||||
db_name: process.env.MONGO_DB_NAME
|
||||
}
|
||||
}
|
||||
]
|
||||
db_name: process.env.MONGO_DB_NAME,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
@@ -239,11 +239,11 @@ export default class MongoModuleService {
|
||||
const moviesCol = this.mongoClient_.collection("movie")
|
||||
|
||||
const insertedMovie = await moviesCol.insertOne({
|
||||
title
|
||||
title,
|
||||
})
|
||||
|
||||
const movie = await moviesCol.findOne({
|
||||
_id: insertedMovie.insertedId
|
||||
_id: insertedMovie.insertedId,
|
||||
})
|
||||
|
||||
return movie
|
||||
@@ -254,8 +254,8 @@ export default class MongoModuleService {
|
||||
|
||||
await moviesCol.deleteOne({
|
||||
_id: {
|
||||
equals: id
|
||||
}
|
||||
equals: id,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -274,7 +274,7 @@ export const MONGO_MODULE = "mongo"
|
||||
|
||||
export default Module(MONGO_MODULE, {
|
||||
service: MongoModuleService,
|
||||
loaders: [mongoConnectionLoader]
|
||||
loaders: [mongoConnectionLoader],
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ export const highlights = [
|
||||
]
|
||||
|
||||
```ts highlights={highlights}
|
||||
import { MedusaRequest, MedusaResponse } from "@medusajs/framework";
|
||||
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
|
||||
import { MedusaRequest, MedusaResponse } from "@medusajs/framework"
|
||||
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
|
||||
|
||||
export async function GET(
|
||||
req: MedusaRequest,
|
||||
@@ -41,12 +41,12 @@ export async function GET(
|
||||
entity: "product",
|
||||
fields: ["*"],
|
||||
filters: {
|
||||
id: "prod_123"
|
||||
}
|
||||
id: "prod_123",
|
||||
},
|
||||
})
|
||||
|
||||
res.json({
|
||||
products
|
||||
products,
|
||||
})
|
||||
}
|
||||
```
|
||||
@@ -84,7 +84,7 @@ export const subscriberHighlights = [
|
||||
|
||||
```ts highlights={subscriberHighlights}
|
||||
import { SubscriberArgs, type SubscriberConfig } from "@medusajs/framework"
|
||||
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
|
||||
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
|
||||
|
||||
export default async function productCreateHandler({
|
||||
event: { data },
|
||||
@@ -96,8 +96,8 @@ export default async function productCreateHandler({
|
||||
entity: "product",
|
||||
fields: ["*"],
|
||||
filters: {
|
||||
id: data.id
|
||||
}
|
||||
id: data.id,
|
||||
},
|
||||
})
|
||||
|
||||
console.log(`You created a product with the title ${products[0].title}`)
|
||||
@@ -119,7 +119,7 @@ export const scheduledJobHighlights = [
|
||||
|
||||
```ts highlights={scheduledJobHighlights}
|
||||
import { MedusaContainer } from "@medusajs/framework/types"
|
||||
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
|
||||
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
|
||||
|
||||
export default async function myCustomJob(
|
||||
container: MedusaContainer
|
||||
@@ -130,8 +130,8 @@ export default async function myCustomJob(
|
||||
entity: "product",
|
||||
fields: ["*"],
|
||||
filters: {
|
||||
id: "prod_123"
|
||||
}
|
||||
id: "prod_123",
|
||||
},
|
||||
})
|
||||
|
||||
console.log(
|
||||
@@ -160,7 +160,7 @@ import {
|
||||
createStep,
|
||||
StepResponse,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
|
||||
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
|
||||
|
||||
const step1 = createStep("step-1", async (_, { container }) => {
|
||||
const query = container.resolve(ContainerRegistrationKeys.QUERY)
|
||||
@@ -169,8 +169,8 @@ const step1 = createStep("step-1", async (_, { container }) => {
|
||||
entity: "product",
|
||||
fields: ["*"],
|
||||
filters: {
|
||||
id: "prod_123"
|
||||
}
|
||||
id: "prod_123",
|
||||
},
|
||||
})
|
||||
|
||||
return new StepResponse(products)
|
||||
|
||||
@@ -37,7 +37,7 @@ import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const Post = model.define("post", {
|
||||
id: model.id().primaryKey(),
|
||||
title: model.text()
|
||||
title: model.text(),
|
||||
})
|
||||
|
||||
export default Post
|
||||
@@ -143,8 +143,8 @@ module.exports = defineConfig({
|
||||
},
|
||||
modules: [
|
||||
{
|
||||
resolve: "./src/modules/blog"
|
||||
}
|
||||
resolve: "./src/modules/blog",
|
||||
},
|
||||
],
|
||||
})
|
||||
```
|
||||
@@ -168,16 +168,16 @@ npx medusa db:generate blog
|
||||
The `db:generate` command of the Medusa CLI accepts one or more module names to generate the migration for. It will create a migration file for the Blog Module in the directory `src/modules/blog/migrations` similar to the following:
|
||||
|
||||
```ts
|
||||
import { Migration } from '@mikro-orm/migrations';
|
||||
import { Migration } from "@mikro-orm/migrations"
|
||||
|
||||
export class Migration20241121103722 extends Migration {
|
||||
|
||||
async up(): Promise<void> {
|
||||
this.addSql('create table if not exists "post" ("id" text not null, "title" text not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "post_pkey" primary key ("id"));');
|
||||
this.addSql("create table if not exists \"post\" (\"id\" text not null, \"title\" text not null, \"created_at\" timestamptz not null default now(), \"updated_at\" timestamptz not null default now(), \"deleted_at\" timestamptz null, constraint \"post_pkey\" primary key (\"id\"));")
|
||||
}
|
||||
|
||||
async down(): Promise<void> {
|
||||
this.addSql('drop table if exists "post" cascade;');
|
||||
this.addSql("drop table if exists \"post\" cascade;")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -226,10 +226,10 @@ import {
|
||||
createStep,
|
||||
createWorkflow,
|
||||
StepResponse,
|
||||
WorkflowResponse
|
||||
} from "@medusajs/framework/workflows-sdk";
|
||||
import { BLOG_MODULE } from "../modules/blog";
|
||||
import BlogModuleService from "../modules/blog/service";
|
||||
WorkflowResponse,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
import { BLOG_MODULE } from "../modules/blog"
|
||||
import BlogModuleService from "../modules/blog/service"
|
||||
|
||||
type CreatePostWorkflowInput = {
|
||||
title: string
|
||||
@@ -241,7 +241,7 @@ const createPostStep = createStep(
|
||||
const blogModuleService: BlogModuleService = container.resolve(BLOG_MODULE)
|
||||
|
||||
const post = await blogModuleService.createPosts({
|
||||
title
|
||||
title,
|
||||
})
|
||||
|
||||
return new StepResponse(post, post)
|
||||
@@ -272,11 +272,11 @@ You'll now execute that workflow in an API route to expose the feature of creati
|
||||
```ts
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse
|
||||
} from "@medusajs/framework/http";
|
||||
MedusaResponse,
|
||||
} from "@medusajs/framework/http"
|
||||
import {
|
||||
createPostWorkflow
|
||||
} from "../../../workflows/create-post";
|
||||
createPostWorkflow,
|
||||
} from "../../../workflows/create-post"
|
||||
|
||||
export async function POST(
|
||||
req: MedusaRequest,
|
||||
@@ -285,12 +285,12 @@ export async function POST(
|
||||
const { result: post } = await createPostWorkflow(req.scope)
|
||||
.run({
|
||||
input: {
|
||||
title: "My Post"
|
||||
}
|
||||
title: "My Post",
|
||||
},
|
||||
})
|
||||
|
||||
res.json({
|
||||
post
|
||||
post,
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
@@ -159,7 +159,7 @@ module.exports = defineConfig({
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
@@ -118,3 +118,5 @@ This is necessary, as only products matching the cart's sales channel(s) can be
|
||||
## Associate Customer with Cart
|
||||
|
||||
When the cart is created for a logged-in customer, it's automatically associated with that customer.
|
||||
|
||||
However, if the cart is created for a guest customer, then the customer logs in, then you have to set the cart's customer as explained in [this guide](../update/page.mdx#set-carts-customer).
|
||||
|
||||
@@ -46,3 +46,46 @@ fetch(`http://localhost:9000/store/carts/${cartId}`, {
|
||||
```
|
||||
|
||||
The Update Cart API route accepts a `region_id` request body parameter, whose value is the new region to associate with the cart.
|
||||
|
||||
---
|
||||
|
||||
## Set Cart's Customer
|
||||
|
||||
You might need to change the cart's customer in two cases:
|
||||
|
||||
- You created the cart for the customer as a guest, then they logged-in, so you want to associate the cart with them as a registered customer.
|
||||
- You're transfering the cart from one customer to another, which is useful in company setups, such as when implementing B2B commerce applicatons.
|
||||
|
||||
To set or change the cart's customer, send an authenticated `POST` request to the Set Cart's Customer API route:
|
||||
|
||||
<Note>
|
||||
|
||||
This API route is only available after [Medusa v2.0.5](https://github.com/medusajs/medusa/releases/tag/v2.0.5).
|
||||
|
||||
</Note>
|
||||
|
||||
```ts
|
||||
fetch(`http://localhost:9000/store/carts/${cartId}/customer`, {
|
||||
credentials: "include",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then(({ cart }) => {
|
||||
// use cart...
|
||||
console.log(cart)
|
||||
})
|
||||
```
|
||||
|
||||
To send an authenticated request, either use `credentials: include` if the customer is already authenticated with a cookie session, or pass the Authorization Bearer token in the request's header.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Learn more about authenticating customers in [this guide](../../customers/login/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
The cart is now associated with the logged-in customer.
|
||||
|
||||
Reference in New Issue
Block a user