Merge branch 'master' into develop
This commit is contained in:
@@ -327,7 +327,7 @@ If you run your Gatsby storefront while the Medusa server is running, you should
|
||||
|
||||

|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn how to [deploy your Medusa server](../deployments/server/index.mdx).
|
||||
- Learn how to [deploy your Gatsby storefront](../deployments/storefront/deploying-gatsby-on-netlify.md).
|
||||
|
||||
@@ -308,7 +308,7 @@ Restart the Gatsby storefront then open a product that you added Rich Text conte
|
||||
|
||||

|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn how to deploy your Medusa server to [Heroku](../../deployments/server/deploying-on-heroku.mdx), [Qovery](../../deployments/server/deploying-on-qovery.md), or [DigitalOcean](../../deployments/server/deploying-on-digital-ocean.md).
|
||||
- Learn [how to deploy your Gatsby storefront to Netlify](../../deployments/storefront/deploying-gatsby-on-netlify.md).
|
||||
|
||||
@@ -274,7 +274,7 @@ If you make changes to the data while your Gatsby storefront is running, the cha
|
||||
|
||||
:::
|
||||
|
||||
## What’s Next :rocket:
|
||||
## What’s Next
|
||||
|
||||
- Learn [how to customize your Contentful server and storefront](./customize-contentful.md).
|
||||
- Learn how to deploy your Medusa server to [Heroku](../../deployments/server/deploying-on-heroku.mdx), [Qovery](../../deployments/server/deploying-on-qovery.md), or [DigitalOcean](../../deployments/server/deploying-on-digital-ocean.md).
|
||||
|
||||
@@ -177,7 +177,7 @@ This will result in a subscription form similar to the following:
|
||||
|
||||
If you try entering an email and clicking Subscribe, the email will be subscribed to your Mailchimp newsletter successfully.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Check out [SendGrid plugin](../add-plugins/sendgrid.mdx) for more Email functionalities.
|
||||
- [Learn more about plugins.](../advanced/backend/plugins/overview.md)
|
||||
|
||||
@@ -286,7 +286,7 @@ If you run your Gatsby storefront while the Medusa server and the MeiliSearch in
|
||||
|
||||

|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn how to [deploy your Medusa server](../deployments/server/index.mdx).
|
||||
- Learn how to [deploy your Gatsby storefront](./../deployments/storefront/deploying-gatsby-on-netlify.md).
|
||||
|
||||
@@ -199,6 +199,6 @@ module.exports = {
|
||||
|
||||
Where `127.0.0.1` is the domain of your local MinIO server.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Check out [more plugins](https://github.com/medusajs/medusa/tree/master/packages) you can add to your store.
|
||||
|
||||
@@ -394,6 +394,6 @@ Clicking this button lets you capture the payment for an order. You can also ref
|
||||
|
||||
Refunding or Capturing payments is reflected in your PayPal dashboard as well.
|
||||
|
||||
## What's Next 🚀
|
||||
## What's Next
|
||||
|
||||
- Check out [more plugins](https://github.com/medusajs/medusa/tree/master/packages) you can add to your store.
|
||||
|
||||
@@ -170,7 +170,7 @@ module.exports = withStoreConfig({
|
||||
|
||||
Where `<BUCKET_NAME>` is the name of the S3 bucket you’re using.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Check out [more plugins](https://github.com/medusajs/medusa/tree/master/packages) you can add to your store.
|
||||
- Learn how to [deploy the Medusa server](../deployments/server/index.mdx).
|
||||
|
||||
@@ -185,7 +185,7 @@ After adding the above subscriber, run your server again if it isn’t running a
|
||||
|
||||

|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn how [services](../advanced/backend/services/create-service.md) and [subscribers](../advanced/backend/subscribers/create-subscriber.md) work.
|
||||
- Check out a [full list of events](../advanced/backend/subscribers/events-list.md) in Medusa.
|
||||
|
||||
@@ -3961,7 +3961,7 @@ You can also track analytics related to emails sent from the SendGrid dashboard.
|
||||
|
||||

|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn more about how [Notifications work in Medusa](../advanced/backend/notification/overview.md).
|
||||
- Install the [Medusa admin](https://github.com/medusajs/admin#-setting-up-admin) for functionalities like Gift Cards creation, swaps, claims, order return requests, and more.
|
||||
@@ -95,7 +95,7 @@ const plugins = [
|
||||
|
||||
That’s all you need to do to integrate Slack into Medusa!
|
||||
|
||||
## What's Next :rocket:
|
||||
## What's Next
|
||||
|
||||
- Install [Medusa's Admin](https://github.com/medusajs/admin) for the full order-management experience.
|
||||
- Add a Storefront to your Medusa server using [the Next.js starter](https://docs.medusajs.com/starters/nextjs-medusa-starter) or [the Gatsby starter](https://docs.medusajs.com/starters/gatsby-medusa-starter).
|
||||
|
||||
@@ -157,7 +157,7 @@ module.exports = withStoreConfig({
|
||||
|
||||
Where `<YOUR_SPACE_DOMAIN>` is the domain name for your Space which can be retrieved from the Space URL. For example, `medusa-server.fra1.digitaloceanspaces.com`.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Check out [more plugins](https://github.com/medusajs/medusa/tree/master/packages) you can add to your store.
|
||||
- Learn how to [deploy the Medusa server on DigitalOcean](../deployments/server/deploying-on-digital-ocean.md).
|
||||
|
||||
@@ -4,7 +4,7 @@ In this document, you’ll learn how to integrate Strapi with Medusa to add rich
|
||||
|
||||
:::info
|
||||
|
||||
This plugin is a [community plugin](https://github.com/Deathwish98/medusa-plugin-strapi) and is not managed by the official Medusa team.
|
||||
This plugin is a [community plugin](https://github.com/Deathwish98/medusa-plugin-strapi) and is not managed by the official Medusa team. At the moment, it supports v4 of Strapi.
|
||||
|
||||
:::
|
||||
|
||||
@@ -172,7 +172,7 @@ Try updating any products on Strapi by going to Content Manager → Products and
|
||||
|
||||
If you try to update products on Medusa either using the [REST APIs](https://docs.medusajs.com/api/admin/#tag/Product/operation/PostProductsProduct) or using [the Medusa Admin](../user-guide/products/manage.mdx), you’ll see that the product is also updated on Strapi.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn [how to deploy the Medusa server](../deployments/server/index.mdx).
|
||||
- Learn [how to create your own plugin](../advanced/backend/plugins/create.md).
|
||||
|
||||
@@ -356,6 +356,6 @@ Clicking this button allows you to capture the payment for an order. You can als
|
||||
|
||||
Refunding or Capturing payments is reflected in your Stripe’s dashboard as well. This gives you access to all of Stripe’s analytical capabilities.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Check out [more plugins](https://github.com/medusajs/medusa/tree/master/packages) you can add to your store.
|
||||
|
||||
@@ -122,7 +122,7 @@ If you’re on a Twilio trial make sure that the phone number you entered on che
|
||||
|
||||

|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn more about how [Notifications work in Medusa](../advanced/backend/notification/overview.md).
|
||||
- Install the [Medusa admin](../admin/quickstart.md) for functionalities like Gift Cards creation, swaps, claims, order return requests, and more.
|
||||
|
||||
@@ -113,7 +113,7 @@ Medusa admin provides a lot of ecommerce features including managing Return Merc
|
||||
|
||||
You can learn more about Medusa admin and its features in the [User Guide](../user-guide/index.mdx).
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Install the [Next.js](../starters/nextjs-medusa-starter.md) or [Gatsby](../starters/gatsby-medusa-starter.md) storefront starters.
|
||||
- [Learn how you can use `create-medusa-app` to install all of Medusa’s 3 components.](../usage/create-medusa-app.mdx)
|
||||
|
||||
@@ -89,7 +89,7 @@ fetch(`<YOUR_SERVER>/admin/uploads`, {
|
||||
|
||||
```bash
|
||||
curl --location --request POST '<YOUR_SERVER>/admin/uploads' \
|
||||
--header 'Authorization: Bearer {api_token}' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>' \
|
||||
--header 'Content-Type: text/csv' \
|
||||
--form 'files=@"<FILE_PATH_1>"'
|
||||
```
|
||||
@@ -149,7 +149,7 @@ fetch(`<YOUR_SERVER>/admin/batch-jobs`, {
|
||||
|
||||
```bash
|
||||
curl --location --request POST '<YOUR_SERVER>/admin/batch-jobs' \
|
||||
--header 'Authorization: Bearer {api_token}' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"type": "product-import",
|
||||
@@ -210,7 +210,7 @@ fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}`)
|
||||
|
||||
```bash
|
||||
curl --location --request GET '<YOUR_SERVER>/admin/batch-jobs/<BATCH_JOB_ID>' \
|
||||
--header 'Authorization: Bearer {api_token}'
|
||||
--header 'Authorization: Bearer <API_TOKEN>'
|
||||
# <BATCH_JOB_ID> is the ID of the batch job
|
||||
```
|
||||
|
||||
@@ -271,7 +271,7 @@ fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}/confirm`, {
|
||||
|
||||
```bash
|
||||
curl --location --request POST '<YOUR_SERVER>/admin/batch-jobs/<BATCH_JOB_ID>/confirm' \
|
||||
--header 'Authorization: Bearer {api_token}'
|
||||
--header 'Authorization: Bearer <API_TOKEN>'
|
||||
# <BATCH_JOB_ID> is the ID of the batch job
|
||||
```
|
||||
|
||||
@@ -288,7 +288,7 @@ After confirming the batch job, you can check the status while it is processing
|
||||
- If the status is `failed`, it means an error has occurred during the import. You can check the error in `result.errors`.
|
||||
- If the status is `completed`, it means the import has finished successfully.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn more about [Batch Jobs and how they work](../backend/batch-jobs/index.md).
|
||||
- Check out the [Batch Jobs API Reference](https://docs.medusajs.com/api/admin/#tag/Batch-Job).
|
||||
|
||||
@@ -0,0 +1,463 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# How to Use CustomerGroup APIs
|
||||
|
||||
In this document, you’ll learn how to use the customer groups admin APIs to manage customer groups and their associated customers and price lists.
|
||||
|
||||
## Overview
|
||||
|
||||
Using the Admin API you can manage customer groups by creating, retrieving, updating, and deleting them. You can also manage the customers in a customer group.
|
||||
|
||||
Using the PriceList API you can specify among the conditions the customer groups that the prices will apply to.
|
||||
|
||||
This guide covers how to use these APIs to perform these tasks.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Medusa Components
|
||||
|
||||
It is assumed that you already have a Medusa server installed and set up. If not, you can follow our [quickstart guide](../../quickstart/quick-start.md) to get started.
|
||||
|
||||
### JS Client
|
||||
|
||||
This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, JavaScript’s Fetch API, or cURL.
|
||||
|
||||
If you follow the JS Client code blocks, it’s assumed you already have [Medusa’s JS Client](../../js-client/overview.md) installed and have [created an instance of the client](../../js-client/overview.md#configuration).
|
||||
|
||||
### Authenticated Admin User
|
||||
|
||||
You must be an authenticated admin user before following along with the steps in the tutorial.
|
||||
|
||||
You can learn more about [authenticating as an admin user in the API reference](https://docs.medusajs.com/api/admin/#section/Authentication).
|
||||
|
||||
---
|
||||
|
||||
## Create Customer Groups
|
||||
|
||||
You can create a customer group by sending a request to the Create Customer Group endpoint:
|
||||
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.customerGroups.create({
|
||||
name: 'VIP'
|
||||
})
|
||||
.then(({ customer_group }) => {
|
||||
console.log(customer_group.id);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/customer-groups`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: 'VIP'
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ customer_group }) => {
|
||||
console.log(customer_group.id)
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl --location --request POST '<SERVER_URL>/admin/customer-groups' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"name": "VIP"
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This request requires the `name` parameter and optionally accepts the `metadata` object parameter to be passed in the body. It returns the created customer group.
|
||||
|
||||
---
|
||||
|
||||
## List Customer Groups
|
||||
|
||||
You can get a list of all customer groups by sending a request to the List Customer Groups endpoint:
|
||||
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.customerGroups.list()
|
||||
.then(({ customer_groups, limit, offset, count }) => {
|
||||
console.log(customer_groups.length);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/customer-groups`)
|
||||
.then((response) => response.json())
|
||||
.then(({ customer_groups, limit, offset, count }) => {
|
||||
console.log(customer_groups.length)
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl --location --request GET '<SERVER_URL>/admin/customer-groups' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This request returns an array of customer groups, as well as pagination fields.
|
||||
|
||||
You can also pass filters and other selection query parameters to the request. Check out the [API reference](https://docs.medusajs.com/api/admin/#tag/Customer-Group/operation/GetCustomerGroups) for more details on available query parameters.
|
||||
|
||||
---
|
||||
|
||||
## Retrieve a Customer Group
|
||||
|
||||
You can retrieve a single customer group by sending a request to the Get a Customer Group endpoint:
|
||||
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.customerGroups.retrieve(customerGroupId)
|
||||
.then(({ customer_group }) => {
|
||||
console.log(customer_group.id);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/customer-groups/${customerGroupId}`)
|
||||
.then((response) => response.json())
|
||||
.then(({ customer_group }) => {
|
||||
console.log(customer_group.id)
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl --location --request GET '<SERVER_URL>/admin/customer-groups/<CUSTOMER_GROUP_ID>' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This request accepts the ID of the customer group to retrieve as a path parameter. It returns the customer group of that ID.
|
||||
|
||||
---
|
||||
|
||||
## Update a Customer Group
|
||||
|
||||
You can update a customer group’s data by sending a request to the Update Customer Group endpoint:
|
||||
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.customerGroups.update(customerGroupId, {
|
||||
metadata: {
|
||||
is_seller: true
|
||||
}
|
||||
})
|
||||
.then(({ customer_group }) => {
|
||||
console.log(customer_group.id);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/customer-groups/${customerGroupId}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
metadata: {
|
||||
is_seller: true
|
||||
}
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ customer_group }) => {
|
||||
console.log(customer_group.id)
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl --location --request POST '<SERVER_URL>/admin/customer-groups/<CUSTOMER_GROUP_ID>' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"metadata": {
|
||||
"is_seller": true
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This request accepts the ID of the customer group as a path parameter, and optionally accepts the `name` or `metadata` fields as body parameters. It returns the updated customer group.
|
||||
|
||||
---
|
||||
|
||||
## Delete Customer Group
|
||||
|
||||
You can delete a customer group by sending a request to the Delete a Customer Group endpoint:
|
||||
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.customerGroups.delete(customerGroupId)
|
||||
.then(({ id, object, deleted }) => {
|
||||
console.log(id);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/customer-groups/${customerGroupId}`, {
|
||||
method: 'DELETE'
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ id, object, deleted }) => {
|
||||
console.log(id)
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl --location --request DELETE '<SERVER_URL>/admin/customer-groups/<CUSTOMER_GROUP_ID>' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This request accepts the ID of the customer group to delete as a path parameter. It returns the ID of the deleted entity.
|
||||
|
||||
---
|
||||
|
||||
## Manage Customers
|
||||
|
||||
### Add Customer to Group
|
||||
|
||||
You can add a customer to a group by sending a request to the Customer Group’s Add Customer endpoint:
|
||||
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.customerGroups.addCustomers(customerGroupId, {
|
||||
customer_ids: [
|
||||
{
|
||||
id: customerId
|
||||
}
|
||||
]
|
||||
})
|
||||
.then(({ customer_group }) => {
|
||||
console.log(customer_group.id);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/customer-groups/${customerGroupId}/customers/batch`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
customer_ids: [
|
||||
{
|
||||
id: customerId
|
||||
}
|
||||
]
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ customer_group }) => {
|
||||
console.log(customer_group.id)
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl --location --request POST '<SERVER_URL>/admin/customer-groups/<CUSTOMER_GROUP_ID>/customers/batch' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"customer_ids": [
|
||||
{
|
||||
"id": "<CUSTOMER_ID>"
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This request accepts the ID of the customer group as a path parameter. In its body, it accepts a `customer_ids` array of objects. Each object in the array must have the `id` property with its value being the ID of the customer you want to add.
|
||||
|
||||
### List Customers
|
||||
|
||||
You can retrieve a list of all customers in a customer group using the List Customers endpoint:
|
||||
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.customerGroups.listCustomers(customerGroupId)
|
||||
.then(({ customers, count, offset, limit }) => {
|
||||
console.log(customers.length);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/customer-groups/${customerGroupId}/customers`)
|
||||
.then((response) => response.json())
|
||||
.then(({ customers, count, offset, limit }) => {
|
||||
console.log(customers.length)
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl --location --request GET '<SERVER_URL>/admin/customer-groups/<CUSTOMER_GROUP_ID>/customers' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This request accepts the ID of the customer group as a path parameter. It returns an array of customers along with pagination fields.
|
||||
|
||||
### Remove Customers from a Group
|
||||
|
||||
:::info
|
||||
|
||||
Removing customers from a group does not remove them entirely. They’ll still be available in your store.
|
||||
|
||||
:::
|
||||
|
||||
You can remove customers from a customer group by sending a request to the Remove Customers endpoint:
|
||||
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.customerGroups.removeCustomers(customer_group_id, {
|
||||
customer_ids: [
|
||||
{
|
||||
id: customer_id
|
||||
}
|
||||
]
|
||||
})
|
||||
.then(({ customer_group }) => {
|
||||
console.log(customer_group.id);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/customer-groups/${customerGroupId}/customers/batch`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
customer_ids: [
|
||||
{
|
||||
id: customerId
|
||||
}
|
||||
]
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ customer_group }) => {
|
||||
console.log(customer_group.id)
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl --location --request DELETE '<SERVER_URL>/admin/customer-groups/<CUSTOMER_GROUP_ID>/customers/batch' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"customer_ids": [
|
||||
{
|
||||
"id": "<CUSTOMER_ID>"
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This request accepts as a path parameter the ID of the customer group to remove customers from. In its body, it accepts a `customer_ids` array of objects. Each object in the array must have the `id` property with the value being the ID of the customer to remove from the group.
|
||||
|
||||
This request returns the customer group.
|
||||
|
||||
---
|
||||
|
||||
## Use Customer Groups as Conditions in a Price List
|
||||
|
||||
When you create or update a price list, you can specify one or more customer groups as conditions for the price list. You can learn how to do that in the [PriceList API documentation](../backend/price-lists/use-api.mdx).
|
||||
|
||||
---
|
||||
|
||||
## What’s Next
|
||||
|
||||
- Learn more about [Customer Groups](../backend/customer-groups/index.md).
|
||||
- Learn about [how to use Sales Channels](../backend/sales-channels/manage-admin.mdx).
|
||||
@@ -285,7 +285,7 @@ fetch(`<YOUR_SERVER>/admin/batch-jobs`, {
|
||||
```bash
|
||||
# using cURL
|
||||
curl --location --request POST '<YOUR_SERVER>/admin/batch-jobs' \
|
||||
--header 'Authorization: Bearer {api_token}' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"type": "publish-products",
|
||||
@@ -322,7 +322,7 @@ fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}`)
|
||||
```bash
|
||||
# using cURL
|
||||
curl --location --request GET '<YOUR_SERVER>/admin/batch-jobs/<BATCH_JOB_ID>' \
|
||||
--header 'Authorization: Bearer {api_token}'
|
||||
--header 'Authorization: Bearer <API_TOKEN>'
|
||||
# <BATCH_JOB_ID> is the ID of the batch job
|
||||
```
|
||||
|
||||
@@ -368,7 +368,7 @@ fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}/confirm`, {
|
||||
```bash
|
||||
# using cURL
|
||||
curl --location --request POST '<YOUR_SERVER>/admin/batch-jobs/<BATCH_JOB_ID>/confirm' \
|
||||
--header 'Authorization: Bearer {api_token}'
|
||||
--header 'Authorization: Bearer <API_TOKEN>'
|
||||
# <BATCH_JOB_ID> is the ID of the batch job
|
||||
```
|
||||
|
||||
@@ -376,7 +376,7 @@ The batch job will start processing afterward. Based on the batch job strategy i
|
||||
|
||||
You can [retrieve the batch job](#optional-retrieve-batch-job) at any given point to check its status.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn more about [batch jobs](./index.md).
|
||||
- Learn how to [import products using the Admin API](../../admin/import-products.mdx).
|
||||
|
||||
@@ -109,7 +109,7 @@ If you don’t want to overwrite Medusa’s batch job strategy, you can create a
|
||||
|
||||
For more details on creating custom batch job strategies, please check out the [Create Batch Job Strategy documentation](create.md).
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn more about [batch jobs](./index.md).
|
||||
- Learn [how to use the Import Product APIs](../../admin/import-products.mdx).
|
||||
|
||||
@@ -123,6 +123,6 @@ To test the previous example out instantly, you can change the cron job expressi
|
||||
|
||||
:::
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn more about [services and how you can use them](../services/overview.md).
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# Customer Groups
|
||||
|
||||
In this document, you’ll learn about Customer Groups and how they can be used in Medusa.
|
||||
|
||||
## Introduction
|
||||
|
||||
Customer groups allow you to combine customers with similar attributes such as purchase habits, region, or for any reason that works for your business model.
|
||||
|
||||
You can then assign different prices for customer groups using price lists.
|
||||
|
||||
### Examples Use Cases
|
||||
|
||||
The customer groups feature can be used in a variety of use cases including:
|
||||
|
||||
- Implement a B2B business model by assigning a specific customer group for wholesale customers.
|
||||
- Combine customers that make purchases frequently into a group and give them a special discount.
|
||||
- Create different customer groups based on different buyer personas.
|
||||
|
||||
---
|
||||
|
||||
## CustomerGroup Entity Overview
|
||||
|
||||
A customer group is stored in the database as a [CustomerGroup](../../../references/entities/classes/CustomerGroup.md) entity. This entity has two attributes other than the `id`: `name` and `metadata`.
|
||||
|
||||
Similar to all entities in Medusa, you can use the `metadata` object attribute to store any custom data you want. For example, you can add some flag or tag to the customer group for a custom use case:
|
||||
|
||||
```jsx
|
||||
metadata: {
|
||||
is_seller: true
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Relations to Other Entities
|
||||
|
||||
### Customer
|
||||
|
||||
A customer can belong to multiple customer groups, and a customer group can have more than one customer. After creating a customer group, you can manage customers in that group.
|
||||
|
||||
The relation between the `Customer` and `CustomerGroup` entities is available on both entities:
|
||||
|
||||
- You can access the customer groups of a customer by expanding the `groups` relation and accessing `customer.groups`.
|
||||
- You can access the customers in a customer group by expanding the `customers` relation and accessing `customerGroup.customers`.
|
||||
|
||||
### PriceList
|
||||
|
||||
A price list can have multiple conditions to define in which cases it should be applied. One of those conditions is customer groups. You can specify more than one customer group to apply the prices on.
|
||||
|
||||
The relation between the `PriceList` and `CustomerGroup` entities is available on both entities:
|
||||
|
||||
- You can access the customer groups of a price list by expanding the `customer_groups` relation and accessing `price_list.customer_groups`.
|
||||
- You can access the price lists that are applied to a customer group by expanding the `price_lists` relation and accessing `customerGroup.price_lists`.
|
||||
|
||||
---
|
||||
|
||||
## What’s Next
|
||||
|
||||
- Learn [how to manage customer groups using the Admin APIs](../../admin/use-customergroups-api.mdx).
|
||||
- Learn more about [Price Lists and how they work](../price-lists/index.md).
|
||||
@@ -1,220 +0,0 @@
|
||||
# Create Endpoint for Admin
|
||||
|
||||
In this document, you’ll learn how to add a custom endpoint in the Backend that you can use from the Admin.
|
||||
|
||||
## Overview
|
||||
|
||||
Custom endpoints reside under the `src/api` directory in your Medusa Backend. To define a new endpoint, you can add the file `index.js` under the `src/api` directory. This file should export a function that returns an Express router.
|
||||
|
||||
Your endpoint can be under any path you wish. By Medusa’s conventions, all Admin REST APIs are prefixed by `/admin`. For example, the `/admin/products` lets you retrieve the products to display them on your Admin.
|
||||
|
||||
## Implementation
|
||||
|
||||
To create a new endpoint, start by creating a new file in `src/api` called `index.js`. At its basic format, `index.js` should look something like this:
|
||||
|
||||
```js
|
||||
import { Router } from "express"
|
||||
|
||||
export default () => {
|
||||
const router = Router()
|
||||
|
||||
router.get("/admin/hello", (req, res) => {
|
||||
res.json({
|
||||
message: "Welcome to Your Store!",
|
||||
})
|
||||
})
|
||||
|
||||
return router
|
||||
}
|
||||
```
|
||||
|
||||
This exports a function that returns an Express router. In that function, you can create one or more endpoints. In the example above, you create the endpoint `/admin/hello`.
|
||||
|
||||
Now, if you run your server and send a request to `/admin/hello`, you will receive a JSON response message.
|
||||
|
||||
:::note
|
||||
|
||||
Custom endpoints are compiled into the `dist` directory of your Backend when you run your server using `medusa develop`, while it’s running, and when you run:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run build
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## Accessing Endpoints from Admin
|
||||
|
||||
If you’re customizing the admin dashboard or creating your own, you need to use the `cors` library. A `OPTIONS` request should be added for each route and handle the requests with the `cors` library.
|
||||
|
||||
First, you need to import your Medusa’s configurations along with the `cors` library:
|
||||
|
||||
```js
|
||||
import cors from "cors"
|
||||
import { projectConfig } from "../../medusa-config"
|
||||
```
|
||||
|
||||
Then, create an object that will hold the Cross-Origin Resource Sharing (CORS) configurations:
|
||||
|
||||
```js
|
||||
const corsOptions = {
|
||||
origin: projectConfig.admin_cors.split(","),
|
||||
credentials: true,
|
||||
}
|
||||
```
|
||||
|
||||
Finally, for each route you add, create an `OPTIONS` request and add `cors` as a middleware for the route:
|
||||
|
||||
```js
|
||||
router.options("/admin/hello", cors(corsOptions))
|
||||
router.get("/admin/hello", cors(corsOptions), (req, res) => {
|
||||
//...
|
||||
})
|
||||
```
|
||||
|
||||
## Multiple Endpoints
|
||||
|
||||
### Same File
|
||||
|
||||
You can add more than one endpoints in `src/api/index.js`:
|
||||
|
||||
```js
|
||||
router.get("/admin/hello", (req, res) => {
|
||||
res.json({
|
||||
message: "Welcome to Your Store!",
|
||||
})
|
||||
})
|
||||
|
||||
router.get("/admin/bye", (req, res) => {
|
||||
res.json({
|
||||
message: "Come back again!",
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### Multiple Files
|
||||
|
||||
Alternatively, you can add multiple files for each endpoint or set of endpoints for readability and easy maintenance.
|
||||
|
||||
To do that with the previous example, first, create the file `src/api/hello.js` with the following content:
|
||||
|
||||
```js
|
||||
export default (router) => {
|
||||
router.get("/admin/hello", (req, res) => {
|
||||
res.json({
|
||||
message: "Welcome to Your Store!",
|
||||
})
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
You export a function that receives an Express router as a parameter and adds the endpoint `admin/hello` to it.
|
||||
|
||||
Next, create the file `src/api/bye.js` with the following content:
|
||||
|
||||
```js
|
||||
export default (router) => {
|
||||
router.get("/admin/bye", (req, res) => {
|
||||
res.json({
|
||||
message: "Come back again!",
|
||||
})
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Again, you export a function that receives an Express router as a parameter and adds the endpoint `admin/bye` to it.
|
||||
|
||||
Finally, in `src/api/index.js` import the two functions at the beginning of the file:
|
||||
|
||||
```js
|
||||
import helloRoute from "./hello"
|
||||
import byeRoute from "./bye"
|
||||
```
|
||||
|
||||
and in the exported function, call each of the functions passing them the Express router:
|
||||
|
||||
```js
|
||||
export default () => {
|
||||
const router = Router()
|
||||
|
||||
helloRoute(router)
|
||||
byeRoute(router)
|
||||
|
||||
return router
|
||||
}
|
||||
```
|
||||
|
||||
## Use Services
|
||||
|
||||
Services in Medusa bundle a set of functionalities into one class. Then, you can use that class anywhere in your Backend. For example, you can use the `ProductService` to retrieve products or perform operations like creating or updating a product.
|
||||
|
||||
You can retrieve any registered service in your endpoint using `req.scope.resolve` passing it the service’s registration name.
|
||||
|
||||
Here’s an example of an endpoint that retrieves the count of products in your store:
|
||||
|
||||
```js
|
||||
router.get("/admin/products/count", (req, res) => {
|
||||
const productService = req.scope.resolve("productService")
|
||||
|
||||
productService.count().then((count) => {
|
||||
res.json({
|
||||
count,
|
||||
})
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
The `productService` has a `count` method that returns a Promise. This Promise resolves to the count of the products. You return a JSON of the product count.
|
||||
|
||||
## Protected Routes
|
||||
|
||||
Protected routes are routes that should be accessible by logged-in users only.
|
||||
|
||||
To make a route protected, first, import the `authenticate` middleware:
|
||||
|
||||
```js
|
||||
import authenticate from "@medusajs/medusa/dist/api/middlewares/authenticate"
|
||||
```
|
||||
|
||||
Then, add the middleware to your route:
|
||||
|
||||
```js
|
||||
router.get("/store/products/count", authenticate(), (req, res) => {
|
||||
//...
|
||||
})
|
||||
```
|
||||
|
||||
Now, only authenticated users can access this endpoint.
|
||||
|
||||
### Accessing Current User
|
||||
|
||||
You can get the logged-in user ID using `req.user`:
|
||||
|
||||
```js
|
||||
const id = req.user.userId
|
||||
```
|
||||
|
||||
To get the user’s details, you can use the `userService`:
|
||||
|
||||
```js
|
||||
const id = req.user.userId
|
||||
const userService = req.scope.resolve("userService")
|
||||
|
||||
const user = await userService.retrieve(id)
|
||||
```
|
||||
|
||||
### Route Parameters
|
||||
|
||||
The routes you create receive two parameters. The first one is the absolute path to the root directory that your server is running from. The second one is an object that has your plugin's options. If your API route is not implemented in a plugin, then it will be an empty object.
|
||||
|
||||
```js
|
||||
export default (rootDirectory, pluginOptions) => {
|
||||
const router = Router()
|
||||
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
## What’s Next 🚀
|
||||
|
||||
- [Learn how to add an endpoint for the Storefront.](/advanced/backend/endpoints/add-storefront)
|
||||
- [Check out the API reference for all available endpoints.](https://docs.medusajs.com/api/admin)
|
||||
@@ -1,219 +0,0 @@
|
||||
# Create Endpoint for Storefront
|
||||
|
||||
In this document, you’ll learn how to add a custom endpoint in the Backend that you can use from the Storefront.
|
||||
|
||||
## Overview
|
||||
|
||||
Custom endpoints reside under the `src/api` directory in your Medusa Backend. To define a new endpoint, you can add the file `index.js` under the `src/api` directory. This file should export a function that returns an Express router.
|
||||
|
||||
Your endpoint can be under any path you wish. By Medusa’s conventions, all Storefront REST APIs are prefixed by `/store`. For example, the `/store/products` lets you retrieve the products to display them on your storefront.
|
||||
|
||||
## Implementation
|
||||
|
||||
To create a new endpoint, start by creating a new file in `src/api` called `index.js`. At its basic format, `index.js` should look something like this:
|
||||
|
||||
```js
|
||||
import { Router } from "express"
|
||||
|
||||
export default () => {
|
||||
const router = Router()
|
||||
|
||||
router.get("/store/hello", (req, res) => {
|
||||
res.json({
|
||||
message: "Welcome to My Store!",
|
||||
})
|
||||
})
|
||||
|
||||
return router
|
||||
}
|
||||
```
|
||||
|
||||
This exports a function that returns an Express router. In that function, you can create one or more endpoints. In the example above, you create the endpoint `/store/hello`.
|
||||
|
||||
Now, if you run your server and send a request to `/store/hello`, you will receive a JSON response message.
|
||||
|
||||
:::note
|
||||
|
||||
Custom endpoints are compiled into the `dist` directory of your Backend when you run your server using `medusa develop`, while it’s running, and when you run:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run build
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## Accessing Endpoints from Storefront
|
||||
|
||||
If you’re customizing one of our storefronts or creating your own, you need to use the `cors` library.
|
||||
|
||||
First, you need to import your Medusa’s configurations along with the `cors` library:
|
||||
|
||||
```js
|
||||
import cors from "cors"
|
||||
import { projectConfig } from "../../medusa-config"
|
||||
```
|
||||
|
||||
Then, create an object that will hold the Cross-Origin Resource Sharing (CORS) configurations:
|
||||
|
||||
```js
|
||||
const corsOptions = {
|
||||
origin: projectConfig.store_cors.split(","),
|
||||
credentials: true,
|
||||
}
|
||||
```
|
||||
|
||||
Finally, for each route add `cors` as a middleware for the route passing it `corsOptions`:
|
||||
|
||||
```js
|
||||
router.get("/store/hello", cors(corsOptions), (req, res) => {
|
||||
//...
|
||||
})
|
||||
```
|
||||
|
||||
## Multiple Endpoints
|
||||
|
||||
### Same File
|
||||
|
||||
You can add more than one endpoints in `src/api/index.js`:
|
||||
|
||||
```js
|
||||
router.get("/store/hello", (req, res) => {
|
||||
res.json({
|
||||
message: "Welcome to My Store!",
|
||||
})
|
||||
})
|
||||
|
||||
router.get("/store/bye", (req, res) => {
|
||||
res.json({
|
||||
message: "Come back again!",
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### Multiple Files
|
||||
|
||||
Alternatively, you can add multiple files for each endpoint or set of endpoints for readability and easy maintenance.
|
||||
|
||||
To do that with the previous example, first, create the file `src/api/hello.js` with the following content:
|
||||
|
||||
```js
|
||||
export default (router) => {
|
||||
router.get("/store/hello", (req, res) => {
|
||||
res.json({
|
||||
message: "Welcome to My Store!",
|
||||
})
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
You export a function that receives an Express router as a parameter and adds the endpoint `store/hello` to it.
|
||||
|
||||
Next, create the file `src/api/bye.js` with the following content:
|
||||
|
||||
```js
|
||||
export default (router) => {
|
||||
router.get("/store/bye", (req, res) => {
|
||||
res.json({
|
||||
message: "Come back again!",
|
||||
})
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Again, you export a function that receives an Express router as a parameter and adds the endpoint `store/bye` to it.
|
||||
|
||||
Finally, in `src/api/index.js` import the two functions at the beginning of the file:
|
||||
|
||||
```js
|
||||
import helloRoute from "./hello"
|
||||
import byeRoute from "./bye"
|
||||
```
|
||||
|
||||
and in the exported function, call each of the functions passing them the Express router:
|
||||
|
||||
```js
|
||||
export default () => {
|
||||
const router = Router()
|
||||
|
||||
helloRoute(router)
|
||||
byeRoute(router)
|
||||
|
||||
return router
|
||||
}
|
||||
```
|
||||
|
||||
## Use Services
|
||||
|
||||
Services in Medusa bundle a set of functionalities into one class. Then, you can use that class anywhere in your Backend. For example, you can use the `ProductService` to retrieve products or perform operations like creating or updating a product.
|
||||
|
||||
You can retrieve any registered service in your endpoint using `req.scope.resolve` passing it the service’s registration name.
|
||||
|
||||
Here’s an example of an endpoint that retrieves the count of products in your store:
|
||||
|
||||
```js
|
||||
router.get("/store/products/count", (req, res) => {
|
||||
const productService = req.scope.resolve("productService")
|
||||
|
||||
productService.count().then((count) => {
|
||||
res.json({
|
||||
count,
|
||||
})
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
The `productService` has a `count` method that returns a Promise. This Promise resolves to the count of the products. You return a JSON of the product count.
|
||||
|
||||
## Protected Routes
|
||||
|
||||
Protected routes are routes that should be accessible by logged-in customers only.
|
||||
|
||||
To make a route protected, first, import the `authenticate` middleware:
|
||||
|
||||
```js
|
||||
import authenticate from "@medusajs/medusa/dist/api/middlewares/authenticate-customer"
|
||||
```
|
||||
|
||||
Then, add the middleware to your route:
|
||||
|
||||
```jsx
|
||||
router.get("/store/products/count", authenticate(), (req, res) => {
|
||||
//...
|
||||
})
|
||||
```
|
||||
|
||||
Now, only authenticated users can access this endpoint.
|
||||
|
||||
### Accessing Current Customer
|
||||
|
||||
You can get the logged-in customer’s ID using `req.user`:
|
||||
|
||||
```jsx
|
||||
const id = req.user.customer_id
|
||||
```
|
||||
|
||||
To get the customer’s details, you can use the `customerService`:
|
||||
|
||||
```jsx
|
||||
const id = req.user.customer_id
|
||||
const customerService = req.scope.resolve("customerService")
|
||||
|
||||
const customer = await customerService.retrieve(id)
|
||||
```
|
||||
|
||||
### Route Parameters
|
||||
|
||||
The routes you create receive two parameters. The first one is the absolute path to the root directory that your server is running from. The second one is an object that has your plugin's options. If your API route is not implemented in a plugin, then it will be an empty object.
|
||||
|
||||
```js
|
||||
export default (rootDirectory, pluginOptions) => {
|
||||
const router = Router()
|
||||
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
## What’s Next :rocket:
|
||||
|
||||
- [Learn how to add an endpoint for the Admin.](/advanced/backend/endpoints/add-admin)
|
||||
- [Check out the API reference for all available endpoints.](https://docs.medusajs.com/api/store)
|
||||
@@ -0,0 +1,259 @@
|
||||
# How to Create Endpoints
|
||||
|
||||
In this document, you’ll learn how to create endpoints in your Medusa server.
|
||||
|
||||
## Overview
|
||||
|
||||
Custom endpoints reside under the `src/api` directory in your Medusa Backend. To define a new endpoint, you can add the file `index.js` under the `src/api` directory. This file should export a function that returns an Express router.
|
||||
|
||||
## Implementation
|
||||
|
||||
To create a new endpoint, start by creating a new file in `src/api` called `index.js`. At its basic format, `index.js` should look something like this:
|
||||
|
||||
```jsx
|
||||
import { Router } from "express"
|
||||
|
||||
export default (rootDirectory, pluginOptions) => {
|
||||
const router = Router()
|
||||
|
||||
router.get("/hello", (req, res) => {
|
||||
res.json({
|
||||
message: "Welcome to My Store!",
|
||||
})
|
||||
})
|
||||
|
||||
return router
|
||||
}
|
||||
```
|
||||
|
||||
This exports a function that returns an Express router. The function receives two parameters:
|
||||
|
||||
- `rootDirectory` is the absolute path to the root directory that your server is running from.
|
||||
- `pluginOptions` is an object that has your plugin's options. If your API route is not implemented in a plugin, then it will be an empty object.
|
||||
|
||||
### Endpoints Path
|
||||
|
||||
Your endpoint can be under any path you wish.
|
||||
|
||||
By Medusa’s conventions:
|
||||
|
||||
- All Storefront REST APIs are prefixed by `/store`. For example, the `/store/products` endpoint lets you retrieve the products to display them on your storefront.
|
||||
- All Admin REST APIs are prefixed by `/admin`. For example, the `/admin/products` endpoint lets you retrieve the products to display them on your Admin.
|
||||
|
||||
You can also create endpoints that do not reside under these two prefixes, similar to the `hello` endpoint in the previous example.
|
||||
|
||||
## CORS Configuration
|
||||
|
||||
If you’re adding a storefront or admin endpoint and you want to access these endpoints from the storefront or Medusa admin, you need to pass your endpoints Cross-Origin Resource Origin (CORS) options using the `cors` package.
|
||||
|
||||
First, you need to import your Medusa configurations along with the `cors` library:
|
||||
|
||||
```jsx
|
||||
import cors from "cors"
|
||||
import { projectConfig } from "../../medusa-config"
|
||||
```
|
||||
|
||||
Then, create an object that will hold the Cross-Origin Resource Sharing (CORS) configurations. If it’s a storefront endpoint, pass the `origin` property storefront options:
|
||||
|
||||
```jsx
|
||||
const corsOptions = {
|
||||
origin: projectConfig.store_cors.split(","),
|
||||
credentials: true,
|
||||
}
|
||||
```
|
||||
|
||||
If it’s an admin endpoint, pass the `origin` property admin options:
|
||||
|
||||
```jsx
|
||||
const corsOptions = {
|
||||
origin: projectConfig.admin_cors.split(","),
|
||||
credentials: true,
|
||||
}
|
||||
```
|
||||
|
||||
Finally, for each route you add, create an `OPTIONS` request and add `cors` as a middleware for the route:
|
||||
|
||||
```jsx
|
||||
router.options("/admin/hello", cors(corsOptions))
|
||||
router.get("/admin/hello", cors(corsOptions), (req, res) => {
|
||||
//...
|
||||
})
|
||||
```
|
||||
|
||||
## Create Multiple Endpoints
|
||||
|
||||
### Same File
|
||||
|
||||
You can add more than one endpoint in `src/api/index.js`:
|
||||
|
||||
```jsx
|
||||
router.options("/store/hello", cors(storeCorsOptions))
|
||||
router.get("/store/hello", cors(storeCorsOptions), (req, res) => {
|
||||
res.json({
|
||||
message: "Welcome to Your Store!",
|
||||
})
|
||||
})
|
||||
|
||||
router.options("/admin/hello", cors(adminCorsOptions))
|
||||
router.get("/admin/hello", cors(adminCorsOptions), (req, res) => {
|
||||
res.json({
|
||||
message: "Welcome to Your Admin!",
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### Multiple Files
|
||||
|
||||
Alternatively, you can add multiple files for each endpoint or set of endpoints for readability and easy maintenance.
|
||||
|
||||
To do that with the previous example, first, create the file `src/api/store.js` with the following content:
|
||||
|
||||
```jsx
|
||||
import cors from "cors"
|
||||
import { projectConfig } from "../../../medusa-config"
|
||||
|
||||
export default (router) => {
|
||||
const storeCorsOptions = {
|
||||
origin: projectConfig.store_cors.split(","),
|
||||
credentials: true,
|
||||
}
|
||||
router.options("/store/hello", cors(storeCorsOptions))
|
||||
router.get("/store/hello", cors(storeCorsOptions), (req, res) => {
|
||||
res.json({
|
||||
message: "Welcome to Your Store!",
|
||||
})
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
You export a function that receives an Express router as a parameter and adds the endpoint `store/hello` to it.
|
||||
|
||||
Next, create the file `src/api/admin.js` with the following content:
|
||||
|
||||
```jsx
|
||||
import cors from "cors"
|
||||
import { projectConfig } from "../../../medusa-config"
|
||||
|
||||
export default (router) => {
|
||||
const adminCorsOptions = {
|
||||
origin: projectConfig.admin_cors.split(","),
|
||||
credentials: true,
|
||||
}
|
||||
router.options("/admin/hello", cors(adminCorsOptions))
|
||||
router.get("/admin/hello", cors(adminCorsOptions), (req, res) => {
|
||||
res.json({
|
||||
message: "Welcome to Your Admin!",
|
||||
})
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Again, you export a function that receives an Express router as a parameter and adds the endpoint `admin/hello` to it.
|
||||
|
||||
Finally, in `src/api/index.js` import the two functions at the beginning of the file:
|
||||
|
||||
```jsx
|
||||
import storeRoutes from "./store"
|
||||
import adminRoutes from "./admin"
|
||||
```
|
||||
|
||||
and in the exported function, call each of the functions passing them the Express router:
|
||||
|
||||
```jsx
|
||||
export default () => {
|
||||
const router = Router()
|
||||
|
||||
storeRoutes(router)
|
||||
adminRoutes(router)
|
||||
|
||||
return router
|
||||
}
|
||||
```
|
||||
|
||||
## Protected Routes
|
||||
|
||||
Protected routes are routes that should be accessible by logged-in customers or users only.
|
||||
|
||||
### Protect Store Routes
|
||||
|
||||
To make a storefront route protected, first, import the `authenticate-customer` middleware:
|
||||
|
||||
```jsx
|
||||
import authenticate from "@medusajs/medusa/dist/api/middlewares/authenticate-customer"
|
||||
```
|
||||
|
||||
Then, add the middleware to your route:
|
||||
|
||||
```jsx
|
||||
router.options("/store/hello", cors(corsOptions))
|
||||
router.get("/store/hello", cors(corsOptions), authenticate(), async (req, res) => {
|
||||
if (req.user) {
|
||||
//user is logged in
|
||||
//to get customer id: req.user.customer_id
|
||||
}
|
||||
//...
|
||||
})
|
||||
```
|
||||
|
||||
Please note that the endpoint is still accessible by all users, however, you’ll be able to access the current logged-in customer if there’s any.
|
||||
|
||||
To disallow guest customers from accessing the endpoint, you can throw an error if `req.user` is `false`.
|
||||
|
||||
### Protect Admin Routes
|
||||
|
||||
To make an admin route protected, first, import the `authenticate` middleware:
|
||||
|
||||
```jsx
|
||||
import authenticate from "@medusajs/medusa/dist/api/middlewares/authenticate"
|
||||
```
|
||||
|
||||
Then, add the middleware to your route:
|
||||
|
||||
```jsx
|
||||
router.options("/admin/products/count", cors(corsOptions))
|
||||
router.get("/admin/products/count", cors(corsOptions), authenticate(), (req, res) => {
|
||||
//access current user
|
||||
const id = req.user.userId
|
||||
const userService = req.scope.resolve("userService")
|
||||
|
||||
const user = await userService.retrieve(id)
|
||||
//...
|
||||
})
|
||||
```
|
||||
|
||||
Now, only authenticated users can access this endpoint.
|
||||
|
||||
## Use Services
|
||||
|
||||
Services in Medusa bundle a set of functionalities into one class. Then, you can use that class anywhere in your backend. For example, you can use the `ProductService` to retrieve products or perform operations like creating or updating a product.
|
||||
|
||||
You can retrieve any registered service in your endpoint using `req.scope.resolve` passing it the service’s registration name.
|
||||
|
||||
Here’s an example of an endpoint that retrieves the count of products in your store:
|
||||
|
||||
```jsx
|
||||
router.get("/admin/products/count", cors(corsOptions), authenticate(), (req, res) => {
|
||||
const productService = req.scope.resolve("productService")
|
||||
|
||||
productService.count().then((count) => {
|
||||
res.json({
|
||||
count,
|
||||
})
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
The `productService` has a `count` method that returns a Promise. This Promise resolves to the count of the products. You return a JSON of the product count.
|
||||
|
||||
## Building Files
|
||||
|
||||
Custom endpoints must be transpiled and moved to the `dist` directory. This happens when you run your server using `medusa develop` and while it’s running, and when you run the following command:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run build
|
||||
```
|
||||
|
||||
## What’s Next
|
||||
|
||||
- Check out the available [Admin](https://docs.medusajs.com/api/admin/) and [Storefront](https://docs.medusajs.com/api/store/) APIs.
|
||||
- Learn how to create a [Service](./../services/create-service.md).
|
||||
@@ -125,7 +125,7 @@ To delete soft-deletable entities that extend the `SoftDeletableEntity` class, y
|
||||
await postRepository.softDelete(post.id);
|
||||
```
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Check out Medusa's entities in the [Entities' reference](../../../references/entities/classes/Address.md).
|
||||
- Learn about [migrations](../migrations/overview.md).
|
||||
|
||||
@@ -16,7 +16,7 @@ All entities must extend either the `BaseEntity` or `SoftDeletableEntity` classe
|
||||
|
||||
The `SoftDeletableEntity` class extends the `BaseEntity` class and adds another column `deleted_at`. If an entity can be soft deleted, meaning that a row in it can appear to the user as deleted but still be available in the database, it should extend `SoftDeletableEntity`.
|
||||
|
||||
## What's Next :rocket:
|
||||
## What's Next
|
||||
|
||||
- Learn [how to create an entity](./index.md).
|
||||
- Check out Medusa's entities in the [Entities' reference](../../../references/entities/classes/Address.md).
|
||||
@@ -85,7 +85,7 @@ If you had the feature flag previously enabled, and you want to disable this fea
|
||||
|
||||
You can follow [this documentation to learn how to revert the last migration you ran](https://docs.medusajs.com/cli/reference#migrations).
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn more about [Migrations](../migrations/overview.md).
|
||||
- Learn how to [configure your Medusa server](../../../usage/configurations.md).
|
||||
|
||||
@@ -38,6 +38,6 @@ medusa migrations run
|
||||
|
||||
If you check your database now you should see that the change defined by the migration has been applied successfully.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn more about [setting up your development server](../../../tutorial/0-set-up-your-development-environment.mdx).
|
||||
|
||||
@@ -48,7 +48,7 @@ npm run seed
|
||||
|
||||
This will use the underlying `seed` command provided by Medusa's CLI to seed your database with data from the file `data/seed.json` on your Medusa server.
|
||||
|
||||
## What's Next :rocket:
|
||||
## What's Next
|
||||
|
||||
- Learn [how to create a migration](index.md)
|
||||
- Learn more about [setting up your development server](../../../tutorial/set-up-your-development-environment).
|
||||
|
||||
@@ -264,7 +264,7 @@ Then, send a request to the [Resend Notification](https://docs.medusajs.com/api/
|
||||
|
||||
This request returns the same notification object as the List Notifications endpoint, but it now has a new object in the `resends` array. This is the resent notification. If you supplied a `to` parameter in the request body, you should see its value in the `to` property of the resent notification object.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Check out the [list of events](../subscribers/events-list.md) you can listen to.
|
||||
- Check out the [SendGrid](../../../add-plugins/sendgrid.mdx) plugin for easy integration of email notifications.
|
||||
|
||||
@@ -78,7 +78,7 @@ An example of a flow that can be implemented using Medusa's Notification API is
|
||||
- The customer returns the items triggering the `return.recieved` event.
|
||||
- The Notification Provider listens to the `return.received` event and sends an email to the customer with confirmation that their items have been received and that a refund has been issued.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn how to [create your own Notification Provider](how-to-create-notification-provider.md).
|
||||
- Check out the [list of events](../subscribers/events-list.md) in Medusa.
|
||||
|
||||
@@ -381,7 +381,7 @@ async retrieveSavedMethods(customer) {
|
||||
}
|
||||
```
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Check out the Payment Providers for [Stripe](https://github.com/medusajs/medusa/tree/2e6622ec5d0ae19d1782e583e099000f0a93b051/packages/medusa-payment-stripe) and [PayPal](https://github.com/medusajs/medusa/tree/2e6622ec5d0ae19d1782e583e099000f0a93b051/packages/medusa-payment-paypal) for implementation examples.
|
||||
- Learn more about the [frontend checkout flow](./../../storefront/how-to-implement-checkout-flow.mdx).
|
||||
|
||||
@@ -118,7 +118,7 @@ If then the request is interrupted for any reason or the payment fails, the clie
|
||||
|
||||
This prevents any payment issues from occurring with the customers and allows for secure retries of failed payments or interrupted connections.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- [Check out how the checkout flow is implemented on the frontend.](./../../storefront/how-to-implement-checkout-flow.mdx)
|
||||
- Check out payment plugins like [Stripe](../../../add-plugins/stripe.md), [Paypal](/add-plugins/paypal), and [Klarna](../../../add-plugins/klarna.md).
|
||||
|
||||
@@ -10,6 +10,12 @@ This guide uses the Medusa CLI throughout different steps. If you don’t have t
|
||||
npm install @medusajs/medusa-cli -g
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
If you run into any errors while installing the CLI tool, check out the [troubleshooting guide](../../../troubleshooting/cli-installation-errors.mdx).
|
||||
|
||||
:::
|
||||
|
||||
## Initialize Project
|
||||
|
||||
The recommended way to create a plugin is using the Medusa CLI. Run the following command to create a new Medusa project:
|
||||
@@ -184,7 +190,7 @@ medusa-plugin-custom
|
||||
|
||||
This guide doesn't cover how to create different files and components. If you’re interested in learning how to do that, you can check out these guides:
|
||||
|
||||
- How to create endpoints for [storefront](../endpoints/add-storefront.md) and [admin](../endpoints/add-admin.md)
|
||||
- How to [create endpoints](../endpoints/add.md)
|
||||
- How to [create a service](../services/create-service.md)
|
||||
- How to [create a subscriber](../subscribers/create-subscriber.md)
|
||||
- How to [create an entity](./../entities/index.md)
|
||||
@@ -449,7 +455,7 @@ To install any published plugin, you can run the following command on any Medusa
|
||||
npm install medusa-plugin-custom
|
||||
```
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Check out [available Services in Medusa](references/services/../../../../../references/services/classes/AuthService.md) that you can use in your plugin.
|
||||
- Check out [available events](../subscribers/events-list.md) that you can listen to in Subscribers.
|
||||
|
||||
@@ -48,7 +48,7 @@ If you’re installing an official plugin from the Medusa repository, you can fi
|
||||
|
||||
For community plugins, please refer to the installation instructions of that plugin to learn about any required configurations.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn how to [create your own plugin](create.md).
|
||||
- Learn how to [create a fulfillment provider](../shipping/add-fulfillment-provider.md) or a [payment provider](../payment/how-to-create-payment-provider.md).
|
||||
|
||||
@@ -81,7 +81,7 @@ Since the line item belongs to a cart, there’s no need to pass the `region_id`
|
||||
|
||||
---
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn more about [price selection strategies](../price-selection-strategy/index.md).
|
||||
- Learn [how to use the PriceList Admin APIs](./use-api.mdx).
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Use PriceList API
|
||||
# How to Use PriceList APIs
|
||||
|
||||
In this document, you’ll learn how to use the PriceList Admin APIs to create, update, and manage prices in a price list.
|
||||
|
||||
@@ -135,7 +135,7 @@ fetch(`<SERVER_URL>/admin/price-lists`, {
|
||||
|
||||
```bash
|
||||
curl --location --request POST '<YOUR_SERVER_URL>/admin/price-lists' \
|
||||
--header 'Authorization: Bearer {api_token}' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"name": "New Price List",
|
||||
@@ -198,7 +198,7 @@ fetch(`<SERVER_URL>/admin/price-lists/${priceListId}`)
|
||||
|
||||
```jsx
|
||||
curl --location --request GET '<SERVER_URL>/admin/price-lists/{id}' \
|
||||
--header 'Authorization: Bearer {api_token}'
|
||||
--header 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@@ -248,7 +248,7 @@ fetch(`<SERVER_URL>/admin/price-lists/${priceListId}`, {
|
||||
|
||||
```bash
|
||||
curl --location --request POST '<SERVER_URL>/admin/price-lists/<PRICE_LIST_ID>' \
|
||||
--header 'Authorization: Bearer {api_token}' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"ends_at": "2022-10-11"
|
||||
@@ -322,7 +322,7 @@ fetch(`<SERVER_URL>/admin/price-lists/${priceListId}/prices/batch`, {
|
||||
|
||||
```bash
|
||||
curl --location --request POST '<SERVER_URL>/admin/price-lists/<PRICE_LIST_ID>' \
|
||||
--header 'Authorization: Bearer {api_token}' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"prices": [
|
||||
@@ -374,7 +374,7 @@ fetch(`<SERVER_URL>/admin/price-lists/${priceListId}/products/${productId}/price
|
||||
|
||||
```bash
|
||||
curl --location --request DELETE '<SERVER_URL>/admin/price-lists/<PRICE_LIST_ID>/products/<PRODUCT_ID>/prices' \
|
||||
--header 'Authorization: Bearer {api_token}'
|
||||
--header 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@@ -414,7 +414,7 @@ fetch(`<SERVER_URL>/admin/price-lists/${priceListId}/variants/${variantId}/price
|
||||
|
||||
```jsx
|
||||
curl --location --request DELETE '<SERVER_URL>/admin/price-lists/<PRICE_LIST_ID>/variants/<VARIANT_ID>/prices' \
|
||||
--header 'Authorization: Bearer {api_token}'
|
||||
--header 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@@ -456,7 +456,7 @@ fetch(`<SERVER_URL>/admin/price-lists/${priceListId}`, {
|
||||
|
||||
```jsx
|
||||
curl --location --request DELETE '<SERVER_URL>/admin/price-lists/<PRICE_LIST_ID>' \
|
||||
--header 'Authorization: Bearer {api_token}'
|
||||
--header 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@@ -466,7 +466,7 @@ This request returns the ID of the deleted price list.
|
||||
|
||||
---
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn more about [price lists](./index.md).
|
||||
- Learn how the [price selection strategy works](../price-selection-strategy/index.md).
|
||||
@@ -60,7 +60,7 @@ The context that is passed to the `calculateVariantPrice` method is an object th
|
||||
|
||||
---
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn [how to override the price selection strategy](./override.md).
|
||||
- Learn more about [price lists](./../price-lists/index.md).
|
||||
|
||||
@@ -106,6 +106,6 @@ Then, try out your strategy using any of the [Products](https://docs.medusajs.co
|
||||
|
||||
---
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn more about [price list selection strategy](./index.md).
|
||||
|
||||
@@ -68,6 +68,7 @@ The relation is implemented in the [Order](../../../references/entities/classes/
|
||||
|
||||
---
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn how to [manage Sales Channels using the Admin APIs](./manage-admin.mdx).
|
||||
- Check out the [Sales Channel’s Admin APIs](https://docs.medusajs.com/api/admin/#tag/Sales-Channel).
|
||||
|
||||
@@ -0,0 +1,522 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# How to Use SalesChannels APIs
|
||||
|
||||
In this document, you’ll learn how to manage sales channels and their products and orders using the Admin APIs.
|
||||
|
||||
:::note
|
||||
|
||||
If you’re looking to learn more in-depth about what Sales Channels are and how they work, check out [this documentation](./index.md) instead.
|
||||
|
||||
:::
|
||||
|
||||
## Overview
|
||||
|
||||
Using Medusa’s 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 server installed and set up. If not, you can follow our [quickstart guide](../../../quickstart/quick-start.md) to get started.
|
||||
|
||||
### Enabled Feature Flags
|
||||
|
||||
The Sales Channels feature is currently in beta mode and guarded by a feature flag. To use sales channels either:
|
||||
|
||||
1. Enable the `MEDUSA_FF_SALES_CHANNELS` environment variable;
|
||||
2. Or enable the `sales_channels` key in the Medusa server's settings.
|
||||
|
||||
You can learn more about enabling it in the [feature flags](../feature-flags/toggle.md) documentation.
|
||||
|
||||
### JS Client
|
||||
|
||||
This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, JavaScript’s Fetch API, or cURL.
|
||||
|
||||
If you follow the JS Client code blocks, it’s assumed you already have [Medusa’s JS Client installed](../../../js-client/overview.md) and [have created an instance of the client](../../../js-client/overview.md#configuration).
|
||||
|
||||
### 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](https://docs.medusajs.com/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">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.salesChannels.create({
|
||||
name: 'App',
|
||||
description: 'Mobile app'
|
||||
})
|
||||
.then(({ sales_channel }) => {
|
||||
console.log(sales_channel.id);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/sales-channels`, {
|
||||
method: 'POST',
|
||||
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 --location --request POST '<SERVER_URL>/admin/sales-channels' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>' \
|
||||
--header '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">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.salesChannels.list()
|
||||
.then(({ sales_channels, limit, offset, count }) => {
|
||||
console.log(sales_channels.length);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/sales-channels`)
|
||||
.then((response) => response.json())
|
||||
.then(({ sales_channels, limit, offset, count }) => {
|
||||
console.log(sales_channels.length)
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl --location --request GET '<SERVER_URL>/admin/sales-channels' \
|
||||
--header '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.](https://docs.medusajs.com/api/admin/#tag/Sales-Channel/operation/GetSalesChannels)
|
||||
|
||||
---
|
||||
|
||||
## Retrieve a Sales Channel
|
||||
|
||||
You can retrieve a sales channel’s details by its ID using the Get Sales Channel endpoint:
|
||||
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.salesChannels.retrieve(salesChannelId)
|
||||
.then(({ sales_channel }) => {
|
||||
console.log(sales_channel.id);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}`)
|
||||
.then((response) => response.json())
|
||||
.then(({ sales_channels, limit, offset, count }) => {
|
||||
console.log(sales_channels.length)
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl --location --request GET '<SERVER_URL>/admin/sales-channels/<SALES_CHANNEL_ID>' \
|
||||
--header '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 Channel’s details and attributes by sending a request to the Update Sales Channel endpoint:
|
||||
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.salesChannels.update(salesChannelId, {
|
||||
is_disabled: false
|
||||
})
|
||||
.then(({ sales_channel }) => {
|
||||
console.log(sales_channel.id);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}`, {
|
||||
method: 'POST',
|
||||
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 --location --request POST '<SERVER_URL>/admin/sales-channels/<SALES_CHANNEL_ID>' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>' \
|
||||
--header '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](https://docs.medusajs.com/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">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.salesChannels.delete(salesChannelId)
|
||||
.then(({ id, object, deleted }) => {
|
||||
console.log(id);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}`, {
|
||||
method: 'DELETE'
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ id, object, deleted }) => {
|
||||
console.log(id)
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl --location --request DELETE '<SERVER_URL>/admin/sales-channels/<SALES_CHANNEL_ID>' \
|
||||
--header '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 Channel’s Add Products endpoint:
|
||||
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.salesChannels.addProducts(salesChannelId, {
|
||||
product_ids: [
|
||||
{
|
||||
id: productId
|
||||
}
|
||||
]
|
||||
})
|
||||
.then(({ sales_channel }) => {
|
||||
console.log(sales_channel.id);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}/products/batch`, {
|
||||
method: 'POST',
|
||||
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 --location --request POST '<SERVER_URL>/admin/sales-channels/<SALES_CHANNEL_ID>/products/batch' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>' \
|
||||
--header '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">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.products.list({
|
||||
sales_channel_id: [
|
||||
salesChannelId
|
||||
]
|
||||
})
|
||||
.then(({ products, limit, offset, count }) => {
|
||||
console.log(products.length);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/products?sales_channel_id[0]=${salesChannelId}`)
|
||||
.then((response) => response.json())
|
||||
.then(({ products, limit, offset, count }) => {
|
||||
console.log(products.length)
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```bash
|
||||
curl --location --request GET '<SERVER_URL>/admin/products?sales_channel_id[0]=<SALES_CHANNEL_ID>' \
|
||||
--header '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 Channel’s Delete Products endpoint:
|
||||
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.salesChannels.removeProducts(salesChannelId, {
|
||||
product_ids: [
|
||||
{
|
||||
id: productId
|
||||
}
|
||||
]
|
||||
})
|
||||
.then(({ sales_channel }) => {
|
||||
console.log(sales_channel.id);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}/products/batch`, {
|
||||
method: 'DELETE',
|
||||
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">
|
||||
|
||||
```jsx
|
||||
curl --location --request DELETE '<SERVER_URL>/admin/sales-channels/<SALES_CHANNEL_ID>/products/batch' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>' \
|
||||
--header '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">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.admin.orders.list({
|
||||
sales_channel_id: [
|
||||
salesChannelId
|
||||
],
|
||||
limit: 50,
|
||||
offset: 0
|
||||
})
|
||||
.then(({ orders, limit, offset, count }) => {
|
||||
console.log(orders.length);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/admin/orders?sales_channel_id[0]=${salesChannelId}`)
|
||||
.then((response) => response.json())
|
||||
.then(({ orders, limit, offset, count }) => {
|
||||
console.log(orders.length)
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="curl" label="cURL">
|
||||
|
||||
```jsx
|
||||
curl --location --request GET '<SERVER_URL>/admin/orders?sales_channel_id[0]=<SALES_CHANNEL_ID>' \
|
||||
--header 'Authorization: Bearer <API_TOKEN>'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The request returns an array of orders that are associated with the specified sales channel.
|
||||
|
||||
---
|
||||
|
||||
## What’s Next
|
||||
|
||||
- Learn more about [Sales Channels and how they work](./index.md).
|
||||
@@ -90,7 +90,7 @@ constructor({ helloService, eventBusService }) {
|
||||
}
|
||||
```
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Check out the [Services Reference](/references/services/classes/AuthService) to see a list of all services in Medusa.
|
||||
- [Learn How to Create an Endpoint.](/advanced/backend/endpoints/add-storefront)
|
||||
- [Learn How to Create an Endpoint.](../endpoints/add.md)
|
||||
|
||||
@@ -18,7 +18,7 @@ For example, if the file name is `hello.js`, the service will be registered as `
|
||||
|
||||
The registration name of the service is important, as you’ll be referring to it when you want to get access to the service using dependency injection or in routes.
|
||||
|
||||
## What's Next :rocket:
|
||||
## What's Next
|
||||
|
||||
- Learn [how to create a service](./create-service.md)
|
||||
- Check out the [Services Reference](/references/services/classes/AuthService) to see a list of all services in Medusa.
|
||||
|
||||
@@ -266,7 +266,7 @@ cancelFulfillment(fulfillment) {
|
||||
}
|
||||
```
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Check out the [Webshipper plugin](https://github.com/medusajs/medusa/tree/cab5821f55cfa448c575a20250c918b7fc6835c9/packages/medusa-fulfillment-webshipper) for an example of a fulfillment provider that interacts with a third-party providers.
|
||||
- Check out the [manual fulfillment plugin](https://github.com/medusajs/medusa/tree/cab5821f55cfa448c575a20250c918b7fc6835c9/packages/medusa-payment-manual) for a basic implementation of a fulfillment provider.
|
||||
|
||||
@@ -135,7 +135,7 @@ The `ShippingMethod` also belongs to the `Order` entity. This association is
|
||||
|
||||
The `ShippingMethod` instance holds a `price` attribute, which will either be the flat rate price or the calculated price.
|
||||
|
||||
## What’s Next :rocket:
|
||||
## What’s Next
|
||||
|
||||
- [Learn how to Create a Fulfillment Provider.](./add-fulfillment-provider.md)
|
||||
- Check out [available shipping plugins](https://github.com/medusajs/medusa/tree/master/packages).
|
||||
|
||||
@@ -71,7 +71,7 @@ constructor({ productService, eventBusService }) {
|
||||
|
||||
You can then use `this.productService` anywhere in your subscriber’s methods.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- [View the list of all events](events-list.md)
|
||||
- [Learn how to create a service.](/advanced/backend/services/create-service)
|
||||
|
||||
@@ -2153,7 +2153,7 @@ Object of the following format:
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn how you can [use services in subscribers](create-subscriber.md#using-services-in-subscribers).
|
||||
- Learn how to [create notifications](../notification/overview.md) in Medusa.
|
||||
|
||||
@@ -20,7 +20,7 @@ Custom subscribers reside in your project's `src/subscribers` directory. Files h
|
||||
|
||||
Whenever an event is emitted, the subscriber’s registered handler method is executed. The handler method receives as a parameter an object that holds data related to the event. For example, if an order is placed the `order.placed` event will be emitted and all the handlers will receive the order id in the parameter object.
|
||||
|
||||
## What's Next :rocket:
|
||||
## What's Next
|
||||
|
||||
- Learn [how to create a Subscriber](create-subscriber.md).
|
||||
- [View the list of all events](events-list.md).
|
||||
|
||||
@@ -187,7 +187,7 @@ The relevant fields are:
|
||||
|
||||
During the calculation of the totals of different components of the cart or order, such as shipping or line items, if tax inclusivity is enabled on that component, a process similar to those explained above will be applied to retrieve the total.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn how to [calculate taxes manually](manual-calculation.md).
|
||||
- [Check out the API reference](https://docs.medusajs.com/api/store/).
|
||||
|
||||
@@ -82,7 +82,7 @@ You can learn how to [retrieve and use services](../services/create-service.md#u
|
||||
|
||||
:::
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn about [tax-inclusive pricing](inclusive-pricing.md).
|
||||
- Learn about available methods in [CartsService](../../../references/services/classes/CartService.md) and [TotalsService](../../../references/services/classes/TotalsService.md).
|
||||
|
||||
@@ -19,31 +19,37 @@ It’s recommended to go through the [Shipping Architecture Overview](../backend
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Medusa Components
|
||||
|
||||
It's assumed that you already have a Medusa server installed and set up. If not, you can follow our [quickstart guide](../../quickstart/quick-start.md) to get started.
|
||||
|
||||
It is also assumed you already have a storefront set up. It can be a custom storefront or one of Medusa’s storefronts. If you don’t have a storefront set up, you can install either the [Next.js](../../starters/nextjs-medusa-starter.md) or [Gatsby](../../starters/gatsby-medusa-starter.md) storefronts.
|
||||
|
||||
### JS Client
|
||||
|
||||
This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client and JavaScript’s Fetch API.
|
||||
|
||||
If you follow the JS Client code blocks, it’s assumed you already have [Medusa’s JS Client installed](../../js-client/overview.md) and have [created an instance of the client](../../js-client/overview.md#configuration).
|
||||
|
||||
### Previous Steps
|
||||
|
||||
This document assumes you’ve already taken care of the add-to-cart flow. So, you should have a [cart created](https://docs.medusajs.com/api/store/#tag/Cart/operation/PostCart) for the customer with at least [one product in it](https://docs.medusajs.com/api/store/#tag/Cart/operation/PostCartsCartLineItems).
|
||||
|
||||
You can learn how to implement the cart flow using [this documentation](../../guides/carts-in-medusa.mdx).
|
||||
|
||||
To follow along with this tutorial, you can make use of the [Medusa JS Client](https://www.npmjs.com/package/@medusajs/medusa-js). You can install it with this command:
|
||||
|
||||
```bash npm2yarn
|
||||
npm install @medusajs/medusa-js
|
||||
```
|
||||
|
||||
There’s also an alternative approach in this document using [JavaScript’s Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) in case you’re unable to use Medusa’s JS Client. Make sure to replace `<SERVER_URL>` in those examples with your server URL.
|
||||
|
||||
## Shipping Step
|
||||
|
||||
In this step, the customer generally enters their shipping info, then chooses the available shipping option based on the entered info.
|
||||
|
||||
### Add Shipping Address
|
||||
|
||||
After the customer enters their shipping address information, you must send a `POST` request to the [Update a Cart](https://docs.medusajs.com/api/store/#tag/Cart/operation/PostCartsCart) API endpoint passing it the new shipping address:
|
||||
After the customer enters their shipping address information, you must send a `POST` request to the [Update a Cart](https://docs.medusajs.com/api/store/#tag/Cart/operation/PostCartsCart) API endpoint:
|
||||
|
||||
<Tabs groupId="request-tyoe">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.carts.update(cart.id, {
|
||||
medusa.carts.update(cartId, {
|
||||
shipping_address: {
|
||||
company,
|
||||
first_name,
|
||||
@@ -56,8 +62,9 @@ medusa.carts.update(cart.id, {
|
||||
postal_code,
|
||||
phone
|
||||
},
|
||||
}).then((response) => {
|
||||
//updated cart is in response.cart
|
||||
})
|
||||
.then(({ cart }) => {
|
||||
console.log(cart.shipping_address);
|
||||
})
|
||||
```
|
||||
|
||||
@@ -65,7 +72,7 @@ medusa.carts.update(cart.id, {
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/store/carts/${cart.id}`, {
|
||||
fetch(`<SERVER_URL>/store/carts/${cartId}`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
shipping_address: {
|
||||
@@ -84,46 +91,51 @@ fetch(`<SERVER_URL>/store/carts/${cart.id}`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((response) => response.json())
|
||||
.then((response) => {
|
||||
//updated cart is in response.cart
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ cart }) => {
|
||||
console.log(cart.shipping_address);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
You can have access to the updated cart in `response.cart`, which now has the shipping address you added in `response.cart.shipping_address`.
|
||||
This request accepts the ID of the cart as a path parameter and the new shipping address in the request body.
|
||||
|
||||
The request returns the updated cart, with the new shipping address available in `cart.shipping_address`.
|
||||
|
||||
### List Shipping Options
|
||||
|
||||
After updating the cart with the customer’s address, the list of available [shipping options](../backend/shipping/overview.md#shipping-option) for that cart might change. So, you should retrieve the updated list of options by sending a `GET` request to the [Retrieve Shipping Options for Cart API](https://docs.medusajs.com/api/store/#tag/Shipping-Option/operation/GetShippingOptionsCartId) endpoint:
|
||||
After updating the cart with the customer’s address, the list of available [shipping options](../backend/shipping/overview.md#shipping-option) for that cart might change. So, you should retrieve the updated list of options.
|
||||
|
||||
You can retrieve the list of shipping options by sending a `GET` request to the [Retrieve Shipping Options for Cart API](https://docs.medusajs.com/api/store/#tag/Shipping-Option/operation/GetShippingOptionsCartId) endpoint:
|
||||
|
||||
<Tabs groupId="request-tyoe">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.shippingOptions.listCartOptions(cart.id)
|
||||
.then((response) => {
|
||||
//shipping options available in response.shipping_options
|
||||
})
|
||||
medusa.shippingOptions.listCartOptions(cartId)
|
||||
.then(({ shipping_options }) => {
|
||||
console.log(shipping_options.length);
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/store/shipping-options/${cart.id}`)
|
||||
.then((response) => response.json())
|
||||
.then((response) => {
|
||||
//shipping options available in response.shipping_options
|
||||
})
|
||||
fetch(`<SERVER_URL>/store/shipping-options/${cartId}`)
|
||||
.then((response) => response.json())
|
||||
.then(({ shipping_options }) => {
|
||||
console.log(shipping_options.length);
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
You can access all shipping options available with their info in `response.shipping_options` which is an array of [shipping options](https://docs.medusajs.com/api/store/#tag/Shipping-Option/operation/GetShippingOptions). Typically you would display those options to the customer to choose from.
|
||||
The request accepts the ID of the cart as a path parameter. It returns the array of [shipping options](https://docs.medusajs.com/api/store/#tag/Shipping-Option/operation/GetShippingOptions). Typically you would display those options to the customer to choose from.
|
||||
|
||||
### Choose Shipping Option
|
||||
|
||||
@@ -133,35 +145,39 @@ Once the customer chooses one of the available shipping options, send a `POST` r
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.carts.addShippingMethod(cart.id, {
|
||||
option_id: shipping_option.id //shipping_option is the select option
|
||||
}).then((response) => {
|
||||
//updated cart is in response.cart
|
||||
})
|
||||
medusa.carts.addShippingMethod(cartId, {
|
||||
option_id: shippingOptionId //the ID of the selected option
|
||||
})
|
||||
.then(({ cart }) => {
|
||||
console.log(cart.shipping_methods)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/store/carts/${cart.id}/shipping-methods`, {
|
||||
fetch(`<SERVER_URL>/store/carts/${cartId}/shipping-methods`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
option_id: shipping_option.id //shipping_option is the select option
|
||||
option_id: shippingOptionId //the ID of the selected option
|
||||
}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((response) => response.json())
|
||||
.then((response) => {
|
||||
//updated cart is in response.cart
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ cart }) => {
|
||||
console.log(cart.shipping_methods)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
You can have access to the updated cart in `response.cart`, which now has one item in the array value of the property `shipping_methods`.
|
||||
The request accepts the ID of the cart as a path parameter and its body the ID of the selected shipping option.
|
||||
|
||||
It returns the updated cart, with the created shipping method available in the array `cart.shipping_methods`.
|
||||
|
||||
## Payment Step
|
||||
|
||||
@@ -177,28 +193,29 @@ To initialize the payment sessions, send a `POST` request to the [Initialize Pay
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.carts.createPaymentSessions(cart.id)
|
||||
.then((response) => {
|
||||
//updated cart is in response.cart
|
||||
})
|
||||
medusa.carts.createPaymentSessions(cartId)
|
||||
.then(({ cart }) => {
|
||||
console.log(cart.payment_sessions)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/store/carts/${cart.id}/payment-sessions`, {
|
||||
fetch(`<SERVER_URL>/store/carts/${cartId}/payment-sessions`, {
|
||||
method: 'POST'
|
||||
}).then((response) => response.json())
|
||||
.then((response) => {
|
||||
//updated cart is in response.cart
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ cart }) => {
|
||||
console.log(cart.payment_sessions)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
You can then access the initialized payment sessions under the `payment_sessions` array in `response.cart`.
|
||||
This endpoint accepts the ID of the cart as a path parameter. It returns the updated cart with the initialized payment sessions available on `cart.payment_sessions`.
|
||||
|
||||
### Select Payment Session
|
||||
|
||||
@@ -208,10 +225,11 @@ When the customer chooses the payment provider they want to complete purchase wi
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.carts.setPaymentSession(cart.id, {
|
||||
provider_id: payment_session.provider_id //payment_session is the session chosen by the customer
|
||||
}).then((response) => {
|
||||
//updated cart is in response.cart
|
||||
medusa.carts.setPaymentSession(cartId, {
|
||||
provider_id: paymentProviderId // retrieved from the payment session selected by the customer
|
||||
})
|
||||
.then(({ cart }) => {
|
||||
console.log(cart.payment_session)
|
||||
})
|
||||
```
|
||||
|
||||
@@ -219,24 +237,27 @@ medusa.carts.setPaymentSession(cart.id, {
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/store/carts/${cart.id}/payment-session`, {
|
||||
fetch(`<SERVER_URL>/store/carts/${cartId}/payment-session`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
provider_id: payment_session.provider_id //payment_session is the session chosen by the customer
|
||||
provider_id: paymentProviderId // retrieved from the payment session selected by the customer
|
||||
}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((response) => response.json())
|
||||
.then((response) => {
|
||||
//updated cart is in response.cart
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ cart }) => {
|
||||
console.log(cart.payment_session)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
You can then access the selected payment session in `response.cart.payment_session`.
|
||||
The request accepts the ID of the cart as a path parameter, and the ID of the payment provider in the request's body.
|
||||
|
||||
It returns the updated cart, with the selected payment session available under `cart.payment_session`.
|
||||
|
||||
:::tip
|
||||
|
||||
@@ -248,20 +269,21 @@ If you have one payment provider or if only one payment provider is available fo
|
||||
|
||||
This step is optional and is only necessary for some payment providers. As mentioned in the [Payment Architecture](../backend/payment/overview.md#overview) documentation, the `PaymentSession` model has a `data` attribute that holds any data required for the Payment Provider to perform payment operations such as capturing payment.
|
||||
|
||||
If you need to update that data at any point before the purchase is made, send a request to [Update a Payment Session](https://docs.medusajs.com/api/store/#tag/Cart/operation/PostCartsCartPaymentSessionUpdate) API endpoint passing it the updated data object:
|
||||
If you need to update that data at any point before the purchase is made, send a request to [Update a Payment Session](https://docs.medusajs.com/api/store/#tag/Cart/operation/PostCartsCartPaymentSessionUpdate) API endpoint:
|
||||
|
||||
<Tabs groupId="request-tyoe">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.carts.updatePaymentSession(cart.id, cart.payment_session.provider_id, {
|
||||
medusa.carts.updatePaymentSession(cartId, paymentProviderId, {
|
||||
data: {
|
||||
//pass any data you want to add in the `data` attribute
|
||||
//for example:
|
||||
//for example:
|
||||
"test": true
|
||||
}
|
||||
}).then((response) => {
|
||||
//updated cart is in response.cart
|
||||
})
|
||||
.then(({ cart }) => {
|
||||
console.log(cart.payment_session.data)
|
||||
})
|
||||
```
|
||||
|
||||
@@ -269,7 +291,7 @@ medusa.carts.updatePaymentSession(cart.id, cart.payment_session.provider_id, {
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/store/carts/${cart.id}/payment-sessions/${cart.payment_session.provider_id}`, {
|
||||
fetch(`<SERVER_URL>/store/carts/${cartId}/payment-sessions/${paymentProviderId}`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
data: {
|
||||
@@ -281,16 +303,19 @@ fetch(`<SERVER_URL>/store/carts/${cart.id}/payment-sessions/${cart.payment_sessi
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((response) => response.json())
|
||||
.then((response) => {
|
||||
//updated cart is in response.cart
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ cart }) => {
|
||||
console.log(cart.payment_session.data)
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
You can have access to the updated data in the payment session in `response.cart.payment_session.data`.
|
||||
This request accepts the ID of the cart and the ID of the payment session's payment provider as path parameters. In the request's body, it accepts a `data` object where you can pass any data relevant for the payment provider.
|
||||
|
||||
It returns the updated cart. You can access the payment session's data on `cart.payment_session.data`.
|
||||
|
||||
### Complete Cart
|
||||
|
||||
@@ -302,33 +327,38 @@ To complete a cart, send a `POST` request to the [Complete a Cart](https://docs.
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
medusa.carts.complete(cart.id)
|
||||
.then((response) => {
|
||||
//order details is in response.data
|
||||
})
|
||||
medusa.carts.complete(cartId)
|
||||
.then(({ type, data }) => {
|
||||
console.log(type, data);
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/store/carts/${cart.id}/complete`, {
|
||||
fetch(`<SERVER_URL>/store/carts/${cartId}/complete`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((response) => response.json())
|
||||
.then((response) => {
|
||||
//order details is in response.data
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({ type, data }) => {
|
||||
console.log(type, data);
|
||||
})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
If the order is placed successfully, you can access the order data in `response.data` and the value for `response.type` is `order`. Otherwise, `response.data` holds the cart details and `response.type` is `cart`.
|
||||
This request accepts the ID of the cart as a path parameter.
|
||||
|
||||
## What’s Next 🚀
|
||||
The request returns two properties: `type` and `data`. If the order was placed successfully, `type` will be `order` and `data` will be the order's data.
|
||||
|
||||
If an error occurred while placing the order, `type` will be `cart` and `data` will be the cart's data.
|
||||
|
||||
## What’s Next
|
||||
|
||||
- Learn more about the [JS Client and how to use it](../../js-client/overview.md).
|
||||
- Check out available plugins for popular payment providers such as [Stripe](../../add-plugins/stripe.md) and [PayPal](/add-plugins/paypal.md).
|
||||
|
||||
@@ -16,6 +16,12 @@ To install the CLI tool, run the following command in your terminal:
|
||||
npm install @medusajs/medusa-cli -g
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
If you run into any errors while installing the CLI tool, check out the [troubleshooting guide](../troubleshooting/cli-installation-errors.mdx).
|
||||
|
||||
:::
|
||||
|
||||
The CLI tool is then available under the `medusa` command. You can see all commands and options with the following command:
|
||||
|
||||
```bash
|
||||
@@ -200,7 +206,7 @@ medusa telemetry
|
||||
| `--enable` | Enable telemetry (default) |
|
||||
| `--disable` | Disable telemetry |
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn more about [anonymous usage data collection](../usage.md).
|
||||
- Learn how to [configure your Medusa server](../usage/configurations.md).
|
||||
|
||||
@@ -269,7 +269,7 @@ Where `<ADMIN_URL>` is the URL of your Medusa Admin that you just deployed.
|
||||
|
||||
Then, restart your Medusa server. Once the server is running again, you can log in to the Medusa Admin and use it.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn how to [deploy your storefront](../storefront/index.mdx).
|
||||
- Learn more about [how you can configure Medusa](../../usage/configurations.md).
|
||||
|
||||
@@ -275,7 +275,7 @@ Then, scroll down and find Environment Variables. You can expand the environment
|
||||
|
||||
Once you click Save, the environment variables will be saved and a redeployment will be triggered.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn [how to deploy the Medusa Admin to Netlify](../admin/deploying-on-netlify.md).
|
||||
- Learn [how to deploy the Gatsby Storefront to Netlify](../storefront/deploying-gatsby-on-netlify.md).
|
||||
|
||||
@@ -280,7 +280,7 @@ heroku config:set <ENV_NAME>=<ENV_VALUE> -a <APP_NAME>
|
||||
|
||||
Where `<APP_NAME>` is the name of your Heroku app, `<ENV_NAME>` is the name of the environment variable, and `<ENV_VALUE>` is the value.
|
||||
|
||||
## What's Next :rocket:
|
||||
## What's Next
|
||||
|
||||
- Learn how to [deploy your Medusa admin](../admin/index.mdx).
|
||||
- Learn how to [deploy your storefront](../storefront/index.mdx).
|
||||
|
||||
@@ -502,7 +502,7 @@ To add environment variables, in your [Qovery Console](https://console.qovery.co
|
||||
|
||||

|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn how to [deploy the Medusa Admin to Netlify](../admin/deploying-on-netlify.md).
|
||||
- Learn how to [deploy the Gatsby Storefront to Netlify](../storefront/deploying-gatsby-on-netlify.md).
|
||||
|
||||
@@ -305,7 +305,7 @@ Where `<STOREFRONT_URL>` is the URL of your Gatsby storefront that you just depl
|
||||
|
||||
Then, restart your Medusa server. Once the server is running again, you can use your Gatsby storefront.
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn how to [deploy the Medusa Admin](../admin/index.mdx).
|
||||
- Learn more about [Medusa’s configurations](../../usage/configurations.md).
|
||||
|
||||
@@ -20,53 +20,28 @@ This document does not cover implementing the checkout flow. You can refer to [t
|
||||
|
||||
## Prerequisites
|
||||
|
||||
It is assumed you already have a Medusa server installed before following along with this tutorial. If not, you can get started in minutes by following the [quickstart guide](../quickstart/quick-start.md).
|
||||
### Medusa Components
|
||||
|
||||
It's assumed that you already have a Medusa server installed and set up. If not, you can follow our [quickstart guide](../quickstart/quick-start.md) to get started.
|
||||
|
||||
It is also assumed you already have a storefront set up. It can be a custom storefront or one of Medusa’s storefronts. If you don’t have a storefront set up, you can install either the [Next.js](../starters/nextjs-medusa-starter.md) or [Gatsby](../starters/gatsby-medusa-starter.md) storefronts.
|
||||
|
||||
## Install the JS Client
|
||||
### JS Client
|
||||
|
||||
It is recommended to use Medusa’s JS Client in your storefront. You can install it using the following command:
|
||||
This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client and JavaScript’s Fetch API.
|
||||
|
||||
```bash npm2yarn
|
||||
npm install @medusajs/medusa-js
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
This document alternatively shows code examples using [JavaScript’s Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch). Make sure to replace `<SERVER_URL>` in those examples with your server URL.
|
||||
|
||||
:::
|
||||
|
||||
Then, initialize the Medusa JS Client in a single file that all of your components can access:
|
||||
|
||||
```jsx
|
||||
import Medusa from '@medusajs/medusa-js';
|
||||
|
||||
export const client = new Medusa({
|
||||
baseUrl: '<SERVER_URL>',
|
||||
maxRetries: 3
|
||||
});
|
||||
```
|
||||
|
||||
Where `<SERVER_URL>` is the URL of your server. If you’re using a local server, it runs on `http://localhost:9000` by default.
|
||||
|
||||
:::caution
|
||||
|
||||
Make sure to include `http://` in the URL when sending requests to the local server. Otherwise, all requests will fail.
|
||||
|
||||
:::
|
||||
If you follow the JS Client code blocks, it’s assumed you already have [Medusa’s JS Client installed](../js-client/overview.md) and have [created an instance of the client](../js-client/overview.md#configuration).
|
||||
|
||||
## Create a Cart
|
||||
|
||||
You can create a cart with the following code snippet:
|
||||
|
||||
<Tabs groupId="request-tyoe">
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
client.carts.create()
|
||||
.then(({cart}) => {
|
||||
medusa.carts.create()
|
||||
.then(({ cart }) => {
|
||||
localStorage.setItem('cart_id', cart.id);
|
||||
//assuming you have a state variable to store the cart
|
||||
setCart(cart);
|
||||
@@ -81,7 +56,7 @@ fetch(`<SERVER_URL>/store/carts`, {
|
||||
method: 'POST'
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({cart}) => {
|
||||
.then(({ cart }) => {
|
||||
localStorage.setItem('cart_id', cart.id);
|
||||
//assuming you have a state variable to store the cart
|
||||
setCart(cart)
|
||||
@@ -91,24 +66,20 @@ fetch(`<SERVER_URL>/store/carts`, {
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
A cart will be created with a random region assigned to it.
|
||||
This request does not require any parameters. It returns the created cart in the response.
|
||||
|
||||
:::note
|
||||
|
||||
The region a cart is associated with determines the currency the cart uses, the tax, payment, and fulfillment providers, and other details and options. So, make sure you use the correct region for a cart.
|
||||
|
||||
:::
|
||||
The cart by default will have a random region assigned to it. You can specify the cart's region by passing in the request's body a `region_id` parameter:
|
||||
|
||||
Otherwise, you can assign it a specific region during creation:
|
||||
|
||||
<Tabs groupId="request-tyoe">
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
client.carts.create({
|
||||
medusa.carts.create({
|
||||
region_id
|
||||
})
|
||||
.then(({cart}) => {
|
||||
.then(({ cart }) => {
|
||||
localStorage.setItem('cart_id', cart.id);
|
||||
//assuming you have a state variable to store the cart
|
||||
setCart(cart);
|
||||
@@ -129,7 +100,7 @@ fetch(`<SERVER_URL>/store/carts`, {
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({cart}) => {
|
||||
.then(({ cart }) => {
|
||||
localStorage.setItem('cart_id', cart.id);
|
||||
//assuming you have a state variable to store the cart
|
||||
setCart(cart)
|
||||
@@ -139,7 +110,13 @@ fetch(`<SERVER_URL>/store/carts`, {
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
To learn about what parameters you can pass during the cart’s creation, check out the [JS Client Reference](../references/js-client/classes/CartsResource.md#create) or the [API Reference](/api/store#tag/Cart/operation/PostCart).
|
||||
Check out the [API Reference](https://docs.medusajs.com/api/store/#tag/Cart/operation/PostCart) for a full list of available request body parameters.
|
||||
|
||||
:::note
|
||||
|
||||
The region a cart is associated with determines the currency the cart uses, the tax, payment, and fulfillment providers, and other details and options. So, make sure you use the correct region for a cart.
|
||||
|
||||
:::
|
||||
|
||||
## Retrieve a Cart
|
||||
|
||||
@@ -147,15 +124,15 @@ Notice that in the previous code snippets, you set the cart’s ID in the local
|
||||
|
||||
You can retrieve the cart at any given point using its ID with the following code snippet:
|
||||
|
||||
<Tabs groupId="request-tyoe">
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
const id = localStorage.getItem('cart_id');
|
||||
|
||||
if (id) {
|
||||
client.carts.retrieve(id)
|
||||
.then(({cart}) => setCart(cart));
|
||||
medusa.carts.retrieve(id)
|
||||
.then(({ cart }) => setCart(cart));
|
||||
}
|
||||
```
|
||||
|
||||
@@ -168,13 +145,15 @@ const id = localStorage.getItem('cart_id');
|
||||
if (id) {
|
||||
fetch(`<SERVER_URL>/store/carts/${id}`)
|
||||
.then((response) => response.json())
|
||||
.then(({cart}) => setCart(cart));
|
||||
.then(({ cart }) => setCart(cart));
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This request accepts the ID of the cart as a path parameter and returns the cart of that ID.
|
||||
|
||||
You can run this code snippet every time the storefront is opened. If a customer has a cart ID stored in their local storage, it’s loaded from the server.
|
||||
|
||||
:::tip
|
||||
@@ -190,14 +169,14 @@ A cart has different data associated with it including the region, email, addres
|
||||
You can use the following snippet to update any of the cart’s data:
|
||||
|
||||
```jsx
|
||||
client.carts.update(cart.id, {
|
||||
medusa.carts.update(cartId, {
|
||||
region_id
|
||||
})
|
||||
.then(({cart}) => setCart(cart));
|
||||
.then(({ cart }) => setCart(cart));
|
||||
```
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/store/carts/${cart.id}`, {
|
||||
fetch(`<SERVER_URL>/store/carts/${cartId}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
@@ -207,34 +186,36 @@ fetch(`<SERVER_URL>/store/carts/${cart.id}`, {
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({cart}) => setCart(cart));
|
||||
.then(({ cart }) => setCart(cart));
|
||||
```
|
||||
|
||||
This updates the region in the cart.
|
||||
This request accepts the ID of the cart as a path parameter. In its body, you can pass any data you want to update in the cart such as the region.
|
||||
|
||||
To find out what data you can update in the cart, check out the [JS Client reference](../references/js-client/classes/CartsResource.md#update) or the [API reference](/api/store/#tag/Cart/operation/PostCartsCart).
|
||||
It returns the updated cart.
|
||||
|
||||
Check out the full list of available request body parameters in the [API Reference](https://docs.medusajs.com/api/store/#tag/Cart/operation/PostCartsCart).
|
||||
|
||||
### Associate a Logged-In Customer with the Cart
|
||||
|
||||
A customer might add items to their cart, then creates an account or log in. In that case, you should ensure that the cart is associated with the logged-in customer moving forward.
|
||||
|
||||
This can be done using the same update operation:
|
||||
You can do that using the same update operation:
|
||||
|
||||
<Tabs groupId="request-tyoe">
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
client.carts.update(cart.id, {
|
||||
medusa.carts.update(cartId, {
|
||||
customer_id
|
||||
})
|
||||
.then(({cart}) => setCart(cart));
|
||||
.then(({ cart }) => setCart(cart));
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/store/carts/${cart.id}`, {
|
||||
fetch(`<SERVER_URL>/store/carts/${cartId}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
@@ -244,7 +225,7 @@ fetch(`<SERVER_URL>/store/carts/${cart.id}`, {
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({cart}) => setCart(cart));
|
||||
.then(({ cart }) => setCart(cart));
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@@ -254,25 +235,25 @@ This updates the `customer_id` associated with the cart to make sure it belongs
|
||||
|
||||
### Associate Guest Customers with a Cart using Email
|
||||
|
||||
In case the customer does not want to use their own account, you must at least associate an email address with the cart before completing the cart and placing the order.
|
||||
In case the customer doesn't want to use their own account, you must at least associate an email address with the cart before completing the cart and placing the order.
|
||||
|
||||
This can be done using the same update operation:
|
||||
You can do that using the same update operation:
|
||||
|
||||
<Tabs groupId="request-tyoe">
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
client.carts.update(cart.id, {
|
||||
medusa.carts.update(cartId, {
|
||||
email: 'user@example.com'
|
||||
})
|
||||
.then(({cart}) => setCart(cart));
|
||||
.then(({ cart }) => setCart(cart));
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/store/carts/${cart.id}`, {
|
||||
fetch(`<SERVER_URL>/store/carts/${cartId}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
@@ -282,7 +263,7 @@ fetch(`<SERVER_URL>/store/carts/${cart.id}`, {
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({cart}) => setCart(cart));
|
||||
.then(({ cart }) => setCart(cart));
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@@ -292,22 +273,22 @@ fetch(`<SERVER_URL>/store/carts/${cart.id}`, {
|
||||
|
||||
To create a line item of a product and add it to a cart, you can use the following code snippet:
|
||||
|
||||
<Tabs groupId="request-tyoe">
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
client.carts.lineItems.create(cart.id, {
|
||||
medusa.carts.lineItems.create(cartId, {
|
||||
variant_id,
|
||||
quantity: 1
|
||||
})
|
||||
.then(({cart}) => setCart(cart));
|
||||
.then(({ cart }) => setCart(cart));
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/store/carts/${cart.id}/line-items`, {
|
||||
fetch(`<SERVER_URL>/store/carts/${cartId}/line-items`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
@@ -318,13 +299,17 @@ fetch(`<SERVER_URL>/store/carts/${cart.id}/line-items`, {
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({cart}) => setCart(cart));
|
||||
.then(({ cart }) => setCart(cart));
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Where `variant_id` is the variant of the product you want to add to the cart.
|
||||
This request accepts the ID of the cart as a path parameter. In the body, it's required to send the ID of the product variant you want to add to the cart and its quantity.
|
||||
|
||||
It returns the updated cart.
|
||||
|
||||
This adds a new line item to the cart. Line items can be accessed using `cart.items` which is an array that holds all line items in the cart. You can learn more about what properties line items have in the [API reference](/api/store/#tag/Cart/operation/PostCartsCartLineItems).
|
||||
|
||||
:::note
|
||||
|
||||
@@ -332,27 +317,25 @@ If you’re using Sales Channels, make sure that the cart and the product belong
|
||||
|
||||
:::
|
||||
|
||||
This adds a new line item to the cart. Line items can be accessed using `cart.items` which is an array that holds all line items in the cart. You can learn more about what properties line items have in the [API reference](/api/store/#tag/Cart/operation/PostCartsCartLineItems).
|
||||
|
||||
## Update Line Item in the Cart
|
||||
|
||||
To update a line item in the cart, you can use the following code snippet:
|
||||
To update a line item's quantity in the cart, you can use the following code snippet:
|
||||
|
||||
<Tabs groupId="request-tyoe">
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
client.carts.lineItems.update(cart.id, line_item_id, {
|
||||
medusa.carts.lineItems.update(cartId, lineItemId, {
|
||||
quantity: 3
|
||||
})
|
||||
.then(({cart}) => setCart(cart))
|
||||
.then(({ cart }) => setCart(cart))
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/store/carts/${cart.id}/line-items/${line_item_id}`, {
|
||||
fetch(`<SERVER_URL>/store/carts/${cartId}/line-items/${lineItemId}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
@@ -362,43 +345,47 @@ fetch(`<SERVER_URL>/store/carts/${cart.id}/line-items/${line_item_id}`, {
|
||||
})
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({cart}) => setCart(cart));
|
||||
.then(({ cart }) => setCart(cart));
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This updates the quantity of the line item in the cart using the item’s ID.
|
||||
This request accepts the ID of the cart and the ID of the line item as path parameters. In the body, it accepts the quantity of the line item.
|
||||
|
||||
It returns the updated cart.
|
||||
|
||||
## Delete a Line Item from the Cart
|
||||
|
||||
To delete a line item from the cart, you can use the following code snippet:
|
||||
|
||||
<Tabs groupId="request-tyoe">
|
||||
<Tabs groupId="request-type">
|
||||
<TabItem value="client" label="Medusa JS Client" default>
|
||||
|
||||
```jsx
|
||||
client.carts.lineItems.delete(cart.id, line_item_id)
|
||||
.then(({cart}) => setCart(cart))
|
||||
medusa.carts.lineItems.delete(cartId, lineItemId)
|
||||
.then(({ cart }) => setCart(cart))
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="fetch" label="Fetch API">
|
||||
|
||||
```jsx
|
||||
fetch(`<SERVER_URL>/store/carts/${cart.id}/line-items/${line_item_id}`, {
|
||||
fetch(`<SERVER_URL>/store/carts/${cartId}/line-items/${lineItemId}`, {
|
||||
method: 'DELETE'
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(({cart}) => setCart(cart));
|
||||
.then(({ cart }) => setCart(cart));
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This deletes a line item from the cart using the item’s ID.
|
||||
This request accepts the ID of the cart and the ID of the line item as path parameters.
|
||||
|
||||
## What’s Next 🚀
|
||||
It returns the updated cart.
|
||||
|
||||
## What’s Next
|
||||
|
||||
- Learn [how to implement the checkout flow in your storefront](../advanced/storefront/how-to-implement-checkout-flow.mdx).
|
||||
- Learn more about the [JS Client and how to use it](../js-client/overview.md).
|
||||
|
||||
@@ -58,9 +58,9 @@ Medusa provides two starter storefronts, one built with [Next.js](./starters/nex
|
||||
|
||||
Alternatively, you can build your own storefront with any frontend framework of your choice just by connecting to your server with the [Storefront REST APIs](https://docs.medusajs.com/api/store).
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Customize your Medusa server by creating your own [endpoints](./advanced/backend/endpoints/add-storefront.md), [services](./advanced/backend/services/create-service.md), and [subscribers](./advanced/backend/subscribers/create-subscriber.md).
|
||||
- Customize your Medusa server by creating your own [endpoints](./advanced/backend/endpoints/add.md), [services](./advanced/backend/services/create-service.md), and [subscribers](./advanced/backend/subscribers/create-subscriber.md).
|
||||
- Check out guides under the Integrations section to install plugins for [CMS](./add-plugins/strapi.md), [Payment](./add-plugins/stripe.md), [Search Engines](./add-plugins/algolia.md), and more.
|
||||
- Deploy your Medusa server in seconds on [Heroku](deployments/server/deploying-on-heroku.mdx), [Qovery](deployments/server/deploying-on-qovery.md), or [Digital Ocean](deployments/server/deploying-on-digital-ocean.md).
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ It's important to configure your Medusa server properly and learn how environmen
|
||||
|
||||
You can learn more about configuring your server and loading environment variables in the [Configure your Server documentation](../usage/configurations.md).
|
||||
|
||||
## What's next :rocket:
|
||||
## What's Next
|
||||
|
||||
- Install the [Next.js](../starters/nextjs-medusa-starter.md) or [Gatsby](../starters/gatsby-medusa-starter.md) storefronts to set up your ecommerce storefront quickly.
|
||||
- Install the [Medusa Admin](../admin/quickstart.md) to supercharge your ecommerce experience with easy access to configurations and features.
|
||||
|
||||
@@ -22,7 +22,7 @@ You can install Node from the [official website](https://nodejs.org/en/).
|
||||
|
||||
:::note
|
||||
|
||||
If you get a permission error when using NPM, check out [NPM's documentation for a solution](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally).
|
||||
If you run into any errors while installing the CLI tool, check out the [troubleshooting guide](../troubleshooting/cli-installation-errors.mdx).
|
||||
|
||||
:::
|
||||
|
||||
@@ -79,7 +79,7 @@ To upload product images to your Medusa server, you must install and configure o
|
||||
- [S3](../add-plugins/s3.md)
|
||||
- [DigitalOcean Spaces](../add-plugins/spaces.md)
|
||||
|
||||
## What's next :rocket:
|
||||
## What's Next
|
||||
|
||||
- Install the [Next.js](../starters/nextjs-medusa-starter.md) or [Gatsby](../starters/gatsby-medusa-starter.md) storefronts to set up your ecommerce storefront.
|
||||
- Install the [Medusa Admin](../admin/quickstart.md) to supercharge your ecommerce experience with easy access to configurations and features.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Quickstart: Gatsby Storefront
|
||||
# Gatsby Storefront Quickstart
|
||||
|
||||
This document guides you to install and set up the Gatsby Storefront for your Medusa Server.
|
||||
|
||||
@@ -107,7 +107,7 @@ The Gatsby storefront comes with a lot of features out of the box including:
|
||||
|
||||

|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Check the [Storefront API reference](https://docs.medusajs.com/api/store) for a full list of REST APIs to use on your storefront.
|
||||
- Learn how to [deploy the Gatsby storefront on Netlify](../deployments/storefront/deploying-gatsby-on-netlify.md).
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Quickstart: Next.js Storefront
|
||||
# Next.js Storefront Quickstart
|
||||
|
||||
This document guides you to install and set up the Next.js Storefront for your Medusa Server.
|
||||
|
||||
@@ -212,7 +212,7 @@ You can learn more about development with Next.js through [their documentation](
|
||||
|
||||

|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Check the [Storefront API reference](https://docs.medusajs.com/api/store) for a full list of REST APIs to use on your storefront.
|
||||
- Learn [how to install Medusa Admin](../admin/quickstart.md).
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Resolve Errors Installing Medusa CLI
|
||||
|
||||
In this document, you can find solutions to some common problems that occur when installing Medusa’s CLI Tool.
|
||||
|
||||
## NPM Error: EACCES Permissions Errors
|
||||
|
||||
If you install the Medusa CLI tool with NPM and get a permission error, NPM proposes as a solution either re-installing NPM with a node version manager (nvm), or manually setting npm’s default directory.
|
||||
|
||||
You can check out more information in [NPM’s documentation](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally).
|
||||
|
||||
<!-- vale off -->
|
||||
|
||||
## Yarn Error: command not found: medusa
|
||||
|
||||
<!-- vale on -->
|
||||
|
||||
If you install the Medusa CLI tool with Yarn, then try to use the CLI tool but get the error:
|
||||
|
||||
```bash
|
||||
command not found: medusa
|
||||
```
|
||||
|
||||
You have to add Yarn’s install location to the PATH variable:
|
||||
|
||||
<Tabs groupId="operating-systems">
|
||||
<TabItem value="unix" label="MacOS / Linux" default>
|
||||
|
||||
```bash
|
||||
export PATH="$(yarn global bin):$PATH"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="windows" label="Windows">
|
||||
|
||||
```bash
|
||||
# MAKE SURE TO INCLUDE %path%
|
||||
setx path "%path%;c:\users\YOURUSERNAME\appdata\local\yarn\bin"
|
||||
# YOURUSERNAME is your account username
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
You can learn more in [Yarn’s documentation](https://classic.yarnpkg.com/en/docs/cli/global#adding-the-install-location-to-your-path).
|
||||
@@ -12,14 +12,6 @@ To get your development environment ready you need to install the following tool
|
||||
|
||||
### Node.js
|
||||
|
||||
:::info
|
||||
|
||||
Node.js is an environment that can execute JavaScript code outside of the browser, making it possible to run on a server.
|
||||
|
||||
Node.js has a bundled package manager called NPM. NPM helps you install "packages" which are small pieces of code that you can leverage in your Node.js applications. Medusa's core is itself a package distributed via NPM and so are all of the plugins that exist around the core.
|
||||
|
||||
:::
|
||||
|
||||
Node.js is the environment that makes it possible for Medusa to run, so you must install Node.js on your computer to start Medusa development.
|
||||
|
||||
:::caution
|
||||
@@ -86,12 +78,6 @@ Make sure that you have Xcode command line tools installed; if not, run the fol
|
||||
|
||||
### Git
|
||||
|
||||
:::info
|
||||
|
||||
Git is a version control system that keeps track of files within a project and makes it possible to do things like going back in history if you have made mistakes or collaborate with teammates without overriding each other's work.
|
||||
|
||||
:::
|
||||
|
||||
Medusa uses Git behind the scenes when you create a new project so you'll have to install it on your computer to get started.
|
||||
|
||||
<Tabs groupId="operating-systems" wrapperClassName={styles.osTabs}>
|
||||
@@ -136,18 +122,18 @@ You can install Medusa’s CLI with the following command:
|
||||
npm install @medusajs/medusa-cli -g
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
If you run into any errors while installing the CLI tool, check out the [troubleshooting guide](../troubleshooting/cli-installation-errors.mdx).
|
||||
|
||||
:::
|
||||
|
||||
## Optional Tools
|
||||
|
||||
These tools are not required to have to run a Medusa server, but it's highly recommended that you have them installed.
|
||||
|
||||
### PostgreSQL
|
||||
|
||||
:::info
|
||||
|
||||
PostgreSQL is an open-source relational database system with more than thirty years of active development. It is robust, reliable, and ensures data integrity so there's no need to worry about those when you scale your project.
|
||||
|
||||
:::
|
||||
|
||||
Although you can use an SQLite database with Medusa which would require no necessary database installations, it is recommended to use a PostgreSQL database for your server.
|
||||
|
||||
:::tip
|
||||
@@ -202,12 +188,6 @@ Where:
|
||||
|
||||
### Redis
|
||||
|
||||
:::info
|
||||
|
||||
Redis is an open-source in-memory data structure store. It can be used for distributing and emitting messages and caching, among other purposes.
|
||||
|
||||
:::
|
||||
|
||||
Medusa uses Redis as the event queue in the server. If you want to use subscribers to handle events such as when an order is placed and perform actions based on the events, then you need to install and configure Redis.
|
||||
|
||||
If you don’t install and configure Redis with your Medusa server, then it will work without any events-related features.
|
||||
@@ -271,7 +251,7 @@ To install Redis without Homebrew you can check out [Redis’s guide on installi
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn how to [configure your Medusa server](../usage/configurations.md).
|
||||
- Learn how to install a storefront with [Next.js](../starters/nextjs-medusa-starter.md) or [Gatsby](./../starters/gatsby-medusa-starter.md).
|
||||
|
||||
@@ -154,10 +154,10 @@ Where `jwt_secret` is the secret used to create the tokens. The more secure it i
|
||||
It is recommended to set the JWT Secret as an environment variable:
|
||||
|
||||
```bash
|
||||
JWT_SECRET=<YOUR_JWT_SECRETL>
|
||||
JWT_SECRET=<YOUR_JWT_SECRET>
|
||||
```
|
||||
|
||||
Where `<YOUR_JWT_SECRETL>` is the JWT secret you want to use.
|
||||
Where `<YOUR_JWT_SECRET>` is the JWT secret you want to use.
|
||||
|
||||
:::caution
|
||||
|
||||
@@ -183,10 +183,10 @@ Where `cookie_secret` is the secret used to create the tokens. The more secure i
|
||||
It is recommended to set the Cookie secret as an environment variable:
|
||||
|
||||
```bash
|
||||
COOKIE_SECRET=<YOUR_COOKIE_SECRETL>
|
||||
COOKIE_SECRET=<YOUR_COOKIE_SECRET>
|
||||
```
|
||||
|
||||
Where `<YOUR_COOKIE_SECRETL>` is the Cookie secret you want to use.
|
||||
Where `<YOUR_COOKIE_SECRET>` is the Cookie secret you want to use.
|
||||
|
||||
:::caution
|
||||
|
||||
@@ -306,7 +306,7 @@ It is recommended to use environment variables to store values of options instea
|
||||
|
||||
:::
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Check out the [Next.js](../starters/nextjs-medusa-starter.md) and [Gatsby](../starters/gatsby-medusa-starter.md) starter storefronts.
|
||||
- Install the [Medusa admin](../admin/quickstart.md).
|
||||
|
||||
@@ -86,7 +86,7 @@ Learn more about the [Next.js](../starters/nextjs-medusa-starter.md) and [Gatsby
|
||||
After choosing the above starters, the installation of each component will begin along with its dependencies. Once the installation is done, you’ll see instructions related to how to start each component.
|
||||
|
||||
```bash
|
||||
Your project is ready 🚀. The available commands are:
|
||||
Your project is ready. The available commands are:
|
||||
|
||||
Medusa API
|
||||
cd my-medusa-store/backend
|
||||
@@ -114,7 +114,7 @@ Inside the root project directory which was specified at the beginning of the in
|
||||
/admin // Medusa admin panel
|
||||
```
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Learn how to [deploy the Medusa server](../deployments/server/index.mdx).
|
||||
- Learn how to [deploy the Medusa admin](../deployments/admin/index.mdx).
|
||||
|
||||
@@ -178,7 +178,7 @@ medusa-dev -q
|
||||
medusa-dev --packages @medusajs/medusa-cli medusa-file-minio
|
||||
```
|
||||
|
||||
## What’s Next 🚀
|
||||
## What’s Next
|
||||
|
||||
- Check out our [contribution guidelines](https://github.com/medusajs/medusa/blob/master/CONTRIBUTING.md).
|
||||
- Learn how to [create a plugin](../advanced/backend/plugins/create.md).
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Manage Customer Groups
|
||||
|
||||
:::note
|
||||
|
||||
This guide is coming soon.
|
||||
|
||||
:::
|
||||
@@ -0,0 +1,115 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Manage Customer Groups
|
||||
|
||||
In this document, you’ll learn how to manage customer groups, including customers in these groups.
|
||||
|
||||
## Create a Customer Group
|
||||
|
||||
To create a customer group:
|
||||
|
||||
1. Go to the Customers page.
|
||||
2. Choose the Groups headline.
|
||||
3. Click on the New Group button.
|
||||
4. In the new window that opens:
|
||||
1. Enter a title for the group.
|
||||
2. Optionally, to add metadata:
|
||||
1. Click on the Add Metadata button.
|
||||
2. Enter a value for the Key and Value Fields.
|
||||
3. To remove a metadata field, click on the <UiIcon lightIcon="https://i.imgur.com/7hztVhj.png" darkIcon="https://i.imgur.com/1yp4PNt.png" alt="trash" /> icon.
|
||||
5. Once you’re done, click on the Publish Group button.
|
||||
|
||||
---
|
||||
|
||||
## View Customer Group Details
|
||||
|
||||
To view the details of a customer group:
|
||||
|
||||
1. Go to the Customers page.
|
||||
2. Choose the Groups headline.
|
||||
3. Click on the name of the group you want to view.
|
||||
|
||||
---
|
||||
|
||||
## Edit a Customer Group
|
||||
|
||||
To edit a customer group:
|
||||
|
||||
1. Go to the customer group’s details page.
|
||||
2. Click on the <UiIcon lightIcon="https://i.imgur.com/1ordBC6.png" darkIcon="https://i.imgur.com/dSwWYBH.png" alt="three dots" /> icon at the right of the group’s name.
|
||||
3. Click on Edit in the dropdown.
|
||||
4. In the new window that opens:
|
||||
1. You can change the title and existing metadata of the group.
|
||||
2. To add metadata:
|
||||
1. Click on the Add Metadata button.
|
||||
2. Enter a value for the Key and Value Fields.
|
||||
3. To remove metadata click on the <UiIcon lightIcon="https://i.imgur.com/7hztVhj.png" darkIcon="https://i.imgur.com/1yp4PNt.png" alt="trash" /> icon.
|
||||
5. Once you’re done, click on the Edit Group button.
|
||||
|
||||
---
|
||||
|
||||
## Manage Customers in a Group
|
||||
|
||||
### View List of Customers in a Group
|
||||
|
||||
To view the list of customers in a customer group:
|
||||
|
||||
1. Go to the customer group’s details page.
|
||||
2. Scroll to the Customers section. You’ll find all customers that belong to this customer group in this section if there are any.
|
||||
|
||||
### Add Customers to a Group
|
||||
|
||||
To add customers to a customer group:
|
||||
|
||||
1. Go to the customer group’s details page.
|
||||
2. Click on the “Edit customers” button at the top right of the Customers section.
|
||||
3. Check the box next to every customer you want to add to the group.
|
||||
4. Click on the Save button.
|
||||
|
||||
### Remove a Customer from a Group
|
||||
|
||||
:::info
|
||||
|
||||
Removing customers from a customer group doesn't remove the customers from your store.
|
||||
|
||||
:::
|
||||
|
||||
To remove customers from a customer group:
|
||||
|
||||
1. Go to the customer group’s details page.
|
||||
2. In the Customer section, click on the <UiIcon lightIcon="https://i.imgur.com/1ordBC6.png" darkIcon="https://i.imgur.com/dSwWYBH.png" alt="three dots" /> icon next to the customer you want to remove from the group.
|
||||
3. Click on “Delete from the Group” from the dropdown.
|
||||
|
||||
### Remove Multiple Customers from a Group
|
||||
|
||||
:::info
|
||||
|
||||
Removing customers from a customer group doesn't remove the customers from your store.
|
||||
|
||||
:::
|
||||
|
||||
To remove more than one customer from a customer group at the same time:
|
||||
|
||||
1. Go to the customer group’s details page.
|
||||
2. Click on the “Edit customers” button at the top right of the Customers section.
|
||||
3. Uncheck the box next to every customer you want to remove from the group.
|
||||
4. Click on the Save button.
|
||||
|
||||
---
|
||||
|
||||
## Delete Customer Group
|
||||
|
||||
:::warning
|
||||
|
||||
Deleting a customer group cannot be undone.
|
||||
|
||||
:::
|
||||
|
||||
To delete a customer group:
|
||||
|
||||
1. Go to the customer group’s details page.
|
||||
2. Click on the <UiIcon lightIcon="https://i.imgur.com/1ordBC6.png" darkIcon="https://i.imgur.com/dSwWYBH.png" alt="three dots" /> icon at the right of the group’s name.
|
||||
3. Click on Delete from the dropdown.
|
||||
4. Confirm deleting the price list by clicking the “Yes, delete” button in the pop-up.
|
||||
@@ -33,4 +33,4 @@ In the list, you can see group details such as the group’s title and the numbe
|
||||
## Learn More About Customers
|
||||
|
||||
- [Manage and View a Customer’s Details](./manage.md)
|
||||
- [Manage and View a Customer Group](./groups.md)
|
||||
- [Manage and View a Customer Group](./groups.mdx)
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
import UiIcon from '@site/src/components/UiIcon';
|
||||
|
||||
# Manage Exchanges
|
||||
|
||||
In this document, you’ll learn how to manage order exchanges including how to find customers’ requested order exchanges, how to create them, and how to fulfill them.
|
||||
|
||||
## Find Requested Order Exchanges
|
||||
|
||||
To find customers’ requested order exchanges:
|
||||
|
||||
1. Go to an order’s details page.
|
||||
2. In the Timeline section, if there are any requested exchanges you’ll find them with the title “Exchange Requested”.
|
||||
|
||||
## Create an Order Exchange
|
||||
|
||||
:::info
|
||||
|
||||
An exchange can only be created if the order’s payment is captured and the items have been fulfilled.
|
||||
|
||||
:::
|
||||
|
||||
To create an order exchange:
|
||||
|
||||
1. Go to an order’s details page.
|
||||
2. In the Timeline section, click on the <UiIcon lightIcon="https://i.imgur.com/1ordBC6.png" darkIcon="https://i.imgur.com/dSwWYBH.png" alt="three dots" /> icon.
|
||||
3. Click on Register Exchange from the dropdown.
|
||||
4. In the new window that opens:
|
||||
1. Choose the items you want the customer to return. For each item you select:
|
||||
1. Click on the Select Reason button.
|
||||
2. Choose a reason from available Reasons. If you can’t find any Reasons, make sure to add Return Reasons in Settings first.
|
||||
3. You can optionally add a Note.
|
||||
4. Once you’re done, click on the Add button.
|
||||
2. Choose a Shipping Method to return the customer’s items.
|
||||
1. You can optionally specify a custom price for shipping by clicking the “Add custom price” button.
|
||||
2. You can remove the custom price by clicking the <UiIcon lightIcon="https://i.imgur.com/7hztVhj.png" darkIcon="https://i.imgur.com/1yp4PNt.png" alt="trash" /> icon.
|
||||
3. In the “Items to send” section, click on the Add Product button. Then:
|
||||
1. Check the products you want to send to the customer in exchange.
|
||||
2. When you’re done, click the Add button.
|
||||
3. You can remove products you’ve added by clicking the <UiIcon lightIcon="https://i.imgur.com/7hztVhj.png" darkIcon="https://i.imgur.com/1yp4PNt.png" alt="trash" /> icon.
|
||||
4. You can change the quantity of the product to send using the <UiIcon lightIcon="https://i.imgur.com/1hL8NiW.png" darkIcon="https://i.imgur.com/8LtkPqW.png" alt="plus" /> and <UiIcon lightIcon="https://i.imgur.com/EGk9uYD.png" darkIcon="https://i.imgur.com/XvkBK8p.png" alt="minus" /> icons.
|
||||
4. If you don’t want the customer to receive an email that an exchange has been registered, uncheck the “Send notifications” checkbox.
|
||||
5. Once you’re done, click the Complete button.
|
||||
|
||||
## Mark an Exchange’s Return as Received
|
||||
|
||||
To mark a return that is part of an exchange as received:
|
||||
|
||||
1. Go to an order’s details page.
|
||||
2. In the Timeline section, find the order exchange.
|
||||
3. Click on the Receive Return button.
|
||||
4. Check the items you want to mark as received.
|
||||
5. Click the Complete button.
|
||||
|
||||
## Cancel an Exchange
|
||||
|
||||
:::warning
|
||||
|
||||
Canceling an exchange can’t be undone.
|
||||
|
||||
:::
|
||||
|
||||
The return of an exchange must be canceled first before the exchange itself can be canceled. If the return has been marked as received, the exchange can’t be canceled after that.
|
||||
|
||||
To cancel an exchange:
|
||||
|
||||
1. Go to an order’s details page.
|
||||
2. In the Timeline section, find the order exchange.
|
||||
3. Click on the <UiIcon lightIcon="https://i.imgur.com/1ordBC6.png" darkIcon="https://i.imgur.com/dSwWYBH.png" alt="three dots" /> icon next to it.
|
||||
4. Click on “Cancel return” from the dropdown.
|
||||
5. Confirm canceling the return by clicking the “Yes, cancel” button in the pop-up.
|
||||
6. Click on the <UiIcon lightIcon="https://i.imgur.com/1ordBC6.png" darkIcon="https://i.imgur.com/dSwWYBH.png" alt="three dots" /> icon again next to the order exchange.
|
||||
7. Click on “Cancel exchange” from the dropdown.
|
||||
8. Confirm canceling the exchange by clicking the “Yes, cancel” button in the pop-up.
|
||||
@@ -39,5 +39,5 @@ In the list, you can see order details such as ID, the ID of the order the draft
|
||||
- [Manage Draft Orders](./drafts.mdx)
|
||||
- [Manage Order Returns](./returns.mdx)
|
||||
- [Manage Order Claims](./claims.mdx)
|
||||
- [Manage Order Exchanges](./swaps.md)
|
||||
- [Export Orders](./export.mdx)
|
||||
- [Manage Order Exchanges](./exchange.mdx)
|
||||
- [Export Orders](./export.mdx)
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
# Manage Exchanges (Swaps)
|
||||
|
||||
:::note
|
||||
|
||||
This guide is coming soon.
|
||||
|
||||
:::
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
sidebar_label: Manage Products
|
||||
---
|
||||
|
||||
import UiIcon from '@site/src/components/UiIcon';
|
||||
|
||||
@@ -46,6 +46,7 @@ const config = {
|
||||
placeholder: "Search docs...",
|
||||
appId: algoliaAppId,
|
||||
contextualSearch: false,
|
||||
externalUrlRegex: "https://medusajs.com"
|
||||
},
|
||||
prism: {
|
||||
defaultLanguage: "js",
|
||||
@@ -180,6 +181,9 @@ const config = {
|
||||
theme: {
|
||||
customCss: require.resolve("./src/css/custom.css")
|
||||
},
|
||||
gtag: {
|
||||
trackingID: 'G-S7G7X3JYS3',
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
|
||||
+23
-8
@@ -222,19 +222,25 @@ module.exports = {
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "advanced/backend/price-lists/use-api"
|
||||
id: "advanced/backend/price-lists/use-api",
|
||||
label: "Use PriceList APIs"
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "advanced/backend/sales-channels/manage-admin",
|
||||
label: "Use SalesChannel APIs"
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "advanced/admin/use-customergroups-api",
|
||||
label: "Use CustomerGroup APIs"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "advanced/backend/endpoints/add-storefront",
|
||||
label: "Create Endpoint for Storefront"
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "advanced/backend/endpoints/add-admin",
|
||||
label: "Create Endpoint for Admin"
|
||||
id: "advanced/backend/endpoints/add",
|
||||
label: "Create an Endpoint"
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
@@ -368,6 +374,10 @@ module.exports = {
|
||||
type: "doc",
|
||||
id: "advanced/backend/sales-channels/index"
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "advanced/backend/customer-groups/index"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -501,6 +511,11 @@ module.exports = {
|
||||
type: "category",
|
||||
label: "Troubleshooting",
|
||||
items: [
|
||||
{
|
||||
type: "doc",
|
||||
id: "troubleshooting/cli-installation-errors",
|
||||
label: "Errors Installing CLI",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "troubleshooting/cors-issues",
|
||||
|
||||
Reference in New Issue
Block a user