docs: publish restructure (#3496)

* docs: added features and guides overview page

* added image

* added version 2

* added version 3

* added version 4

* docs: implemented new color scheme

* docs: redesigned sidebar (#3193)

* docs: redesigned navbar for restructure (#3199)

* docs: redesigned footer (#3209)

* docs: redesigned cards (#3230)

* docs: redesigned admonitions (#3231)

* docs: redesign announcement bar (#3236)

* docs: redesigned large cards (#3239)

* docs: redesigned code blocks (#3253)

* docs: redesigned search modal and page (#3264)

* docs: redesigned doc footer (#3268)

* docs: added new sidebars + refactored css and assets (#3279)

* docs: redesigned api reference sidebar

* docs: refactored css

* docs: added code tabs transition

* docs: added new sidebars

* removed unused assets

* remove unusued assets

* Fix deploy errors

* fix incorrect link

* docs: fixed code responsivity + missing icons (#3283)

* docs: changed icons (#3296)

* docs: design fixes to the sidebar (#3297)

* redesign fixes

* docs: small design fixes

* docs: several design fixes after restructure (#3299)

* docs: bordered icon fixes

* docs: desgin fixes

* fixes to code blocks and sidebar scroll

* design adjustments

* docs: restructured homepage (#3305)

* docs: restructured homepage

* design fixes

* fixed core concepts icon

* docs: added core concepts page (#3318)

* docs: restructured homepage

* design fixes

* docs: added core concepts page

* changed text of different components

* docs: added architecture link

* added missing prop for user guide

* docs: added regions overview page (#3327)

* docs: added regions overview

* moved region pages to new structure

* docs: fixed description of regions architecture page

* small changes

* small fix

* docs: added customers overview page (#3331)

* docs: added regions overview

* moved region pages to new structure

* docs: fixed description of regions architecture page

* small changes

* small fix

* docs: added customers overview page

* fix link

* resolve link issues

* docs: updated regions architecture image

* docs: second-iteration fixes (#3347)

* docs: redesigned document

* design fixes

* docs: added products overview page (#3354)

* docs: added carts overview page (#3363)

* docs: added orders overview (#3364)

* docs: added orders overview

* added links in overview

* docs: added vercel redirects

* docs: added soon badge for cards (#3389)

* docs: resolved feedback changes + organized troubleshooting pages (#3409)

* docs: resolved feedback changes

* added extra line

* docs: changed icons for restructure (#3421)

* docs: added taxes overview page (#3422)

* docs: added taxes overview page

* docs: fix sidebar label

* added link to taxes overview page

* fixed link

* docs: fixed sidebar scroll (#3429)

* docs: added discounts overview (#3432)

* docs: added discounts overview

* fixed links

* docs: added gift cards overview (#3433)

* docs: added price lists overview page (#3440)

* docs: added price lists overview page

* fixed links

* docs: added sales channels overview page (#3441)

* docs: added sales overview page

* fixed links

* docs: added users overview (#3443)

* docs: fixed sidebar border height (#3444)

* docs: fixed sidebar border height

* fixed svg markup

* docs: added possible solutions to feedback component (#3449)

* docs: added several overview pages + restructured files (#3463)

* docs: added several overview pages

* fixed links

* docs: added feature flags + PAK overview pages (#3464)

* docs: added feature flags + PAK overview pages

* fixed links

* fix link

* fix link

* fixed links colors

* docs: added strategies overview page (#3468)

* docs: automated upgrade guide (#3470)

* docs: automated upgrade guide

* fixed vercel redirect

* docs: restructured files in docs codebase (#3475)

* docs: restructured files

* docs: fixed eslint exception

* docs: finished restructure loose-ends (#3493)

* fixed uses of backend

* docs: finished loose ends

* eslint fixes

* fixed links

* merged master

* added update instructions for v1.7.12
This commit is contained in:
Shahed Nasser
2023-03-16 17:03:10 +02:00
committed by GitHub
parent f312ce1e0f
commit 1decaa27c7
415 changed files with 12422 additions and 5098 deletions
@@ -0,0 +1,799 @@
---
description: 'Learn how to implement sales channels features for admins in Medusa using the REST APIs. This includes how to list sales channels, and create, retrieve, update and delete a sales channel. This also includes how to manage products in a sales channel.'
addHowToData: true
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# How to Manage Sales Channels
In this document, youll learn how to manage sales channels and their products and orders using the Admin APIs.
:::note
If youre looking to learn more in-depth about what Sales Channels are and how they work, check out [this documentation](../sales-channels.md) instead.
:::
## Overview
Using Medusas Admin APIs, you can manage Sales Channels including creating, retrieving, updating, and deleting sales channels. You can also manage their products and orders.
This guide explains how to perform all these operations using the Admin APIs.
---
## Prerequisites
### Medusa Components
It's assumed that you already have a Medusa backend installed and set up. If not, you can follow our [quickstart guide](../../../development/backend/install.mdx) to get started.
### JS Client
This guide includes code snippets to send requests to your Medusa backend using Medusas JS Client, among other methods.
If you follow the JS Client code blocks, its assumed you already have [Medusas JS Client installed](../../../js-client/overview.md) and [have created an instance of the client](../../../js-client/overview.md#configuration).
### Medusa React
This guide also includes code snippets to send requests to your Medusa backend using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../../medusa-react/overview.md#usage).
### Authenticated Admin User
You must be an authenticated admin user before following along with the steps in this guide.
You can learn more about [authenticating as an admin user in the API reference](/api/admin/#section/Authentication).
---
## Create Sales Channels
You can create a sales channel by sending a request to the Create a Sales Channel endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.salesChannels.create({
name: "App",
description: "Mobile app",
})
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminCreateSalesChannel } from "medusa-react"
const CreateSalesChannel = () => {
const createSalesChannel = useAdminCreateSalesChannel()
// ...
const handleCreate = (name: string, description: string) => {
createSalesChannel.mutate({
name,
description,
})
}
// ...
}
export default CreateSalesChannel
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/admin/sales-channels`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "App",
description: "Mobile app",
}),
})
.then((response) => response.json())
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X POST '<BACKEND_URL>/admin/sales-channels' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
name: 'App',
description: 'Mobile app'
}'
```
</TabItem>
</Tabs>
This request requires the request body parameters `name`, and optionally accepts the `description` and `is_disabled` request body parameters.
It returns the created sales channel.
---
## List Sales Channels
You can list all sales channels by sending a request to the List Sales Channels endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.salesChannels.list()
.then(({ sales_channels, limit, offset, count }) => {
console.log(sales_channels.length)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { SalesChannel } from "@medusajs/medusa"
import { useAdminSalesChannels } from "medusa-react"
const SalesChannels = () => {
const { sales_channels, isLoading } = useAdminSalesChannels()
return (
<div>
{isLoading && <span>Loading...</span>}
{sales_channels && !sales_channels.length && (
<span>No Sales Channels</span>
)}
{sales_channels && sales_channels.length > 0 && (
<ul>
{sales_channels.map((salesChannel: SalesChannel) => (
<li key={salesChannel.id}>{salesChannel.name}</li>
))}
</ul>
)}
</div>
)
}
export default SalesChannels
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/admin/sales-channels`, {
credentials: "include",
})
.then((response) => response.json())
.then(({ sales_channels, limit, offset, count }) => {
console.log(sales_channels.length)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X GET '<BACKEND_URL>/admin/sales-channels' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
</Tabs>
This request returns an array of all sales channels in your store. You can also pass query parameters to filter or customize the pagination of the results. Check out [the API Reference for a full list of query parameters.](/api/admin/#tag/Sales-Channel/operation/GetSalesChannels)
---
## Retrieve a Sales Channel
You can retrieve a sales channels details by its ID using the Get Sales Channel endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.salesChannels.retrieve(salesChannelId)
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminSalesChannel } from "medusa-react"
const SalesChannel = () => {
const {
sales_channel,
isLoading,
} = useAdminSalesChannel(salesChannelId)
return (
<div>
{isLoading && <span>Loading...</span>}
{sales_channel && <span>{sales_channel.name}</span>}
</div>
)
}
export default SalesChannel
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/admin/sales-channels/${salesChannelId}`, {
credentials: "include",
})
.then((response) => response.json())
.then(({ sales_channels, limit, offset, count }) => {
console.log(sales_channels.length)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X GET '<BACKEND_URL>/admin/sales-channels/<SALES_CHANNEL_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
</Tabs>
This request returns the sales channel with the specified ID.
---
## Update a Sales Channel
You can update a Sales Channels details and attributes by sending a request to the Update Sales Channel endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.salesChannels.update(salesChannelId, {
is_disabled: false,
})
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminUpdateSalesChannel } from "medusa-react"
const UpdateSalesChannel = () => {
const updateSalesChannel = useAdminUpdateSalesChannel(
salesChannelId
)
// ...
const handleUpdate = () => {
updateSalesChannel.mutate({
is_disabled: false,
})
}
// ...
}
export default UpdateSalesChannel
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/admin/sales-channels/${salesChannelId}`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
is_disabled: false,
}),
})
.then((response) => response.json())
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X POST '<BACKEND_URL>/admin/sales-channels/<SALES_CHANNEL_ID>' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"is_disabled": false
}'
```
</TabItem>
</Tabs>
In this example, you enable a sales channel by changing the value of the `is_disabled` attribute.
This request returns the updated sales channel.
You can check out [the API Reference for a full list of body parameters](/api/admin/#tag/Sales-Channel/operation/PostSalesChannelsSalesChannel) that you can pass to this request.
---
## Delete a Sales Channel
You can delete a sales channel by sending a request to the Delete Sales Channel endpoint with the ID of the sales channel to delete:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.salesChannels.delete(salesChannelId)
.then(({ id, object, deleted }) => {
console.log(id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDeleteSalesChannel } from "medusa-react"
const SalesChannel = () => {
const deleteSalesChannel = useAdminDeleteSalesChannel(
salesChannelId
)
// ...
const handleDelete = () => {
deleteSalesChannel.mutate()
}
// ...
}
export default SalesChannel
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/admin/sales-channels/${salesChannelId}`, {
method: "DELETE",
credentials: "include",
})
.then((response) => response.json())
.then(({ id, object, deleted }) => {
console.log(id)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X DELETE '<BACKEND_URL>/admin/sales-channels/<SALES_CHANNEL_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
</Tabs>
The ID of the deleted sales channel is returned in the response.
---
## Manage Products
### Add Product to a Sales Channel
To add a product to a sales channel, send a request to the Sales Channels Add Products endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.salesChannels.addProducts(salesChannelId, {
product_ids: [
{
id: productId,
},
],
})
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminAddProductsToSalesChannel } from "medusa-react"
const SalesChannel = () => {
const addProducts = useAdminAddProductsToSalesChannel(
salesChannelId
)
// ...
const handleAddProducts = (productId: string) => {
addProducts.mutate({
product_ids: [
{
id: productId,
},
],
})
}
// ...
}
export default SalesChannel
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
<!-- eslint-disable max-len -->
```ts
fetch(
`<BACKEND_URL>/admin/sales-channels/${salesChannelId}/products/batch`,
{
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
product_ids: [
{
id: productId,
},
],
}),
}
)
.then((response) => response.json())
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X POST '<BACKEND_URL>/admin/sales-channels/<SALES_CHANNEL_ID>/products/batch' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"product_ids": [
{
"id": "<PRODUCT_ID>"
}
]
}'
```
</TabItem>
</Tabs>
This request accepts the `product_ids` body parameter, which is an array of objects. Each object in the array must have an `id` property with the ID of the product to add as a value.
This request returns the sales channel.
### List Products Available in a Sales Channel
You can list the products available in a sales channel by sending a request to the List Products endpoint and passing the `sales_channel_id` query parameter to filter by a specific sales channel:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.products.list({
sales_channel_id: [
salesChannelId,
],
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { Product } from "@medusajs/medusa"
import {
PricedProduct,
} from "@medusajs/medusa/dist/types/pricing"
import { useAdminProducts } from "medusa-react"
const SalesChannelProducts = () => {
const { products, isLoading } = useAdminProducts({
sales_channel_id: [salesChannelId],
})
return (
<div>
{isLoading && <span>Loading...</span>}
{products && products.length > 0 && (
<ul>
{products.map(
(product: (Product | PricedProduct)) => (
<li key={product.id}>{product.title}</li>
)
)}
</ul>
)}
{products && !products.length && (
<span>No Products</span>
)}
</div>
)
}
export default SalesChannelProducts
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
<!-- eslint-disable max-len -->
```ts
fetch(
`<BACKEND_URL>/admin/products?sales_channel_id[0]=${salesChannelId}`,
{
credentials: "include",
}
)
.then((response) => response.json())
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X GET '<BACKEND_URL>/admin/products?sales_channel_id[0]=<SALES_CHANNEL_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
</Tabs>
The request returns an array of products that are available in the specified sales channel.
### Delete Products from a Sales Channel
:::info
Deleting a product from a sales channel doesn't delete it completely. It only makes it unavailable in that sales channel.
:::
You can delete a product from a sales channel by sending a request to the Sales Channels Delete Products endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
<!-- eslint-disable max-len -->
```ts
medusa.admin.salesChannels.removeProducts(salesChannelId, {
product_ids: [
{
id: productId,
},
],
})
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import {
useAdminDeleteProductsFromSalesChannel,
} from "medusa-react"
const SalesChannel = () => {
const deleteProducts = useAdminDeleteProductsFromSalesChannel(
salesChannelId
)
// ...
const handleDeleteProducts = (productId: string) => {
deleteProducts.mutate({
product_ids: [
{
id: productId,
},
],
})
}
// ...
}
export default SalesChannel
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
<!-- eslint-disable max-len -->
```ts
fetch(
`<BACKEND_URL>/admin/sales-channels/${salesChannelId}/products/batch`,
{
method: "DELETE",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
product_ids: [
{
id: productId,
},
],
}),
}
)
.then((response) => response.json())
.then(({ sales_channel }) => {
console.log(sales_channel.id)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X DELETE '<BACKEND_URL>/admin/sales-channels/<SALES_CHANNEL_ID>/products/batch' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"product_ids": [
{
"id": "<PRODUCT_ID>"
}
]
}'
```
</TabItem>
</Tabs>
This request accepts the `product_ids` body parameter, which is an array of objects. Each object in the array must have an `id` property with the ID of the product to delete as a value.
This request returns the sales channel.
---
## List Orders by Sales Channels
You can filter orders by a specific sales channel by sending a request to the List Orders endpoint and passing the `sales_channel_id` query parameter to filter by a specific sales channel:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.admin.orders.list({
sales_channel_id: [
salesChannelId,
],
limit: 50,
offset: 0,
})
.then(({ orders, limit, offset, count }) => {
console.log(orders.length)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { Order } from "@medusajs/medusa"
import { useAdminOrders } from "medusa-react"
const SalesChannelOrders = () => {
const { orders, isLoading } = useAdminOrders({
sales_channel_id: [salesChannelId],
offset: 0,
limit: 50,
})
return (
<div>
{isLoading && <span>Loading...</span>}
{orders && orders.length > 0 && (
<ul>
{orders.map((order: Order) => (
<li key={order.id}>{order.display_id}</li>
))}
</ul>
)}
{orders && !orders.length && <span>No Orders</span>}
</div>
)
}
export default SalesChannelOrders
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
<!-- eslint-disable max-len -->
```ts
fetch(`<BACKEND_URL>/admin/orders?sales_channel_id[0]=${salesChannelId}`, {
credentials: "include",
})
.then((response) => response.json())
.then(({ orders, limit, offset, count }) => {
console.log(orders.length)
})
```
</TabItem>
<TabItem value="curl" label="cURL">
```bash
curl -L -X GET '<BACKEND_URL>/admin/orders?sales_channel_id[0]=<SALES_CHANNEL_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
```
</TabItem>
</Tabs>
The request returns an array of orders that are associated with the specified sales channel.
@@ -0,0 +1,124 @@
---
description: "Sales channels are different methods a business offers its products for purchase for the customers. Learn about the available features and guides."
---
import DocCardList from '@theme/DocCardList';
import DocCard from '@theme/DocCard';
import Icons from '@theme/Icon';
# Sales Channels
Sales channels are different methods a business offers its products for purchase for the customers. This overview introduces the available features related to sales channels.
:::note
Not a developer? Check out the [Sales Channels user guide](../../user-guide/sales-channels/index.md).
:::
## Features
### Sales Channel Management
Admins can manage sales channels, creating an unlimited number of them. They specify the products availability for each sales channel.
<DocCardList colSize={4} items={[
{
type: 'link',
href: '/modules/sales-channels/admin/manage',
label: 'Admin: Manage Sales Channels',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to manage sales channels using the Admin APIs.'
}
},
{
type: 'link',
href: '/user-guide/sales-channels/manage',
label: 'User Guide: Manage Sales Channels',
customProps: {
icon: Icons['users-solid'],
description: 'Learn how to manage sales channels using Medusa Admin.'
}
},
{
type: 'link',
href: '/user-guide/sales-channels/products',
label: 'User Guide: Manage Products',
customProps: {
icon: Icons['users-solid'],
description: 'Learn how to manage products in a sales channel using Medusa Admin.'
}
},
]} />
### Sales Channels for Each Platform
Developers can associate a platform with a sales channel. For example, associating a storefront with a web sales channel. Only products available in that sales channel will be shown, and all orders placed on that sales channel will be associated with it.
Admins can filter orders by a sales channel. This would allow them to handle orders coming from each sales channel differently.
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/modules/sales-channels/storefront/use-sales-channels',
label: 'Storefront: Use Sales Channels',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to use sales channels in a storefront.'
}
},
{
type: 'link',
href: '/modules/sales-channels/admin/manage#list-orders-by-sales-channels',
label: 'Admin: Orders by Sales Channels',
customProps: {
icon: Icons['academic-cap-solid'],
description: 'Learn how to filter orders by a sales channel.'
}
},
]} />
---
## Understand the Architecture
Learn how sales channel related entities and concepts are built, their relation to other modules, and more.
<DocCard item={{
type: 'link',
href: '/modules/sales-channels',
label: 'Architecture: Sales Channel',
customProps: {
icon: Icons['circle-stack-solid'],
description: 'Learn about the Sales Channels architecture.'
}
}}
/>
---
## Related Modules
Discover Sales Channels relation to other modules in Medusa.
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/modules/products/overview',
label: 'Product',
customProps: {
icon: Icons['tag-solid'],
description: 'Products availability can be changed for each sales channel.'
}
},
{
type: 'link',
href: '/modules/orders/overview',
label: 'Orders',
customProps: {
icon: Icons['shopping-cart-solid'],
description: 'Orders can be associated and organized by a sales channel.'
}
},
]} />
@@ -0,0 +1,67 @@
---
description: 'Learn what Sales Channels are and how they can be used in Medusa. Sales Channels allow merchants to separate between the different channels products are sold in.'
---
# Sales Channels
In this document, youll learn about Sales Channels and how they can be used in Medusa.
## Introduction
Sales Channels allow you to separate between the different channels you sell products in. For example, you can have a sales channel for your website and another for your mobile apps.
Sales Channels are associated with stores, products, carts, and orders: A store has a default sales channel; you can define which products are available in a sales channel; you can specify the sales channel of a cart; you can filter orders by sales channel.
### Example Use Cases
The sales channel feature can be used in a variety of use cases including:
- Implement a B2B Ecommerce Store.
- Specifying different products for each channel you sell in.
- Support Omnichannel in your ecommerce store.
---
## SalesChannel Entity Overview
A sales channel is stored in the database as a [SalesChannel](../../references/entities/classes/SalesChannel.md) entity. Some of its important attributes are:
- `name`: The name of the sales channel.
- `is_disabled`: A boolean value indicating of the Sales Channel is disabled or not.
---
## Relations to Other Entities
### Store
A store has a default sales channel. When you first run your Medusa backend or seed your database, a default sales channel is created, if it doesnt exist, and associated with the store.
The relation is implemented in the [Store](../../references/entities/classes/Store.md) entity. You can access the default sales channel of a store by expanding the `default_sales_channel` relation and using `store.default_sales_channel`. You can also access the ID of the default sales channel using `store.default_sales_channel_id`.
### Product
Products can be available in more than one sales channel. You can then filter products by a sales channel using the Storefront and Admin APIs.
The relation is implemented in the [Product](../../references/entities/classes/Product.md) entity. You can access the sales channels a product is available in by expanding the `sales_channels` relation and using `product.sales_channels`.
### Cart
When you create a cart, you can optionally specify the sales channel it belongs to. If you dont set the sales channel, the stores default sales channel will be associated with it.
A cart can belong to only one sales channel. Only products that belong to the same sales channel as the cart can be added to it.
The relation is implemented in the [Cart](../../references/entities/classes/Cart.md) entity. You can access the sales channel a cart is associated with by expanding the `sales_channel` relation and using `cart.sales_channel`. You can also access the ID of the sales channel using `cart.sales_channel_id`.
### Order
Orders can optionally be associated with a sales channel. You can filter orders by a sales channel using the Storefront and Admin APIs.
The relation is implemented in the [Order](../../references/entities/classes/Order.md) entity. You can access the sales channel an order is associated with by expanding the `sales_channel` relation and using `order.sales_channel`. You can also access the ID of the sales channel using `order.sales_channel_id`.
---
## See Also
- [Manage sales channels using the admin APIs](./admin/manage.mdx)
- [Use sales channels in the storefront](./storefront/use-sales-channels.mdx)
@@ -0,0 +1,256 @@
---
description: 'Learn how to implement sales channel functionalities in the storefront using REST APIs. This includes filtering products by Sales Channel and associating a cart with a sales channel.'
addHowToData: true
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# How to Use Sales Channels in Storefronts
In this document, youll learn how to use sales channels in your storefront.
## Overview
In your storefront, you can filter products by sales channels. You can also associate carts with a sales channel.
This guide explains how to perform these operations using the Storefront APIs.
### Alternative Approach: Publishable API keys
This guide covers how to pass the sales channel ID into different requests to retrieve or process data associated with the sales channel.
An alternative approach is to use Publishable API keys. You can learn how to use them in the following documents:
- [Using publishable API keys in requests](../../../development/publishable-api-keys/index.mdx)
- Managing publishable API keys using [admin APIs](../../../development/publishable-api-keys/admin/manage-publishable-api-keys.mdx) or using [Medusa Admin](../../../user-guide/settings/publishable-api-keys.mdx)
---
## Prerequisites
### Medusa Components
It's assumed that you already have a Medusa backend installed and set up. If not, you can follow our [quickstart guide](../../../development/backend/install.mdx) to get started.
It is also assumed you already have a storefront set up. It can be a custom storefront or one of Medusas storefronts. If you dont have a storefront set up, you can install either the [Next.js](../../../starters/nextjs-medusa-starter.mdx) or [Gatsby](../../../starters/gatsby-medusa-starter.mdx) storefronts.
### JS Client
This guide includes code snippets to send requests to your Medusa backend using Medusas JS Client, among other methods.
If you follow the JS Client code blocks, its assumed you already have [Medusas JS Client installed](../../../js-client/overview.md) and have [created an instance of the client](../../../js-client/overview.md#configuration).
### Medusa React
This guide also includes code snippets to send requests to your Medusa backend using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../../medusa-react/overview.md#usage).
For requests that use the cart, it's also assumed you already have [used CartProvider higher in your component tree](../../../medusa-react/overview.md#cartprovider).
---
## Filter Products by Sales Channel
To filter products by a specific sales channel, pass the `sales_channel_id` query parameter to the List Products endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.products.list({
sales_channel_id: [
salesChannelId,
],
})
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { Product } from "@medusajs/medusa"
import { useProducts } from "medusa-react"
const Products = () => {
const { products, isLoading } = useProducts({
sales_channel_id: [
salesChannelId,
],
})
return (
<div>
{isLoading && <span>Loading...</span>}
{products && products.length > 0 && (
<ul>
{products.map((product: Product) => (
<li key={product.id}>{product.title}</li>
))}
</ul>
)}
{products && !products.length && <span>No Products</span>}
</div>
)
}
export default Products
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
<!-- eslint-disable max-len -->
```ts
fetch(`<BACKEND_URL>/store/products?sales_channel_id[0]=${salesChannelId}`)
.then((response) => response.json())
.then(({ products, limit, offset, count }) => {
console.log(products.length)
})
```
</TabItem>
</Tabs>
The `sales_channel_id` query parameter is an array of sales channel IDs. You can pass more than one sales channel.
The request returns an array of products. These are the products that are available in the sales channel.
---
## Associate a Cart with a Sales Channel
### When Creating a Cart
To associate a sales channel with a cart while creating it, you can pass the `sales_channel_id` request body parameter with the ID of the sales channel:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.carts.create({
sales_channel_id: salesChannelId,
})
.then(({ cart }) => {
console.log(cart.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
const Cart = () => {
const { cart, createCart } = useCart()
const handleCreateCart = () => {
createCart.mutate(
{
sales_channel_id: salesChannelId,
},
{
onSuccess: ({ cart }) => {
localStorage.setItem("cart_id", cart.id)
},
}
)
}
// ...
}
export default Cart
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/store/carts`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
sales_channel_id: salesChannelId,
}),
})
.then((response) => response.json())
.then(({ cart }) => {
console.log(cart.id)
})
```
</TabItem>
</Tabs>
The request returns the created cart.
### Updating an Existing Cart
You can update the sales channel of an existing cart by passing the `sales_channel_id` request body parameter with the ID of the sales channel:
<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>
```ts
medusa.carts.update(cartId, {
sales_channel_id: salesChannelId,
})
.then(({ cart }) => {
console.log(cart.id)
})
```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
const Cart = () => {
// ...
const { updateCart } = useCart()
const changeSalesChannel = (salesChannelId: string) => {
updateCart.mutate({
sales_channel_id: salesChannelId,
})
}
// ...
}
export default Cart
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<BACKEND_URL>/store/carts/${cartId}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
sales_channel_id: salesChannelId,
}),
})
.then((response) => response.json())
.then(({ cart }) => console.log(cart.id))
```
</TabItem>
</Tabs>
The request returns the updated cart.