Merge branch 'master' into develop

This commit is contained in:
olivermrbl committed 2023-01-31 12:10:52 +01:00
commit 0326d6cfa3
196 files changed
+4672 -837

No files matched your search

+11 -2
View File
@@ -286,11 +286,20 @@ components:
In this API reference, you'll find in the cURL request samples the use of `{api_token}`. This is where you must pass the API token. In this API reference, you'll find in the cURL request samples the use of `{api_token}`. This is where you must pass the API token.
If you're alternatively following along with the JS Client request samples, you must provide the `apiKey` option when creating the Medusa client: If you're following along with the JS Client request samples, you must provide the `apiKey` option when creating the Medusa client:
```js ```ts
const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3, apiKey: '{api_token}' }) const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3, apiKey: '{api_token}' })
``` ```
If you're using Medusa React, you can pass the `apiKey` prop to `MedusaProvider`:
```tsx
<MedusaProvider
apiKey='api_token}'
//...
>
```
scheme: bearer scheme: bearer
cookie_auth: cookie_auth:
type: apiKey type: apiKey
+17 -4
View File
@@ -18648,17 +18648,30 @@ components:
of `{api_token}`. This is where you must pass the API token. of `{api_token}`. This is where you must pass the API token.
If you're alternatively following along with the JS Client request If you're following along with the JS Client request samples, you must
samples, you must provide the `apiKey` option when creating the Medusa provide the `apiKey` option when creating the Medusa client:
client:
```js ```ts
const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3, const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3,
apiKey: '{api_token}' }) apiKey: '{api_token}' })
``` ```
If you're using Medusa React, you can pass the `apiKey` prop to
`MedusaProvider`:
```tsx
<MedusaProvider
apiKey='{api_token}'
//...
>
```
scheme: bearer scheme: bearer
cookie_auth: cookie_auth:
type: apiKey type: apiKey
+17 -4
View File
@@ -18648,17 +18648,30 @@ components:
of `{api_token}`. This is where you must pass the API token. of `{api_token}`. This is where you must pass the API token.
If you're alternatively following along with the JS Client request If you're following along with the JS Client request samples, you must
samples, you must provide the `apiKey` option when creating the Medusa provide the `apiKey` option when creating the Medusa client:
client:
```js ```ts
const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3, const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3,
apiKey: '{api_token}' }) apiKey: '{api_token}' })
``` ```
If you're using Medusa React, you can pass the `apiKey` prop to
`MedusaProvider`:
```tsx
<MedusaProvider
apiKey='{api_token}'
//...
>
```
scheme: bearer scheme: bearer
cookie_auth: cookie_auth:
type: apiKey type: apiKey
+17 -4
View File
@@ -543,17 +543,30 @@ components:
of `{api_token}`. This is where you must pass the API token. of `{api_token}`. This is where you must pass the API token.
If you're alternatively following along with the JS Client request If you're following along with the JS Client request samples, you must
samples, you must provide the `apiKey` option when creating the Medusa provide the `apiKey` option when creating the Medusa client:
client:
```js ```ts
const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3, const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3,
apiKey: '{api_token}' }) apiKey: '{api_token}' })
``` ```
If you're using Medusa React, you can pass the `apiKey` prop to
`MedusaProvider`:
```tsx
<MedusaProvider
apiKey='{api_token}'
//...
>
```
scheme: bearer scheme: bearer
cookie_auth: cookie_auth:
type: apiKey type: apiKey
+2 -2
View File
@@ -3313,7 +3313,7 @@ paths:
const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries:
3 }) 3 })
medusa.store.productTags.list() medusa.productTags.list()
.then(({ product_tags }) => { .then(({ product_tags }) => {
console.log(product_tags.length); console.log(product_tags.length);
@@ -3463,7 +3463,7 @@ paths:
// must be previously logged in or use api token // must be previously logged in or use api token
medusa.store.productTypes.list() medusa.productTypes.list()
.then(({ product_types }) => { .then(({ product_types }) => {
console.log(product_types.length); console.log(product_types.length);
+2 -2
View File
@@ -3313,7 +3313,7 @@ paths:
const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries:
3 }) 3 })
medusa.store.productTags.list() medusa.productTags.list()
.then(({ product_tags }) => { .then(({ product_tags }) => {
console.log(product_tags.length); console.log(product_tags.length);
@@ -3463,7 +3463,7 @@ paths:
// must be previously logged in or use api token // must be previously logged in or use api token
medusa.store.productTypes.list() medusa.productTypes.list()
.then(({ product_types }) => { .then(({ product_types }) => {
console.log(product_types.length); console.log(product_types.length);
@@ -1,6 +1,6 @@
import Medusa from "@medusajs/medusa-js" import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3 }) const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3 })
medusa.store.productTags.list() medusa.productTags.list()
.then(({ product_tags }) => { .then(({ product_tags }) => {
console.log(product_tags.length); console.log(product_tags.length);
}); });
@@ -1,7 +1,7 @@
import Medusa from "@medusajs/medusa-js" import Medusa from "@medusajs/medusa-js"
const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3 }) const medusa = new Medusa({ baseUrl: MEDUSA_BACKEND_URL, maxRetries: 3 })
// must be previously logged in or use api token // must be previously logged in or use api token
medusa.store.productTypes.list() medusa.productTypes.list()
.then(({ product_types }) => { .then(({ product_types }) => {
console.log(product_types.length); console.log(product_types.length);
}); });
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to integrate Algolia with the Medusa server. Learn how to install the Algolia plugin into the Medusa server and how to integrate it into a storefront.'
addHowToData: true
---
# Algolia # Algolia
In this document, you’ll learn how to install the [Algolia plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-algolia) and use it on both your Medusa Server and your storefront. In this document, you’ll learn how to install the [Algolia plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-algolia) and use it on both your Medusa Server and your storefront.
@@ -1,3 +1,8 @@
---
description: 'Learn how to customize the Contentful integration with Medusa and how to customize the Gatsby storefront that is connected to Contentful.'
addHowToData: true
---
# Customize your Medusa and Contentful Integration # Customize your Medusa and Contentful Integration
In this document, you’ll learn how to customize the Contentful integration with Medusa and how to customize the Gatsby storefront that is connected to Contentful. In this document, you’ll learn how to customize the Contentful integration with Medusa and how to customize the Gatsby storefront that is connected to Contentful.
@@ -1,3 +1,8 @@
---
description: 'Learn how to integrate Contentful with the Medusa server and a Gatsby storefront. Contentful is a headless CMS server that provides rich CMS functionalities.'
addHowToData: true
---
# Contentful # Contentful
In this document, you’ll learn how to integrate a Medusa server with Contentful to add rich Content Management System (CMS) functionalities In this document, you’ll learn how to integrate a Medusa server with Contentful to add rich Content Management System (CMS) functionalities
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to integrate Klarna as a payment provider with the Medusa server. Learn how to install Klarna and enable the payment provider in a region.'
addHowToData: true
---
# Klarna # Klarna
In this document, you’ll learn how to integrate Klarna as a payment provider in Medusa. In this document, you’ll learn how to integrate Klarna as a payment provider in Medusa.
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to integrate Mailchimp with the Medusa server. Learn how to install the plugin on the Medusa server and how to add a subscription form.'
addHowToData: true
---
# Mailchimp # Mailchimp
In this document, you’ll learn about the Mailchimp plugin, what it does, and how to use it. In this document, you’ll learn about the Mailchimp plugin, what it does, and how to use it.
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to integrate MeiliSearch with the Medusa server. Learn how to install the MeiliSearch plugin on the Medusa server and integrate it into the storefront.'
addHowToData: true
---
# MeiliSearch # MeiliSearch
In this document, you’ll learn how to install the [MeiliSearch plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-meilisearch) and use it on both your Medusa Server and your storefront. In this document, you’ll learn how to install the [MeiliSearch plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-meilisearch) and use it on both your Medusa Server and your storefront.
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to integrate MinIO with the Medusa server. Learn how to install the MinIO plugin on the Medusa server and configure it.'
addHowToData: true
---
# MinIO # MinIO
This document will guide you through installing the MinIO file service plugin on your Medusa server. This document will guide you through installing the MinIO file service plugin on your Medusa server.
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to integrate PayPal with the Medusa server. Learn how to install the PayPal plugin on the Medusa server and integrate into a storefront.'
addHowToData: true
---
# PayPal # PayPal
This document guides you through setting up PayPal as a payment provider in your Medusa server, admin, and storefront using the [PayPal plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-payment-paypal). This document guides you through setting up PayPal as a payment provider in your Medusa server, admin, and storefront using the [PayPal plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-payment-paypal).
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to integrate the S3 plugin with the Medusa server. Learn how to configure and use S3 to store images related to the Medusa server.'
addHowToData: true
---
# S3 # S3
In this document, you’ll learn how to install the [S3 plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-file-s3) on your Medusa server and use it for storage. In this document, you’ll learn how to install the [S3 plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-file-s3) on your Medusa server and use it for storage.
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to integrate Segment with the Medusa server. Learn how to add custom tracking with Segment and Medusa.'
addHowToData: true
---
# Segment # Segment
In this document, you’ll learn about the [Segment plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-segment), what it does, and how to install and use it. In this document, you’ll learn about the [Segment plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-segment), what it does, and how to install and use it.
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to integrate SendGrid with the Medusa server. Learn how to install the SendGrid plugin and test it out.'
addHowToData: true
---
# SendGrid # SendGrid
In this document, you’ll learn about the [SendGrid plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-sendgrid), what it does, and how to use it. In this document, you’ll learn about the [SendGrid plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-sendgrid), what it does, and how to use it.
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to integrate Slack with the Medusa server. Learn how to create and configure a Slack app and install the Slack plugin on the Medusa server.'
addHowToData: true
---
# Slack # Slack
In this documentation, you'll learn how to add the [Slack plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-slack-notification) to your Medusa server to start receiving order notifications. In this documentation, you'll learn how to add the [Slack plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-slack-notification) to your Medusa server to start receiving order notifications.
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to integrate Spaces with the Medusa server. Learn how to install and configure the Spaces plugin on the Medusa server.'
addHowToData: true
---
# Spaces # Spaces
In this document, you’ll learn how to install the [Spaces plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-file-spaces) on your Medusa server and use it for storage. In this document, you’ll learn how to install the [Spaces plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-file-spaces) on your Medusa server and use it for storage.
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to integrate Strapi with the Medusa server. Learn how to install the plugin and test two-way sync between the ecommerce and CMS services.'
addHowToData: true
---
# Strapi # Strapi
In this document, you’ll learn how to integrate Strapi with Medusa to add rich Content Management System (CMS) functionalities. In this document, you’ll learn how to integrate Strapi with Medusa to add rich Content Management System (CMS) functionalities.
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to integrate Stripe with the Medusa server. Learn how to install the Stripe plugin on the Medusa server and integrate it into a storefront.'
addHowToData: true
---
# Stripe # Stripe
This document guides you through setting up Stripe payments in your Medusa server, admin, and storefront using the [Stripe Plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-payment-stripe). This document guides you through setting up Stripe payments in your Medusa server, admin, and storefront using the [Stripe Plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-payment-stripe).
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to integrate Twilio SMS with the Medusa server. Learn how to install the Twilio SMS plugin and test it out.'
addHowToData: true
---
# Twilio SMS # Twilio SMS
In this document, you’ll learn about the Twilio SMS Plugin, what it does, and how to use it in Medusa. In this document, you’ll learn about the Twilio SMS Plugin, what it does, and how to use it in Medusa.
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to set up the Medusa Admin repository for local development and customization. This includes cloning the GitHub repository and adding an upstream repository.'
addHowToData: true
---
# Customize Medusa Admin # Customize Medusa Admin
In this document, you’ll learn how to customize the Medusa admin by forking it, and how to keep it updated with changes from the main repository. In this document, you’ll learn how to customize the Medusa admin by forking it, and how to keep it updated with changes from the main repository.
+5
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to install the Medusa admin. The Medusa admin gives merchants an easy-to-use interface to manage their data such as orders, products, regions, and more.'
addHowToData: true
---
import Feedback from '@site/src/components/Feedback'; import Feedback from '@site/src/components/Feedback';
# Medusa Admin Quickstart # Medusa Admin Quickstart
+113 -9
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to bulk-import prices into Medusa using the Admin REST APIs. The steps include uploading a CSV file, creating a batch job for the import, and confirming the batch job.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -40,10 +45,16 @@ You must have a CSV file that you will use to import prices into your Medusa ser
### JS Client ### 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. This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
### Authenticated Admin User ### Authenticated Admin User
You must be an authenticated admin user before following along with the steps in the tutorial. You must be an authenticated admin user before following along with the steps in the tutorial.
@@ -67,17 +78,37 @@ You can do that by sending the following request to the [Upload Files](https://d
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.uploads.create(file) // file is an instance of File medusa.admin.uploads.create(file) // file is an instance of File
.then(({ uploads }) => { .then(({ uploads }) => {
const key = uploads[0].key const key = uploads[0].key
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminUploadFile } from "medusa-react"
const ImportPrices = () => {
const uploadFile = useAdminUploadFile()
// ...
const handleFileUpload = (file: File) => {
uploadFile.mutate(file)
}
// ...
}
export default ImportPrices
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
const formData = new FormData() const formData = new FormData()
formData.append("files", file) // file is an instance of File formData.append("files", file) // file is an instance of File
@@ -121,7 +152,7 @@ You can do that by sending the following request to the [Create a Batch Job](htt
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.batchJobs.create({ medusa.admin.batchJobs.create({
type: "price-list-import", type: "price-list-import",
context: { context: {
@@ -135,10 +166,36 @@ medusa.admin.batchJobs.create({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminCreateBatchJob } from "medusa-react"
const ImportPrices = () => {
const createBatchJob = useAdminCreateBatchJob()
// ...
const handleCreateBatchJob = () => {
createBatchJob.mutate({
type: "price-list-import",
context: {
fileKey: key, // obtained from previous step
},
dry_run: true,
})
}
// ...
}
export default ImportPrices
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<YOUR_SERVER>/admin/batch-jobs`, { fetch(`<YOUR_SERVER>/admin/batch-jobs`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -209,17 +266,44 @@ You can retrieve all the details of the batch job, including its status and the
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.batchJobs.retrieve(batchJobId) medusa.admin.batchJobs.retrieve(batchJobId)
.then(( batch_job ) => { .then(( batch_job ) => {
console.log(batch_job.status, batch_job.result) console.log(batch_job.status, batch_job.result)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminBatchJob } from "medusa-react"
const ImportPrices = () => {
const { batch_job, isLoading } = useAdminBatchJob(batchJobId)
// ...
return (
<div>
{/* ... */}
{isLoading && <span>Loading</span>}
{batch_job && (
<span>
Status: {batch_job.status}.
Number of Prices: {batch_job.result.count}
</span>
)}
</div>
)
}
export default ImportPrices
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}`, { fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}`, {
credentials: "include", credentials: "include",
}) })
@@ -272,17 +356,37 @@ To confirm a batch job send the following request:
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.batchJobs.confirm(batchJobId) medusa.admin.batchJobs.confirm(batchJobId)
.then(( batch_job ) => { .then(( batch_job ) => {
console.log(batch_job.status) console.log(batch_job.status)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminConfirmBatchJob } from "medusa-react"
const ImportPrices = () => {
const confirmBatchJob = useAdminConfirmBatchJob(batchJobId)
// ...
const handleConfirmJob = () => {
confirmBatchJob.mutate()
}
// ...
}
export default ImportPrices
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}/confirm`, { fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}/confirm`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
+113 -9
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to import products into Medusa using the Admin REST APIs. The steps include uploading a CSV file, creating a batch job for the import, and confirming the batch job.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -40,10 +45,16 @@ If you have Sales Channels enabled on your server, you must use [this CSV exampl
### JS Client ### 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. This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
### Authenticated Admin User ### Authenticated Admin User
You must be an authenticated admin user before following along with the steps in the tutorial. You must be an authenticated admin user before following along with the steps in the tutorial.
@@ -61,17 +72,37 @@ You can do that by sending the following request to the [Upload Files](https://d
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.uploads.create(file) // file is an instance of File medusa.admin.uploads.create(file) // file is an instance of File
.then(({ uploads }) => { .then(({ uploads }) => {
const key = uploads[0].key const key = uploads[0].key
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminUploadFile } from "medusa-react"
const ImportProducts = () => {
const uploadFile = useAdminUploadFile()
// ...
const handleFileUpload = (file: File) => {
uploadFile.mutate(file)
}
// ...
}
export default ImportProducts
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
const formData = new FormData() const formData = new FormData()
formData.append("files", file) // file is an instance of File formData.append("files", file) // file is an instance of File
@@ -115,7 +146,7 @@ You can do that by sending the following request to the [Create a Batch Job](htt
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.batchJobs.create({ medusa.admin.batchJobs.create({
type: "product-import", type: "product-import",
context: { context: {
@@ -128,10 +159,36 @@ medusa.admin.batchJobs.create({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminCreateBatchJob } from "medusa-react"
const ImportProducts = () => {
const createBatchJob = useAdminCreateBatchJob()
// ...
const handleCreateBatchJob = () => {
createBatchJob.mutate({
type: "product-import",
context: {
fileKey: key, // obtained from previous step
},
dry_run: true,
})
}
// ...
}
export default ImportProducts
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<YOUR_SERVER>/admin/batch-jobs`, { fetch(`<YOUR_SERVER>/admin/batch-jobs`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -197,17 +254,44 @@ You can retrieve all the details of the batch job, including its status and the
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.batchJobs.retrieve(batchJobId) medusa.admin.batchJobs.retrieve(batchJobId)
.then(( batch_job ) => { .then(( batch_job ) => {
console.log(batch_job.status, batch_job.result) console.log(batch_job.status, batch_job.result)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminBatchJob } from "medusa-react"
const ImportProducts = () => {
const { batch_job, isLoading } = useAdminBatchJob(batchJobId)
// ...
return (
<div>
{/* ... */}
{isLoading && <span>Loading</span>}
{batch_job && (
<span>
Status: {batch_job.status}.
Number of Products: {batch_job.result.count}
</span>
)}
</div>
)
}
export default ImportProducts
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}`, { fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}`, {
credentials: "include", credentials: "include",
}) })
@@ -260,17 +344,37 @@ To confirm a batch job send the following request:
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.batchJobs.confirm(batchJobId) medusa.admin.batchJobs.confirm(batchJobId)
.then(( batch_job ) => { .then(( batch_job ) => {
console.log(batch_job.status) console.log(batch_job.status)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminConfirmBatchJob } from "medusa-react"
const ImportProducts = () => {
const confirmBatchJob = useAdminConfirmBatchJob(batchJobId)
// ...
const handleConfirmJob = () => {
confirmBatchJob.mutate()
}
// ...
}
export default ImportProducts
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}/confirm`, { fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}/confirm`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -1,3 +1,8 @@
---
description: 'Learn how to implement customer-related functionalities for admins using the REST APIs. This includes how to list customers, add a new customer and edit the details of a customer.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -31,6 +36,12 @@ This guide includes code snippets to send requests to your Medusa server using M
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
### Authenticated Admin User ### Authenticated Admin User
You must be an authenticated admin user before following along with the steps in the tutorial. You must be an authenticated admin user before following along with the steps in the tutorial.
@@ -53,6 +64,34 @@ medusa.admin.customers.list()
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { Customer } from "@medusajs/medusa"
import { useAdminCustomers } from "medusa-react"
const Customers = () => {
const { customers, isLoading } = useAdminCustomers()
return (
<div>
{isLoading && <span>Loading...</span>}
{customers && !customers.length && <span>No customers</span>}
{customers && customers.length > 0 && (
<ul>
{customers.map((customer: Customer) => (
<li key={customer.id}>{customer.first_name}</li>
))}
</ul>
)}
</div>
)
}
export default Customers
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -115,6 +154,38 @@ medusa.admin.customers.create({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminCreateCustomer } from "medusa-react"
const CreateCustomer = () => {
const createCustomer = useAdminCreateCustomer()
// ...
const handleCreate = () => {
// ...
createCustomer.mutate({
first_name,
last_name,
email,
password,
})
}
// ...
return (
<form>
{/* Render form */}
</form>
)
}
export default CreateCustomer
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -187,6 +258,38 @@ medusa.admin.customers.update(customerId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminUpdateCustomer } from "medusa-react"
const UpdateCustomer = () => {
const updateCustomer = useAdminUpdateCustomer(customerId)
// ...
const handleUpdate = () => {
// ...
updateCustomer.mutate({
email,
password,
first_name,
last_name,
})
}
// ...
return (
<form>
{/* Render form */}
</form>
)
}
export default UpdateCustomer
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
+221 -20
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to implement discount functionalities for admins in Medusa using the REST APIs. This includes creating, updating, and deleting discounts, and managing conditions of discounts.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -43,6 +48,12 @@ This guide includes code snippets to send requests to your Medusa server using M
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
### Authenticated Admin User ### Authenticated Admin User
You must be an authenticated admin user before following along with the steps in the tutorial. You must be an authenticated admin user before following along with the steps in the tutorial.
@@ -58,7 +69,7 @@ You can create a discount by sending a request to the [Create Discount](/api/adm
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
import { AllocationType, DiscountRuleType } from "@medusajs/medusa" import { AllocationType, DiscountRuleType } from "@medusajs/medusa"
// ... // ...
medusa.admin.discounts.create({ medusa.admin.discounts.create({
@@ -69,18 +80,54 @@ medusa.admin.discounts.create({
allocation: AllocationType.ITEM, allocation: AllocationType.ITEM,
}, },
regions: [ regions: [
regionId, regionId,
], ],
is_dynamic: false,
is_disabled: false,
}) })
.then(({ discount }) => { .then(({ discount }) => {
console.log(discount.id) console.log(discount.id)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminCreateDiscount } from "medusa-react"
import { AllocationType, DiscountRuleType } from "@medusajs/medusa"
const CreateDiscount = () => {
const createDiscount = useAdminCreateDiscount()
// ...
const handleCreate = () => {
// ...
createDiscount.mutate({
code,
rule: {
type: DiscountRuleType.FIXED,
value: 10,
allocation: AllocationType.ITEM,
},
regions: [
regionId,
],
is_dynamic: false,
is_disabled: false,
})
}
// ...
}
export default CreateDiscount
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<YOUR_SERVER>/admin/discounts`, { fetch(`<YOUR_SERVER>/admin/discounts`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -97,6 +144,8 @@ fetch(`<YOUR_SERVER>/admin/discounts`, {
regions: [ regions: [
regionId, regionId,
], ],
is_dynamic: false,
is_disabled: false,
}), }),
}) })
.then((response) => response.json()) .then((response) => response.json())
@@ -121,7 +170,9 @@ curl -L -X POST '<YOUR_SERVER>/admin/discounts' \
}, },
"regions": [ "regions": [
"<REGION_ID>" "<REGION_ID>"
] ],
"is_dynamic": false,
"is_disabled": false
}' }'
``` ```
@@ -150,9 +201,8 @@ For example, you can update the discount’s description and status by sending t
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.discounts.update(discountId, { medusa.admin.discounts.update(discountId, {
description: "New description",
is_disabled: true, is_disabled: true,
}) })
.then(({ discount }) => { .then(({ discount }) => {
@@ -160,10 +210,33 @@ medusa.admin.discounts.update(discountId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminUpdateDiscount } from "medusa-react"
const UpdateDiscount = () => {
const updateDiscount = useAdminUpdateDiscount(discount_id)
// ...
const handleUpdate = () => {
// ...
updateDiscount.mutate({
is_disabled: true,
})
}
// ...
}
export default UpdateDiscount
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<YOUR_SERVER>/admin/discounts/${discountId}`, { fetch(`<YOUR_SERVER>/admin/discounts/${discountId}`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -171,7 +244,6 @@ fetch(`<YOUR_SERVER>/admin/discounts/${discountId}`, {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
body: JSON.stringify({ body: JSON.stringify({
description: "New description",
is_disabled: true, is_disabled: true,
}), }),
}) })
@@ -189,7 +261,6 @@ curl -L -X POST '<YOUR_SERVER>/admin/discounts/<DISCOUNT_ID>' \
-H 'Authorization: Bearer <API_TOKEN>' \ -H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
--data-raw '{ --data-raw '{
"description": "New description",
"is_disabled": true "is_disabled": true
}' }'
``` ```
@@ -197,7 +268,7 @@ curl -L -X POST '<YOUR_SERVER>/admin/discounts/<DISCOUNT_ID>' \
</TabItem> </TabItem>
</Tabs> </Tabs>
This request accepts the discount ID as a path parameter. You can pass the parameters you want to update in the request body. In the example above, you pass the `description` and `is_disabled` parameters to update them. This request accepts the discount ID as a path parameter. You can pass the parameters you want to update in the request body. In the example above, is_disabled` parameter to update it.
You can check the [API reference](/api/admin/#tag/Discount/operation/PostDiscountsDiscount) for all the accepted parameters to update the discount. You can check the [API reference](/api/admin/#tag/Discount/operation/PostDiscountsDiscount) for all the accepted parameters to update the discount.
@@ -220,7 +291,7 @@ You can send a request to the [Create Condition](/api/admin/#tag/Discount-Condit
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
import { DiscountConditionOperator } from "@medusajs/medusa" import { DiscountConditionOperator } from "@medusajs/medusa"
// ... // ...
medusa.admin.discounts.createCondition(discount_id, { medusa.admin.discounts.createCondition(discount_id, {
@@ -234,10 +305,40 @@ medusa.admin.discounts.createCondition(discount_id, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDiscountCreateCondition } from "medusa-react"
import { DiscountConditionOperator } from "@medusajs/medusa"
const Discount = () => {
const createCondition = useAdminDiscountCreateCondition(discount_id)
// ...
const handleCreateCondition = (
operator: DiscountConditionOperator,
productId: string
) => {
// ...
createCondition.mutate({
operator,
products: [
productId,
],
})
}
// ...
}
export default Discount
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<YOUR_SERVER>/admin/discounts/${discountId}/conditions`, { fetch(`<YOUR_SERVER>/admin/discounts/${discountId}/conditions`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -299,7 +400,7 @@ You can retrieve a condition and its resources by sending a request to the [Get
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.discounts.getCondition(discountId, conditionId, { medusa.admin.discounts.getCondition(discountId, conditionId, {
expand: "products", expand: "products",
}) })
@@ -308,10 +409,44 @@ medusa.admin.discounts.getCondition(discountId, conditionId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminGetDiscountCondition } from "medusa-react"
import { Product } from "@medusajs/medusa"
const DiscountCondition = () => {
const { discount_condition, isLoading } = useAdminGetDiscountCondition(
discount_id,
conditionId
)
// ...
return (
<div>
{isLoading && <span>Loading</span>}
{discount_condition && (
<>
<span>{discount_condition.id}</span>
<ul>
{discount_condition.products.map((product: Product) => (
<li key={product.id}>{product.title}</li>
))}
</ul>
</>
)}
</div>
)
}
export default DiscountCondition
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch( fetch(
`<YOUR_SERVER>/admin/discounts/${discountId}` + `<YOUR_SERVER>/admin/discounts/${discountId}` +
`/conditions/${conditionId}&expand=products`, `/conditions/${conditionId}&expand=products`,
@@ -351,7 +486,7 @@ For example, to update the products in a condition:
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.discounts.updateCondition(discountId, conditionId, { medusa.admin.discounts.updateCondition(discountId, conditionId, {
products: [ products: [
productId1, productId1,
@@ -363,10 +498,36 @@ medusa.admin.discounts.updateCondition(discountId, conditionId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDiscountUpdateCondition } from "medusa-react"
import { Product } from "@medusajs/medusa"
const DiscountCondition = () => {
const updateCondition = useAdminDiscountUpdateCondition(
discount_id,
conditionId
)
// ...
const handleUpdateCondition = (productIds: string[]) => {
updateCondition.mutate({
products: productIds,
})
}
// ...
}
export default DiscountCondition
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch( fetch(
`<YOUR_SERVER>/admin/discounts/${discountId}/conditions/${conditionId}`, `<YOUR_SERVER>/admin/discounts/${discountId}/conditions/${conditionId}`,
{ {
@@ -420,17 +581,37 @@ You can delete a condition by sending a request to the [Delete Condition](/api/a
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.discounts.deleteCondition(discountId, conditionId) medusa.admin.discounts.deleteCondition(discountId, conditionId)
.then(({ discount }) => { .then(({ discount }) => {
console.log(discount) console.log(discount)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDiscountRemoveCondition } from "medusa-react"
const Discount = () => {
const deleteCondition = useAdminDiscountRemoveCondition(discount_id)
// ...
const handleUpdateCondition = (conditionId: string) => {
deleteCondition.mutate(conditionId)
}
// ...
}
export default Discount
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch( fetch(
`<YOUR_SERVER>/admin/discounts/${discountId}/conditions/${conditionId}`, `<YOUR_SERVER>/admin/discounts/${discountId}/conditions/${conditionId}`,
{ {
@@ -468,17 +649,37 @@ You can delete a discount by sending a request to the [Delete Discount](/api/adm
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.discounts.delete(discount_id) medusa.admin.discounts.delete(discount_id)
.then(({ id, object, deleted }) => { .then(({ id, object, deleted }) => {
console.log(id) console.log(id)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDeleteDiscount } from "medusa-react"
const Discount = () => {
const deleteDiscount = useAdminDeleteDiscount(discount_id)
// ...
const handleDelete = () => {
deleteDiscount.mutate()
}
// ...
}
export default Discount
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<YOUR_SERVER>/admin/discounts/${discountId}`, { fetch(`<YOUR_SERVER>/admin/discounts/${discountId}`, {
method: "DELETE", method: "DELETE",
credentials: "include", credentials: "include",
@@ -1,3 +1,8 @@
---
description: 'Learn how to implement gift card functionalities for admins using the REST APIs. This includes how to create, update, and delete gift cards, as well as custom gift cards.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -32,10 +37,16 @@ It is assumed that you already have a Medusa server installed and set up. If not
### JS Client ### 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. This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
### Authenticated Admin User ### Authenticated Admin User
You must be an authenticated admin user before following along with the steps in the tutorial. You must be an authenticated admin user before following along with the steps in the tutorial.
@@ -71,6 +82,37 @@ medusa.admin.products.list({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { Product } from "@medusajs/medusa"
import { PricedProduct } from "@medusajs/medusa/dist/types/pricing"
import { useAdminProducts } from "medusa-react"
const GiftCard = () => {
const { products, isLoading } = useAdminProducts({
is_giftcard: true,
})
return (
<div>
{isLoading && <span>Loading...</span>}
{products && products.length > 0 && (
<ul>
{products.map((product: (Product | PricedProduct)) => (
<li key={product.id}>{product.title}</li>
))}
</ul>
)}
{products && !products.length && <span>No Gift Cards</span>}
</div>
)
}
export default GiftCard
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -149,6 +191,55 @@ medusa.admin.products.create({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminCreateProduct } from "medusa-react"
import { ProductStatus } from "@medusajs/medusa"
const CreateGiftCard = () => {
const createGiftCard = useAdminCreateProduct()
// ...
const handleCreate = () => {
createGiftCard.mutate({
title: "My Gift Card",
is_giftcard: true,
discountable: false,
status: ProductStatus.PUBLISHED,
options: [
{
title: "Denomination",
},
],
variants: [
{
title: "1",
inventory_quantity: 0,
manage_inventory: false,
prices: [
{
amount: 2000,
currency_code: "usd",
},
],
options: [
{
value: "2000",
},
],
},
],
})
}
// ...
}
export default CreateGiftCard
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -266,6 +357,28 @@ medusa.admin.products.update(giftCardId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminUpdateProduct } from "medusa-react"
const UpdateGiftCard = () => {
const createGiftCard = useAdminUpdateProduct(giftCardId)
// ...
const handleUpdate = () => {
createGiftCard.mutate({
description: "The best gift card",
})
}
// ...
}
export default UpdateGiftCard
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -321,6 +434,26 @@ medusa.admin.products.delete(giftCardId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDeleteProduct } from "medusa-react"
const GiftCard = () => {
const deleteGiftCard = useAdminDeleteProduct(giftCardId)
// ...
const handleDelete = () => {
deleteGiftCard.mutate()
}
// ...
}
export default GiftCard
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -374,6 +507,36 @@ medusa.admin.giftCards.list()
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { GiftCard } from "@medusajs/medusa"
import { useAdminGiftCards } from "medusa-react"
const CustomGiftCards = () => {
const { gift_cards, isLoading } = useAdminGiftCards()
return (
<div>
{isLoading && <span>Loading...</span>}
{gift_cards && !gift_cards.length && (
<span>No custom gift cards...</span>
)}
{gift_cards && gift_cards.length > 0 && (
<ul>
{gift_cards.map((giftCard: GiftCard) => (
<li key={giftCard.id}>{giftCard.code}</li>
))}
</ul>
)}
</div>
)
}
export default CustomGiftCards
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -421,6 +584,29 @@ medusa.admin.giftCards.create({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminCreateGiftCard } from "medusa-react"
const CreateCustomGiftCards = () => {
const createGiftCard = useAdminCreateGiftCard()
// ...
const handleCreate = (regionId: string, value: number) => {
createGiftCard.mutate({
region_id: regionId,
value,
})
}
// ...
}
export default CreateCustomGiftCards
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -482,6 +668,28 @@ medusa.admin.giftCards.update(giftCardId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminUpdateGiftCard } from "medusa-react"
const UpdateCustomGiftCards = () => {
const updateGiftCard = useAdminUpdateGiftCard(customGiftCardId)
// ...
const handleUpdate = (regionId: string) => {
updateGiftCard.mutate({
region_id: regionId,
})
}
// ...
}
export default UpdateCustomGiftCards
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -537,6 +745,26 @@ medusa.admin.giftCards.delete(giftCardId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDeleteGiftCard } from "medusa-react"
const CustomGiftCard = () => {
const deleteGiftCard = useAdminDeleteGiftCard(customGiftCardId)
// ...
const handleDelete = () => {
deleteGiftCard.mutate()
}
// ...
}
export default CustomGiftCard
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -1,7 +1,12 @@
---
description: 'Learn how to implement publishable API key functionalities for admins in Medusa using the REST APIs. This includes how to list, create, update, and delete a publishable API key.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
# Manage Publishable API Keys # How to Manage Publishable API Keys
In this document, you’ll learn how to manage the publishable API keys using the admin APIs. In this document, you’ll learn how to manage the publishable API keys using the admin APIs.
@@ -36,10 +41,16 @@ It is assumed that you already have a Medusa server installed and set up. If not
### JS Client ### 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. This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
### Authenticated Admin User ### Authenticated Admin User
You must be an authenticated admin user before following along with the steps in the tutorial. You must be an authenticated admin user before following along with the steps in the tutorial.
@@ -62,6 +73,38 @@ medusa.admin.publishableApiKeys.list()
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { PublishableApiKey } from "@medusajs/medusa"
import { useAdminPublishableApiKeys } from "medusa-react"
const PublishabelApiKeys = () => {
const { publishable_api_keys, isLoading } = useAdminPublishableApiKeys()
return (
<div>
{isLoading && <span>Loading...</span>}
{publishable_api_keys && !publishable_api_keys.length && (
<span>No Publishable API Keys</span>
)}
{publishable_api_keys && publishable_api_keys.length > 0 && (
<ul>
{publishable_api_keys.map(
(publishableApiKey: PublishableApiKey) => (
<li key={publishableApiKey.id}>{publishableApiKey.title}</li>
)
)}
</ul>
)}
</div>
)
}
export default PublishabelApiKeys
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -119,6 +162,28 @@ medusa.admin.publishableApiKeys.create({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminCreatePublishableApiKey } from "medusa-react"
const CreatePublishableApiKey = () => {
const createKey = useAdminCreatePublishableApiKey()
// ...
const handleCreate = (title: string) => {
createKey.mutate({
title,
})
}
// ...
}
export default CreatePublishableApiKey
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -176,6 +241,28 @@ medusa.admin.publishableApiKeys.update(publishableApiKeyId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminUpdatePublishableApiKey } from "medusa-react"
const UpdatePublishableApiKey = () => {
const updateKey = useAdminUpdatePublishableApiKey(publishableApiKeyId)
// ...
const handleUpdate = (title: string) => {
updateKey.mutate({
title,
})
}
// ...
}
export default UpdatePublishableApiKey
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -233,6 +320,26 @@ medusa.admin.publishableApiKeys.revoke(publishableApiKeyId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminRevokePublishableApiKey } from "medusa-react"
const PublishableApiKey = () => {
const revokeKey = useAdminRevokePublishableApiKey(publishableApiKeyId)
// ...
const handleRevoke = () => {
revokeKey.mutate()
}
// ...
}
export default PublishableApiKey
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -279,6 +386,26 @@ medusa.admin.publishableApiKeys.delete(publishableApiKeyId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDeletePublishableApiKey } from "medusa-react"
const PublishableApiKey = () => {
const deleteKey = useAdminDeletePublishableApiKey(publishableApiKeyId)
// ...
const handleDelete = () => {
deleteKey.mutate()
}
// ...
}
export default PublishableApiKey
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -332,6 +459,39 @@ medusa.admin.publishableApiKeys.listSalesChannels(publishableApiKeyId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { SalesChannel } from "@medusajs/medusa"
import { useAdminPublishableApiKeySalesChannels } from "medusa-react"
const SalesChannels = () => {
const { sales_channels, isLoading } =
useAdminPublishableApiKeySalesChannels(
publishableApiKeyId
)
return (
<div>
{isLoading && <span>Loading...</span>}
{sales_channels && !sales_channels.length && (
<span>No Sales Channels</span>
)}
{sales_channels && sales_channels.length > 0 && (
<ul>
{sales_channels.map((salesChannel: SalesChannel) => (
<li key={salesChannel.id}>{salesChannel.name}</li>
))}
</ul>
)}
</div>
)
}
export default SalesChannels
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -388,6 +548,34 @@ medusa.admin.publishableApiKeys.addSalesChannelsBatch(
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminAddPublishableKeySalesChannelsBatch } from "medusa-react"
const PublishableApiKey = () => {
const addSalesChannels = useAdminAddPublishableKeySalesChannelsBatch(
publishableApiKeyId
)
// ...
const handleAdd = (salesChannelId: string) => {
addSalesChannels.mutate({
sales_channel_ids: [
{
id: salesChannelId,
},
],
})
}
// ...
}
export default PublishableApiKey
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -467,6 +655,37 @@ medusa.admin.publishableApiKeys.deleteSalesChannelsBatch(
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import {
useAdminRemovePublishableKeySalesChannelsBatch,
} from "medusa-react"
const PublishableApiKey = () => {
const deleteSalesChannels =
useAdminRemovePublishableKeySalesChannelsBatch(
publishableApiKeyId
)
// ...
const handleDelete = (salesChannelId: string) => {
deleteSalesChannels.mutate({
sales_channel_ids: [
{
id: salesChannelId,
},
],
})
}
// ...
}
export default PublishableApiKey
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
+156 -11
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to implement region-related functionalities for admins using the REST APIs. This includes how to list regions, and create, update, and delete regions.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -35,10 +40,16 @@ It is assumed that you already have a Medusa server installed and set up. If not
### JS Client ### 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. This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
### Authenticated Admin User ### Authenticated Admin User
You must be an authenticated admin user before following along with the steps in the tutorial. You must be an authenticated admin user before following along with the steps in the tutorial.
@@ -54,7 +65,7 @@ You can retrieve regions available on your server using the [List Regions](/api/
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```tsx ```ts
medusa.admin.regions.list() medusa.admin.regions.list()
.then(({ regions, limit, offset, count }) => { .then(({ regions, limit, offset, count }) => {
console.log(regions.length) console.log(regions.length)
@@ -63,9 +74,37 @@ medusa.admin.regions.list()
``` ```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="medusa-react" label="Medusa React">
```tsx ```tsx
import { Region } from "@medusajs/medusa"
import { useAdminRegions } from "medusa-react"
const Regions = () => {
const { regions, isLoading } = useAdminRegions()
return (
<div>
{isLoading && <span>Loading...</span>}
{regions && !regions.length && <span>No Regions</span>}
{regions && regions.length > 0 && (
<ul>
{regions.map((region: Region) => (
<li key={region.id}>{region.name}</li>
))}
</ul>
)}
</div>
)
}
export default Regions
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<SERVER_URL>/admin/regions`, { fetch(`<SERVER_URL>/admin/regions`, {
credentials: "include", credentials: "include",
}) })
@@ -100,7 +139,7 @@ You can create a region by sending a request to the [Create a Region](/api/admin
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```tsx ```ts
medusa.admin.regions.create({ medusa.admin.regions.create({
name: "Europe", name: "Europe",
currency_code: "eur", currency_code: "eur",
@@ -121,9 +160,42 @@ medusa.admin.regions.create({
``` ```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="medusa-react" label="Medusa React">
```tsx ```tsx
import { useAdminCreateRegion } from "medusa-react"
const CreateRegion = () => {
const createRegion = useAdminCreateRegion()
// ...
const handleCreate = () => {
createRegion.mutate({
name: "Europe",
currency_code: "eur",
tax_rate: 0,
payment_providers: [
"manual",
],
fulfillment_providers: [
"manual",
],
countries: [
"DK",
],
})
}
// ...
}
export default CreateRegion
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<SERVER_URL>/admin/regions`, { fetch(`<SERVER_URL>/admin/regions`, {
credentials: "include", credentials: "include",
method: "POST", method: "POST",
@@ -198,7 +270,7 @@ Alternatively, you can update the details of a region using the [Update a Region
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```tsx ```ts
medusa.admin.regions.update(regionId, { medusa.admin.regions.update(regionId, {
countries: [ countries: [
"DK", "DK",
@@ -211,9 +283,34 @@ medusa.admin.regions.update(regionId, {
``` ```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="medusa-react" label="Medusa React">
```tsx ```tsx
import { useAdminUpdateRegion } from "medusa-react"
const UpdateRegion = () => {
const updateRegion = useAdminUpdateRegion(regionId)
// ...
const handleUpdate = () => {
updateRegion.mutate({
countries: [
"DK",
"DE",
],
})
}
// ...
}
export default UpdateRegion
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<SERVER_URL>/admin/regions/${regionId}`, { fetch(`<SERVER_URL>/admin/regions/${regionId}`, {
credentials: "include", credentials: "include",
method: "POST", method: "POST",
@@ -269,7 +366,7 @@ You can add a shipping option to a region by sending a request to the [Create Sh
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```tsx ```ts
medusa.admin.shippingOptions.create({ medusa.admin.shippingOptions.create({
name: "PostFake", name: "PostFake",
region_id: regionId, region_id: regionId,
@@ -285,9 +382,37 @@ medusa.admin.shippingOptions.create({
``` ```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="medusa-react" label="Medusa React">
```tsx ```tsx
import { useAdminCreateShippingOption } from "medusa-react"
const Region = () => {
const createShippingOption = useAdminCreateShippingOption()
// ...
const handleCreate = () => {
createShippingOption.mutate({
name: "PostFake",
region_id: regionId,
provider_id: "manual",
data: {
},
price_type: "flat_rate",
amount: 1000,
})
}
// ...
}
export default Region
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<SERVER_URL>/admin/shipping-options`, { fetch(`<SERVER_URL>/admin/shipping-options`, {
credentials: "include", credentials: "include",
method: "POST", method: "POST",
@@ -357,7 +482,7 @@ You can delete a region by sending a request to the [Delete a Region](/api/admin
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```tsx ```ts
medusa.admin.regions.delete(regionId) medusa.admin.regions.delete(regionId)
.then(({ id, object, deleted }) => { .then(({ id, object, deleted }) => {
console.log(id) console.log(id)
@@ -365,9 +490,29 @@ medusa.admin.regions.delete(regionId)
``` ```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="medusa-react" label="Medusa React">
```tsx ```tsx
import { useAdminDeleteRegion } from "medusa-react"
const Region = () => {
const deleteRegion = useAdminDeleteRegion(regionId)
// ...
const handleDelete = () => {
deleteRegion.mutate()
}
// ...
}
export default Region
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<SERVER_URL>/admin/regions/${regionId}`, { fetch(`<SERVER_URL>/admin/regions/${regionId}`, {
credentials: "include", credentials: "include",
method: "DELETE", method: "DELETE",
+221 -2
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to implement order-editing features for admins using the REST APIs. This guide includes how to create an order edit and move order edit to request state, and more.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -49,10 +54,16 @@ It is assumed that you already have a Medusa server installed and set up. If not
### JS Client ### 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. This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
### Authenticated Admin User ### Authenticated Admin User
You must be an authenticated admin user before following along with the steps in the tutorial. You must be an authenticated admin user before following along with the steps in the tutorial.
@@ -83,6 +94,27 @@ medusa.admin.orderEdits.create({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminCreateOrderEdit } from "medusa-react"
const OrderEdit = () => {
const createOrderEdit = useAdminCreateOrderEdit()
const handleCreateOrderEdit = (orderId: string) => {
createOrderEdit.mutate({
order_id: orderId,
})
}
// ...
}
export default OrderEdit
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -157,6 +189,28 @@ medusa.admin.orderEdits.addLineItem(orderEditId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminOrderEditAddLineItem } from "medusa-react"
const OrderEdit = () => {
const addLineItem = useAdminOrderEditAddLineItem(orderEditId)
const handleAddLineItem = (quantity: number, variantId: string) => {
addLineItem.mutate({
quantity,
variant_id: variantId,
})
}
// ...
}
export default OrderEdit
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -218,6 +272,30 @@ medusa.admin.orderEdits.updateLineItem(orderEditId, itemId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminOrderEditUpdateLineItem } from "medusa-react"
const OrderEdit = () => {
const updateLineItem = useAdminOrderEditUpdateLineItem(
orderEditId,
itemId
)
const handleUpdateLineItem = (quantity: number) => {
updateLineItem.mutate({
quantity,
})
}
// ...
}
export default OrderEdit
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -273,6 +351,28 @@ medusa.admin.orderEdits.removeLineItem(orderEditId, itemId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminOrderEditDeleteLineItem } from "medusa-react"
const OrderEdit = () => {
const removeLineItem = useAdminOrderEditDeleteLineItem(
orderEditId,
itemId
)
const handleRemoveLineItem = () => {
removeLineItem.mutate()
}
// ...
}
export default OrderEdit
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -320,6 +420,28 @@ medusa.admin.orderEdits.deleteItemChange(orderEditId, changeId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDeleteOrderEditItemChange } from "medusa-react"
const OrderEdit = () => {
const deleteItemChange = useAdminDeleteOrderEditItemChange(
orderEditId,
itemChangeId
)
const handleDeleteItemChange = () => {
deleteItemChange.mutate()
}
// ...
}
export default OrderEdit
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -374,6 +496,28 @@ medusa.admin.orderEdits.requestConfirmation(orderEditId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminRequestOrderEditConfirmation } from "medusa-react"
const OrderEdit = () => {
const requestOrderConfirmation =
useAdminRequestOrderEditConfirmation(
orderEditId
)
const handleRequestConfirmation = () => {
requestOrderConfirmation.mutate()
}
// ...
}
export default OrderEdit
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -441,6 +585,25 @@ medusa.admin.orderEdits.confirm(orderEditId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminConfirmOrderEdit } from "medusa-react"
const OrderEdit = () => {
const confirmOrderEdit = useAdminConfirmOrderEdit(orderEditId)
const handleConfirmOrderEdit = () => {
confirmOrderEdit.mutate()
}
// ...
}
export default OrderEdit
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -503,6 +666,25 @@ medusa.admin.payments.capturePayment(paymentId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminPaymentsCapturePayment } from "medusa-react"
const OrderEditPayment = () => {
const capturePayment = useAdminPaymentsCapturePayment(paymentId)
const handleCapturePayment = () => {
capturePayment.mutate()
}
// ...
}
export default OrderEditPayment
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -542,14 +724,41 @@ To refund the difference to the customer, send a request to the [Refund Payment]
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```ts ```ts
import { RefundReason } from "@medusajs/medusa"
// ...
medusa.admin.payments.refundPayment(paymentId, { medusa.admin.payments.refundPayment(paymentId, {
amount, amount,
reason: RefundReason.DISCOUNT, // for example
}) })
.then(({ refund }) => { .then(({ refund }) => {
console.log(refund.id) console.log(refund.id)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminPaymentsRefundPayment } from "medusa-react"
import { RefundReason } from "@medusajs/medusa"
const OrderEditPayment = () => {
const refundPayment = useAdminPaymentsRefundPayment(paymentId)
const handleRefundPayment = (amount: number, reason: RefundReason) => {
refundPayment.mutate({
amount,
reason,
})
}
// ...
}
export default OrderEditPayment
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -562,6 +771,7 @@ fetch(`<YOUR_SERVER>/admin/payments/${paymentId}/refund`, {
}, },
body: JSON.stringify({ body: JSON.stringify({
amount, amount,
reason: "discount",
}), }),
}) })
.then((response) => response.json()) .then((response) => response.json())
@@ -578,7 +788,8 @@ curl -L -X POST '<SERVER_URL>/admin/payments/<PAYMENT_ID>/refund' \
-H 'Authorization: Bearer <API_TOKEN>' \ -H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
--data-raw '{ --data-raw '{
"amount": 1000 "amount": 1000,
"reason": "discount"
}' }'
``` ```
@@ -589,6 +800,14 @@ This request requires the ID of the payment as a path parameter. The payment can
In the request’s body parameters, the `amount` field parameter is required. It is the amount to be refunded. In the request’s body parameters, the `amount` field parameter is required. It is the amount to be refunded.
The `reason` request body parameter is also required. Its value is a string that can be one of the following:
- `discount`
- `return`
- `swap`
- `claim`
- `other`
:::note :::note
Check out what other parameters can be sent in the [API reference](/api/admin/#tag/Payment/operation/PostPaymentsPaymentRefunds). Check out what other parameters can be sent in the [API reference](/api/admin/#tag/Payment/operation/PostPaymentsPaymentRefunds).
@@ -1,3 +1,8 @@
---
description: 'Learn how to implement customer group functionalities for admins using the REST APIs. This includes listing customer groups, creating a customer group, managing customers in the group, and more.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -23,10 +28,16 @@ It is assumed that you already have a Medusa server installed and set up. If not
### JS Client ### 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. This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
### Authenticated Admin User ### Authenticated Admin User
You must be an authenticated admin user before following along with the steps in the tutorial. You must be an authenticated admin user before following along with the steps in the tutorial.
@@ -42,7 +53,7 @@ You can create a customer group by sending a request to the Create Customer Grou
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.customerGroups.create({ medusa.admin.customerGroups.create({
name: "VIP", name: "VIP",
}) })
@@ -51,10 +62,38 @@ medusa.admin.customerGroups.create({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminCreateCustomerGroup } from "medusa-react"
const CreateCustomerGroup = () => {
const createCustomerGroup = useAdminCreateCustomerGroup()
// ...
const handleCreate = () => {
createCustomerGroup.mutate({
name,
})
}
// ...
return (
<form>
{/* Render form */}
</form>
)
}
export default CreateCustomerGroup
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/admin/customer-groups`, { fetch(`<SERVER_URL>/admin/customer-groups`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -97,17 +136,47 @@ You can get a list of all customer groups by sending a request to the List Custo
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.customerGroups.list() medusa.admin.customerGroups.list()
.then(({ customer_groups, limit, offset, count }) => { .then(({ customer_groups, limit, offset, count }) => {
console.log(customer_groups.length) console.log(customer_groups.length)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { CustomerGroup } from "@medusajs/medusa"
import { useAdminCustomerGroups } from "medusa-react"
const CustomerGroups = () => {
const { customer_groups, isLoading } = useAdminCustomerGroups()
return (
<div>
{isLoading && <span>Loading...</span>}
{customer_groups && !customer_groups.length && (
<span>No Customer Groups</span>
)}
{customer_groups && customer_groups.length > 0 && (
<ul>
{customer_groups.map((customerGroup: CustomerGroup) => (
<li key={customerGroup.id}>{customerGroup.name}</li>
))}
</ul>
)}
</div>
)
}
export default CustomerGroups
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/admin/customer-groups`, { fetch(`<SERVER_URL>/admin/customer-groups`, {
credentials: "include", credentials: "include",
}) })
@@ -141,17 +210,39 @@ You can retrieve a single customer group by sending a request to the Get a Custo
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.customerGroups.retrieve(customerGroupId) medusa.admin.customerGroups.retrieve(customerGroupId)
.then(({ customer_group }) => { .then(({ customer_group }) => {
console.log(customer_group.id) console.log(customer_group.id)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminCustomerGroup } from "medusa-react"
const CustomerGroup = () => {
const { customer_group, isLoading } = useAdminCustomerGroup(
customerGroupId
)
return (
<div>
{isLoading && <span>Loading...</span>}
{customer_group && <span>{customer_group.name}</span>}
</div>
)
}
export default CustomerGroup
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/admin/customer-groups/${customerGroupId}`, { fetch(`<SERVER_URL>/admin/customer-groups/${customerGroupId}`, {
credentials: "include", credentials: "include",
}) })
@@ -183,7 +274,7 @@ You can update a customer group’s data by sending a request to the Update Cust
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.customerGroups.update(customerGroupId, { medusa.admin.customerGroups.update(customerGroupId, {
metadata: { metadata: {
is_seller: true, is_seller: true,
@@ -194,10 +285,38 @@ medusa.admin.customerGroups.update(customerGroupId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminUpdateCustomerGroup } from "medusa-react"
const UpdateCustomerGroup = () => {
const updateCustomerGroup = useAdminUpdateCustomerGroup(customerGroupId)
// ..
const handleUpdate = () => {
updateCustomerGroup.mutate({
name,
})
}
// ...
return (
<form>
{/* Render form */}
</form>
)
}
export default UpdateCustomerGroup
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/admin/customer-groups/${customerGroupId}`, { fetch(`<SERVER_URL>/admin/customer-groups/${customerGroupId}`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -244,17 +363,37 @@ You can delete a customer group by sending a request to the Delete a Customer Gr
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.customerGroups.delete(customerGroupId) medusa.admin.customerGroups.delete(customerGroupId)
.then(({ id, object, deleted }) => { .then(({ id, object, deleted }) => {
console.log(id) console.log(id)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDeleteCustomerGroup } from "medusa-react"
const CustomerGroup = () => {
const deleteCustomerGroup = useAdminDeleteCustomerGroup(customerGroupId)
// ...
const handleDeleteCustomerGroup = () => {
deleteCustomerGroup.mutate()
}
// ...
}
export default CustomerGroup
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/admin/customer-groups/${customerGroupId}`, { fetch(`<SERVER_URL>/admin/customer-groups/${customerGroupId}`, {
method: "DELETE", method: "DELETE",
credentials: "include", credentials: "include",
@@ -289,7 +428,7 @@ You can add a customer to a group by sending a request to the Customer Group’s
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.customerGroups.addCustomers(customerGroupId, { medusa.admin.customerGroups.addCustomers(customerGroupId, {
customer_ids: [ customer_ids: [
{ {
@@ -302,10 +441,36 @@ medusa.admin.customerGroups.addCustomers(customerGroupId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminAddCustomersToCustomerGroup } from "medusa-react"
const CustomerGroup = () => {
const addCustomers = useAdminAddCustomersToCustomerGroup(customerGroupId)
// ...
const handleAddCustomers= (customerId: string) => {
addCustomers.mutate({
customer_ids: [
{
id: customerId,
},
],
})
}
// ...
}
export default CustomerGroup
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch( fetch(
`<SERVER_URL>/admin/customer-groups/${customerGroupId}/customers/batch`, `<SERVER_URL>/admin/customer-groups/${customerGroupId}/customers/batch`,
{ {
@@ -357,17 +522,47 @@ You can retrieve a list of all customers in a customer group using the List Cust
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.customerGroups.listCustomers(customerGroupId) medusa.admin.customerGroups.listCustomers(customerGroupId)
.then(({ customers, count, offset, limit }) => { .then(({ customers, count, offset, limit }) => {
console.log(customers.length) console.log(customers.length)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { Customer } from "@medusajs/medusa"
import { useAdminCustomerGroupCustomers } from "medusa-react"
const CustomerGroup = () => {
const { customers, isLoading } = useAdminCustomerGroupCustomers(
customerGroupId
)
return (
<div>
{isLoading && <span>Loading...</span>}
{customers && !customers.length && <span>No customers</span>}
{customers && customers.length > 0 && (
<ul>
{customers.map((customer: Customer) => (
<li key={customer.id}>{customer.first_name}</li>
))}
</ul>
)}
</div>
)
}
export default CustomerGroup
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/admin/customer-groups/${customerGroupId}/customers`, { fetch(`<SERVER_URL>/admin/customer-groups/${customerGroupId}/customers`, {
credentials: "include", credentials: "include",
}) })
@@ -403,7 +598,7 @@ You can remove customers from a customer group by sending a request to the Remov
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.customerGroups.removeCustomers(customer_group_id, { medusa.admin.customerGroups.removeCustomers(customer_group_id, {
customer_ids: [ customer_ids: [
{ {
@@ -416,10 +611,39 @@ medusa.admin.customerGroups.removeCustomers(customer_group_id, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { Customer } from "@medusajs/medusa"
import { useAdminRemoveCustomersFromCustomerGroup } from "medusa-react"
const CustomerGroup = () => {
const removeCustomers = useAdminRemoveCustomersFromCustomerGroup(
customerGroupId
)
// ...
const handleRemoveCustomer = (customer_id: string) => {
removeCustomers.mutate({
customer_ids: [
{
id: customer_id,
},
],
})
}
// ...
}
export default CustomerGroup
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch( fetch(
`<SERVER_URL>/admin/customer-groups/${customerGroupId}/customers/batch`, `<SERVER_URL>/admin/customer-groups/${customerGroupId}/customers/batch`,
{ {
@@ -1,3 +1,8 @@
---
description: 'Learn how to create a batch job strategy in the Medusa server. This guide also includes how to test your batch job strategy.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -1,4 +1,9 @@
# Customize Import Strategy ---
description: 'Learn how to customize the import strategy in Medusa. The import strategy can be used to import entities such as products, prices in a price list, orders, or other entities.'
addHowToData: true
---
# How to Customize Import Strategy
In this document, you’ll learn how to create a custom product import strategy either by overwriting the default strategy or creating your own. In this document, you’ll learn how to create a custom product import strategy either by overwriting the default strategy or creating your own.
@@ -30,7 +35,7 @@ If you use SQLite during your development, it’s highly recommended that you us
The steps required for overwriting a batch job strategy are essentially the same steps required to create a batch job strategy with a minor difference. For that reason, this documentation does not cover the basics of a batch job strategy. The steps required for overwriting a batch job strategy are essentially the same steps required to create a batch job strategy with a minor difference. For that reason, this documentation does not cover the basics of a batch job strategy.
If you’re interested to learn more about batch job strategies and how they work, please check out the [Create Batch Job Strategy documentation](./create.md). If you’re interested to learn more about batch job strategies and how they work, please check out the [Create Batch Job Strategy documentation](./create.mdx).
### 1. Create a File ### 1. Create a File
@@ -69,7 +74,7 @@ export default MyImportStrategy
:::note :::note
This is the base implementation of a batch job strategy. You can learn about all the different methods and properties in [this documentation](./create.md#3-define-required-properties). This is the base implementation of a batch job strategy. You can learn about all the different methods and properties in [this documentation](./create.mdx#3-define-required-properties).
::: :::
@@ -92,7 +97,7 @@ class MyImportStrategy extends AbstractBatchJobStrategy {
You can now define your custom functionality in your batch job strategy. For example, you can create custom import logic to import products. You can now define your custom functionality in your batch job strategy. For example, you can create custom import logic to import products.
Refer to the [Create a Batch Job documentation](./create.md#3-define-required-properties) to understand what properties and methods are required in your batch job strategy and how you can use them to implement your custom functionality. Refer to the [Create a Batch Job documentation](./create.mdx#3-define-required-properties) to understand what properties and methods are required in your batch job strategy and how you can use them to implement your custom functionality.
### 5. Run Build Command ### 5. Run Build Command
@@ -104,7 +109,7 @@ npm run build
### 6. Test your Functionality ### 6. Test your Functionality
Since you didn’t create a new batch job type and overwrote the functionality of the strategy, you can test out your functionality using the [same steps used with the default strategy](./create.md#test-your-batch-job-strategy). Since you didn’t create a new batch job type and overwrote the functionality of the strategy, you can test out your functionality using the [same steps used with the default strategy](./create.mdx#test-your-batch-job-strategy).
Specifically, since you create batch jobs using the [Create Batch Job](https://docs.medusajs.com/api/admin/#tag/Batch-Job/operation/PostBatchJobs) endpoint which accepts the batch job type as a body parameter, you just need to send the same type you used for this field. In the example of this documentation, the `type` would be `product-import`. Specifically, since you create batch jobs using the [Create Batch Job](https://docs.medusajs.com/api/admin/#tag/Batch-Job/operation/PostBatchJobs) endpoint which accepts the batch job type as a body parameter, you just need to send the same type you used for this field. In the example of this documentation, the `type` would be `product-import`.
@@ -116,7 +121,7 @@ If you overwrote the import functionality, you can follow [these steps to learn
If you don’t want to overwrite Medusa’s batch job strategy, you can create a custom batch job strategy with a different `batchType` value. Then, use that type when you send a request to [Create a Batch Job](https://docs.medusajs.com/api/admin/#tag/Batch-Job). If you don’t want to overwrite Medusa’s batch job strategy, you can create a custom batch job strategy with a different `batchType` value. Then, use that type when you send a request to [Create a Batch Job](https://docs.medusajs.com/api/admin/#tag/Batch-Job).
For more details on creating custom batch job strategies, please check out the [Create Batch Job Strategy documentation](create.md). For more details on creating custom batch job strategies, please check out the [Create Batch Job Strategy documentation](create.mdx).
--- ---
@@ -1,3 +1,7 @@
---
description: 'Learn what batch jobs in the Medusa server are and their flow. Batch jobs are tasks that can be performed asynchronously and iteratively in the Medusa server.'
---
# Batch Jobs # Batch Jobs
In this document, you’ll learn what Batch Jobs are and how they work in Medusa. In this document, you’ll learn what Batch Jobs are and how they work in Medusa.
@@ -1,3 +1,7 @@
---
description: 'Learn what Customer Groups are and how they can be used in the Medusa server. Customer Groups allow to combine customers with similar attributes into a single group.'
---
# Customer Groups # Customer Groups
In this document, you’ll learn about Customer Groups and how they can be used in Medusa. In this document, you’ll learn about Customer Groups and how they can be used in Medusa.
@@ -1,3 +1,7 @@
---
description: 'Learn about what Customers are in Medusa and how they are implemented. Customers are individuals that make purchases in your store.'
---
# Customers # Customers
In this document, you’ll learn about Customers and their relation to other entities in Medusa. In this document, you’ll learn about Customers and their relation to other entities in Medusa.
@@ -1,3 +1,7 @@
---
description: 'Learn what the dependency container is and how to use it in Medusa. Learn also what dependency injection is, and what the resources regsitered and their names are.'
---
# Dependency Container # Dependency Container
In this document, you’ll learn what the dependency container is and how you can use it in Medusa. In this document, you’ll learn what the dependency container is and how you can use it in Medusa.
@@ -1,3 +1,7 @@
---
description: 'Learn about the discount architecture in the Medusa server. Discounts are used to offer promotions to the user for marketing purposes.'
---
# Discounts Architecture # Discounts Architecture
In this document, you’ll learn about Discounts architecture and how it works. In this document, you’ll learn about Discounts architecture and how it works.
@@ -1,3 +1,8 @@
---
description: 'Learn how to add a middleware in Medusa. A middleware is a function that has access to the request and response objects and can be used to perform actions around an endpoint.'
addHowToData: true
---
# How to Add a Middleware # How to Add a Middleware
In this document, you’ll learn how to add a middleware to an existing or custom route in Medusa. In this document, you’ll learn how to add a middleware to an existing or custom route in Medusa.
@@ -1,3 +1,8 @@
---
description: 'Learn how to create endpoints in the Medusa server. This guide also includes how to add CORS configurations, creating multiple endpoints, adding protected routes, and more.'
addHowToData: true
---
# How to Create Endpoints # How to Create Endpoints
In this document, you’ll learn how to create endpoints in your Medusa server. In this document, you’ll learn how to create endpoints in your Medusa server.
@@ -1,3 +1,8 @@
---
description: 'Learn how to create an entity in the Medusa server. This guide also explains how to create a repository and access and delete the entity.'
addHowToData: true
---
# Create an Entity # Create an Entity
In this document, you’ll learn how you can create an [Entity](overview.md). In this document, you’ll learn how you can create an [Entity](overview.md).
@@ -1,3 +1,7 @@
---
description: 'Learn what entities are in the Medusa server. There are entities in the Medusa server, and developers can create custom entities.'
---
# Entities # Entities
In this document, you'll learn what Entities are in Medusa. In this document, you'll learn what Entities are in Medusa.
@@ -20,6 +24,47 @@ The `SoftDeletableEntity` class extends the `BaseEntity` class and adds another
--- ---
## metadata Attribute
Most entities in Medusa have a `metadata` attribute. This attribute is an object that can be used to store custom data related to that entity. In the database, this attribute is stored as a [JSON Binary (JSONB)](https://www.postgresql.org/docs/current/datatype-json.html#JSON-CONTAINMENT) column. On retrieval, the attribute is parsed into an object.
Some example use cases for the `metadata` attribute include:
- Store an external ID of an entity related to a third-party integartion.
- Store product customization such as personalization options.
### Add and Update Metadata
You can add or update metadata entities either through the REST APIs or through create and update methods in the entity's respective service.
In the [admin REST APIs](/api/admin), you'll find that in create or update requests of some entities you can also set the `metadata`.
In services, there are typically `create` or `update` methods that allow you to set or update the metadata.
If you want to add a property to the `metadata` object or update a property in the `metadata` object, you can pass the `metadata` object with the properties you want to add or update in it. For example:
```json
{
// other data
"metadata": {
"is_b2b": true
}
}
```
If you want to remove a property from the `metadata` object, you can pass the `metadata` object with the property you want to delete. The property should have an empty string value. For example:
```json
{
// other data
"metadata": {
"is_b2b": "" // this deletes the `is_b2b` property from `metadata`
}
}
```
---
## See Also ## See Also
- [Create an entity](./index.md) - [Create an entity](./index.md)
@@ -1,3 +1,7 @@
---
description: 'Learn how the events system is implemented in Medusa. It is built on a publish-subscribe architecture. The Medusa core publishes events when certain actions take place.'
---
# Events Architecture # Events Architecture
In this document, you'll learn how the events system is implemented in Medusa. In this document, you'll learn how the events system is implemented in Medusa.
@@ -1,4 +1,9 @@
# Toggle Feature Flags ---
description: 'Learn how to toggle feature flags in the Medusa server. This guide explains the steps required to toggle a feature flag.'
addHowToData: true
---
# How to Toggle Feature Flags
In this document, you’ll learn about what feature flags are and how to toggle them. In this document, you’ll learn about what feature flags are and how to toggle them.
@@ -1,3 +1,7 @@
---
description: 'Learn what gift cards are and how they work in the Medusa server. Learn about the relations between Gift Cards and other entities.'
---
# Gift Cards # Gift Cards
In this document, you’ll learn about Gift Cards and how they work in Medusa. In this document, you’ll learn about Gift Cards and how they work in Medusa.
@@ -1,3 +1,8 @@
---
description: 'Learn how to create a migration in the Medusa server. This guide explains how to write and run migrations.'
addHowToData: true
---
# How to Create Migrations # How to Create Migrations
In this document, you’ll learn how to create a [Migration](overview.md) using [Typeorm](https://typeorm.io) on your Medusa server. In this document, you’ll learn how to create a [Migration](overview.md) using [Typeorm](https://typeorm.io) on your Medusa server.
@@ -1,3 +1,7 @@
---
description: 'Learn what Migrations are in the Medusa server and how to run them. Migrations are used to make changes to the database schema the Medusa server is linked to.'
---
# Migrations # Migrations
In this document, you'll learn what Migrations are in Medusa. In this document, you'll learn what Migrations are in Medusa.
@@ -1,3 +1,8 @@
---
description: 'Learn how to create a notification provider in the Medusa server. This guide explains the different methods available in a Notification provider.'
addHowToData: true
---
# How to Create a Notification Provider # How to Create a Notification Provider
In this document, you’ll learn how to add a Notification Provider to your Medusa server. In this document, you’ll learn how to add a Notification Provider to your Medusa server.
@@ -1,3 +1,7 @@
---
description: 'Learn about the Notificaiton architecture in Medusa and the automation flow. The Notification Architecture is made up of the Notification Provider and Notification.'
---
# Notification Architecture Overview # Notification Architecture Overview
This document gives an overview of the notification architecture and how it works. This document gives an overview of the notification architecture and how it works.
@@ -1,3 +1,8 @@
---
description: 'Learn how to create a payment provider in the Medusa server. This guide explains the different methods available in a fulfillment provider.'
addHowToData: true
---
# How to Create a Payment Provider # How to Create a Payment Provider
In this document, you’ll learn how to add a Payment Provider to your Medusa server. If you’re unfamiliar with the Payment architecture in Medusa, make sure to check out the [overview](./overview.md) first. In this document, you’ll learn how to add a Payment Provider to your Medusa server. If you’re unfamiliar with the Payment architecture in Medusa, make sure to check out the [overview](./overview.md) first.
@@ -1,3 +1,7 @@
---
description: 'Learn about the payment architecture in the Medusa server. The payment architecture refers to all operations in the ecommerce store related to processing payments.'
---
# Payment Architecture Overview # Payment Architecture Overview
In this document, you’ll learn about the payment architecture in Medusa, specifically its 3 main components and the idempotency key. In this document, you’ll learn about the payment architecture in Medusa, specifically its 3 main components and the idempotency key.
+23 -165
View File
@@ -1,6 +1,11 @@
# Create a Plugin ---
description: 'Learn how to create a plugin in Medusa. This guide explains how to develop, configure, and test a plugin.'
addHowToData: true
---
In this document, you’ll learn how to create a plugin and publish it. If you’re interested to learn more about what plugins are and where to find available official and community plugins, check out the [overview document](overview.md). # How to Create a Plugin
In this document, you’ll learn how to create a plugin and some tips for develoment. If you’re interested to learn more about what plugins are and where to find available official and community plugins, check out the [overview document](overview.md).
## Prerequisites ## Prerequisites
@@ -34,10 +39,6 @@ By convention, all plugin names start with `medusa` followed by a descriptive na
## Changes to package.json ## Changes to package.json
### Rename Project Name
Update the `name` field in the `package.json` file to the name of your plugin. This should be the same name that you chose when running the `medusa new` command.
### Change Dependencies ### Change Dependencies
A basic Medusa server installed with the `medusa new` command has dependencies similar to this: A basic Medusa server installed with the `medusa new` command has dependencies similar to this:
@@ -62,7 +63,7 @@ A basic Medusa server installed with the `medusa new` command has dependencies s
For a plugin, some dependencies are not necessary. You can remove the packages `medusa-fulfillment-manual`, `medusa-payment-manual`, and `medusa-payment-stripe` as they are fulfillment and payment plugins necessary for a Medusa server, but not for a plugin. For a plugin, some dependencies are not necessary. You can remove the packages `medusa-fulfillment-manual`, `medusa-payment-manual`, and `medusa-payment-stripe` as they are fulfillment and payment plugins necessary for a Medusa server, but not for a plugin.
Additionally, you remove `@medusajs/medusa-cli` as you don’t need to use the Medusa CLI while developing a plugin. Additionally, you can remove `@medusajs/medusa-cli` as you don’t need to use the Medusa CLI while developing a plugin.
Once you’re done making these changes, re-run the install command to update your `node_modules` directory: Once you’re done making these changes, re-run the install command to update your `node_modules` directory:
@@ -70,65 +71,27 @@ Once you’re done making these changes, re-run the install command to update yo
npm install npm install
``` ```
This section includes recommended changes to your `package.json`. You can skip any of these changes if you don’t find them necessary to your plugin.
### Recommended: Change scripts ### Recommended: Change scripts
It's recommended to remove the `seed` and `start` scripts from your `package.json` as they aren't necessary for plugin development.
Furthermore, it's recommended to change the `build` command and add a new `watch` command:
```json title=package.json
"scripts": {
"build": "babel src --out-dir . --ignore **/__tests__ --extensions \".ts,.js\"",
"watch": "babel -w src --out-dir . --ignore **/__tests__ --extensions \".ts,.js\""
}
```
The change to the `build` command ensures that the built files are placed as explained in the [plugin structure section](#plugin-structure). The `watch` command makes the [testing of the plugin](#test-your-plugin) easier.
:::caution :::caution
If you don't make changes to the `build` and `watch` commands, please be aware of the [expected plugin structure](#plugin-structure). If you don't make changes to the `build` and `watch` commands, please be aware of the [expected plugin structure](#plugin-structure).
::: :::
A basic Medusa installation comes with the following scripts:
```json title=package.json
"scripts": {
"seed": "medusa seed -f ./data/seed.json",
"build": "babel src --out-dir . --ignore **/__tests__ --extensions \".ts,.js\"",
"start": "medusa develop"
}
```
The `seed` and `start` scripts aren't necessary for plugin development so you can remove them.
It’s also recommended to add the `watch` script that automatically compiles your files if they are changed:
```json title=package.json
"watch": "babel -w src --out-dir . --ignore **/__tests__ --extensions \".ts,.js\""
```
This is helpful when testing the plugin.
:::note
Testing the plugin is covered in a [later section](#test-your-plugin).
:::
Another recommended script is the `prepare` script that builds your files under a “production” environment:
```json title=package.json
"prepare": "cross-env NODE_ENV=production npm run build"
```
You would typically run this script before publishing your plugin.
This script requires installing the package `cross-env` as a development dependency:
```bash npm2yarn
npm install --save-dev cross-env
```
### Recommended: Change Basic Info
`package.json` holds information that further describes the package or the author that created the package. It is recommended to make the following changes:
- `description`: Change this to a sentence that describes what your plugin does.
- `author`: Your name and email.
- `repository`: The repository that holds your plugin’s codebase.
- `keywords`: This should hold the keywords that are related to your plugin. It’s recommended that all plugins use the keywords `medusa-plugin` or `medusa`.
--- ---
## Develop your Plugin ## Develop your Plugin
@@ -350,116 +313,11 @@ It is safe to ignore any `cross-env: command not found` error you may receive.
--- ---
## NPM Ignore File
Not all files that you use while developing your plugin are necessary to be published.
For example, the files you add in the `src` directory are compiled to the root of the plugin directory before publishing. Then, when a developer installs your plugin, they’ll just be using the files in the root.
So, you can ignore files and directories like `src` from the final published NPM package.
To do that, create the file `.npmignore` with the following content:
```bash title=.npmignore
/lib
node_modules
.DS_store
.env*
/*.js
!index.js
yarn.lock
src
.gitignore
.eslintrc
.babelrc
.prettierrc
#These are files that are included in a
#Medusa project and can be removed from a
#plugin project
medusa-config.js
Dockerfile
medusa-db.sql
develop.sh
```
---
## Publish Plugin ## Publish Plugin
Once you’re done developing your plugin you can publish the package on NPM’s registry so that other developers can benefit from it and use it. Once you're done with the development of the plugin, you can publish it to NPM so that other Medusa developers and users can use it.
Before you publish a plugin, you must [create an account on NPM](https://www.npmjs.com/signup). Please refer to [this guide on required steps to publish a plugin](./publish.md).
### Prepare Plugin
Before you publish or update your plugin, make sure to run the `prepare` command [defined earlier](#recommended-change-scripts):
```bash npm2yarn
npm run prepare
```
### Login
In your terminal, log in with your NPM account:
```bash
npm login
```
You’ll be asked to enter your NPM email and password.
### Publish Plugin Package
Once you’re logged in, you can publish your package with the following command:
```bash
npm publish
```
Your package is then published on NPM and everyone can use it and install it.
### Update Plugin
To update your plugin at a later point, you can run the following command to change the NPM version:
```bash
npm version <type>
```
Where `<type>` indicates the type of version update you’re publishing. For example, it can be `major` or `minor`.
You can see the [full list of types in NPM’s documentation](https://docs.npmjs.com/cli/v8/commands/npm-version).
Then, publish the new update:
```bash
npm publish
```
---
## Add Plugin to Medusa’s Repository
All officially-supported plugins are available in the [`packages` directory of the Medusa GitHub repository](https://github.com/medusajs/medusa/tree/master/packages).
If you’re interested in adding your plugin, you need to create a new pull request (PR) where you add your plugin inside the `packages` directory. Our team will then review your plugin, and if it’s approved the PR will be merged and your plugin will be available on Medusa’s repository.
:::note
Before contributing to the Medusa repository, please check out the [contribution guidelines](https://github.com/medusajs/medusa/blob/master/CONTRIBUTING.md).
:::
---
## Install a Plugin
To install any published plugin, you can run the following command on any Medusa server project:
```bash npm2yarn
npm install medusa-plugin-custom
```
--- ---
@@ -1,3 +1,7 @@
---
description: 'Learn what Plugins are and how they are used in Medusa. Plugins are re-usable customizations that can be added to a Medusa server.'
---
# Plugins # Plugins
In this document, you’ll get an overview of plugins in Medusa, where to find them, and how to install them. If you want to learn how to create a plugin, check out [this guide](create.md) instead. In this document, you’ll get an overview of plugins in Medusa, where to find them, and how to install them. If you want to learn how to create a plugin, check out [this guide](create.md) instead.
@@ -54,5 +58,6 @@ For community plugins, please refer to the installation instructions of that plu
## See Also ## See Also
- [Create your own plugin](create.md) - [Create a plugin](create.md)
- [Publish a plugin](publish.md)
- [Create a fulfillment provider](../shipping/add-fulfillment-provider.md) or a [payment provider](../payment/how-to-create-payment-provider.md) - [Create a fulfillment provider](../shipping/add-fulfillment-provider.md) or a [payment provider](../payment/how-to-create-payment-provider.md)
@@ -0,0 +1,160 @@
---
description: 'Learn how to publish a Medusa plugin to NPM. This guide lists some check lists to ensure you have implemented before publishing, as well as required steps.'
addHowToData: true
---
# How to Publish a Plugin
In this document, you'll learn how to publish a Medusa plugin to NPM and what are some requirements to keep in mind before publishing.
## Prerequisites
If you haven't created a plugin yet, please check [this guide to learn how to create a plugin](./create.md).
---
## Prepare the Plugin
### package.json Checklist
Before publishing your plugin, make sure you've set the following fields in your plugin's package.json:
- `name`: The name of your plugin. By convention, all plugin names start with `medusa` followed by a descriptive name of what the plugin does. For example, `medusa-payment-stripe`.
- `description`: A short description of what the plugin does.
- `author`: Your name or your company's name.
- `repository`: This includes details about the repository that holds the source code of the plugin. It's an object that holds the following properties:
- `type`: Should be `git`.
- `url`: The URL to the repository (for example, the GitHub repository holding the code of your plugin).
- `keywords`: An array of keywords that are related to the plugin. It's required for all Medusa plugins to use the keywords `medusa-plugin`. Other recommended keywords are:
- `medusa-plugin-analytics`: For plugins that add analytics functionalities or integrations.
- `medusa-plugin-cms`: For plugins that add CMS functionalities or integrations.
- `medusa-plugin-notification`: For plugins that add notification functionalities or integrations.
- `medusa-plugin-payment`: For plugins that add payment functionalities or integrations.
- `medusa-plugin-search`: For plugins that add search functionalities or integrations.
- `medusa-plugin-shipping`: For plugins that add shipping functionalities or integrations.
- `medusa-plugin-storage`: For plugins that add a file service or storage integration.
- `medusa-plugin-source`: For plugins that help migrate or import data into Medusa from another platform.
- `medusa-plugin-storefront`: For storefronts that can be integrated with a Medusa server.
- `medusa-plugin-other`: For any other type of plugin.
### Scripts in package.json
Make sure you add the `publish` command to your `scripts` field and make the following change to the `build` command:
```json title=package.json
"build": "babel src --out-dir . --ignore **/__tests__ --extensions \".ts,.js\"",
"prepare": "cross-env NODE_ENV=production npm run build"
```
The `build` command ensures that the plugin's built files are placed as explained in the [plugin structure](./create.md#plugin-structure) section of the Create Plugin documentation.
The `prepare` command facilitates your publishing process. You would typically run this script before publishing your plugin.
This new script requires installing the package `cross-env` as a development dependency:
```bash npm2yarn
npm install --save-dev cross-env
```
### Plugin Structure
Make sure your plugin's structure is as described in the [Create Plugin](./create.md#plugin-structure) documentation. If you've made the changes mentioned in [the above section to the scripts](#scripts-in-packagejson) in `package.json`, you should have the correct structure when you run the `prepare` command.
### NPM Ignore File
Not all files that you use while developing your plugin are necessary to be published.
For example, the files you add in the `src` directory are compiled to the root of the plugin directory before publishing. Then, when a developer installs your plugin, they’ll just be using the files in the root.
So, you can ignore files and directories like `src` from the final published NPM package.
To do that, create the file `.npmignore` with the following content:
```bash title=.npmignore
/lib
node_modules
.DS_store
.env*
/*.js
!index.js
yarn.lock
src
.gitignore
.eslintrc
.babelrc
.prettierrc
# These are files that are included in a
# Medusa project and can be removed from a
# plugin project
medusa-config.js
Dockerfile
medusa-db.sql
develop.sh
```
---
## Publish Plugin
This section explains how to publish your plugin to NPM.
Before you publish a plugin, you must [create an account on NPM](https://www.npmjs.com/signup).
### Run Prepare Command
Before you publish or update your plugin, make sure to run the `prepare` command [defined earlier](#packagejson-checklist):
```bash npm2yarn
npm run prepare
```
### Login
In your terminal, log in with your NPM account:
```bash
npm login
```
You’ll be asked to enter your NPM email and password.
### Publish Plugin Package
Once you’re logged in, you can publish your package with the following command:
```bash
npm publish
```
Your package is then published on NPM and everyone can use it and install it.
### Install Plugin
To install your published plugin, you can run the following command on any Medusa server project:
```bash npm2yarn
npm install medusa-plugin-custom
```
### Update Plugin
To update your plugin at a later point, you can run the following command to change the NPM version:
```bash
npm version <type>
```
Where `<type>` indicates the type of version update you’re publishing. For example, it can be `major` or `minor`. You can see the [full list of types in NPM’s documentation](https://docs.npmjs.com/cli/v8/commands/npm-version).
Then, publish the new update:
```bash
npm publish
```
---
## See Also
- [Available official plugins](https://github.com/medusajs/medusa/tree/master/packages)
@@ -1,3 +1,7 @@
---
description: 'Learn what price lists are and how they work in a Medusa server. Price Lists can be used to override product prices based on different conditions.'
---
# Price Lists # Price Lists
In this document, you’ll learn what price lists are and how they work. In this document, you’ll learn what price lists are and how they work.
@@ -1,7 +1,12 @@
---
description: 'Learn how to implement price list functionalities for admins using the REST APIs. This includes how to create a price list, retriving price list details, managing prices in the price list, and more.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
# How to Use PriceList APIs # How to Manage PriceLists
In this document, you’ll learn how to use the PriceList Admin APIs to create, update, and manage prices in a price list. In this document, you’ll learn how to use the PriceList Admin APIs to create, update, and manage prices in a price list.
@@ -23,6 +28,12 @@ This guide includes code snippets to send requests to your Medusa server using M
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../../medusa-react/overview.md#usage).
### Authenticated Admin User ### Authenticated Admin User
You must be an authenticated admin user before following along with the steps in the tutorial. You must be an authenticated admin user before following along with the steps in the tutorial.
@@ -69,13 +80,13 @@ For example, sending the following request creates a price list with two prices:
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```jsx
import { PriceListType } from "@medusajs/medusa" import { PriceListStatus, PriceListType } from "@medusajs/medusa"
medusa.admin.priceLists.create({ medusa.admin.priceLists.create({
name: "New Price List", name: "New Price List",
description: "A new price list", description: "A new price list",
type: PriceListType.SALE, type: PriceListType.SALE,
status: "active", status: PriceListStatus.ACTIVE,
prices: [ prices: [
{ {
amount: 1000, amount: 1000,
@@ -96,6 +107,46 @@ medusa.admin.priceLists.create({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { PriceListStatus, PriceListType } from "@medusajs/medusa"
import { useAdminCreatePriceList } from "medusa-react"
const CreatePriceList = () => {
const createPriceList = useAdminCreatePriceList()
// ...
const handleCreate = () => {
createPriceList.mutate({
name: "New Price List",
description: "A new price list",
type: PriceListType.SALE,
status: PriceListStatus.ACTIVE,
prices: [
{
amount: 1000,
variant_id,
currency_code: "eur",
max_quantity: 3,
},
{
amount: 1500,
variant_id,
currency_code: "eur",
min_quantity: 4,
},
],
})
}
// ...
}
export default CreatePriceList
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -185,6 +236,27 @@ medusa.admin.priceLists.retrieve(priceListId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { CustomerGroup } from "@medusajs/medusa"
import { useAdminPriceList } from "medusa-react"
const PriceList = () => {
const { price_list, isLoading } = useAdminPriceList(priceListId)
return (
<div>
{isLoading && <span>Loading...</span>}
{price_list && <span>{price_list.name}</span>}
</div>
)
}
export default PriceList
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -229,6 +301,29 @@ medusa.admin.priceLists.update(priceListId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { PriceListStatus, PriceListType } from "@medusajs/medusa"
import { useAdminUpdatePriceList } from "medusa-react"
const CreatePriceList = () => {
const updatePriceList = useAdminUpdatePriceList(priceListId)
// ...
const handleUpdate = () => {
updatePriceList.mutate({
ends_at: "2022-10-11",
})
}
// ...
}
export default CreatePriceList
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -298,6 +393,34 @@ medusa.admin.priceLists.addPrices(priceListId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminCreatePriceListPrices } from "medusa-react"
const PriceList = () => {
const addPrice = useAdminCreatePriceListPrices(priceListId)
// ...
const handleAddPrice = () => {
addPrice.mutate({
prices: [
{
amount: 1200,
variant_id,
currency_code: "eur",
},
],
})
}
// ...
}
export default PriceList
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -363,6 +486,29 @@ medusa.admin.priceLists.deleteProductPrices(priceListId, productId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDeletePriceListProductPrices } from "medusa-react"
const PriceList = () => {
const deletePrices = useAdminDeletePriceListProductPrices(
priceListId,
productId
)
// ...
const handleDeletePrices = () => {
deletePrices.mutate()
}
// ...
}
export default PriceList
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -409,6 +555,29 @@ medusa.admin.priceLists.deleteVariantPrices(priceListId, variantId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDeletePriceListVariantPrices } from "medusa-react"
const PriceList = () => {
const deleteVariantPrices = useAdminDeletePriceListVariantPrices(
priceListId,
variantId
)
// ...
const handleDeletePrices = () => {
deleteVariantPrices.mutate()
}
// ...
}
export default PriceList
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -457,6 +626,26 @@ medusa.admin.priceLists.delete(priceListId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDeletePriceList } from "medusa-react"
const PriceList = () => {
const deletePriceList = useAdminDeletePriceList(priceListId)
// ...
const handleDeletePriceList = () => {
deletePriceList.mutate()
}
// ...
}
export default PriceList
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -1,3 +1,7 @@
---
description: 'Learn what the price selection strategy is in the Medusa server. The price selection strategy retrieves the best price for a product variant for a specific context.'
---
# Price Selection Strategy # Price Selection Strategy
In this document, you’ll learn what a price selection strategy is. In this document, you’ll learn what a price selection strategy is.
@@ -1,4 +1,9 @@
# Override Price Selection Strategy ---
description: 'Learn how to override the price selection strategy. The price selection strategy is used to determine the best price based on a specific context.'
addHowToData: true
---
# How to Override Price Selection Strategy
In this document, you’ll learn how to override Medusa’s price selection strategy to create a custom pricing strategy. In this document, you’ll learn how to override Medusa’s price selection strategy to create a custom pricing strategy.
@@ -1,3 +1,7 @@
---
description: 'Learn what publishable API keys are and how they can be used in the Medusa server. Publishable API keys can be used to scope API calls with an API key.'
---
# Publishable API Keys Overview # Publishable API Keys Overview
In this document, you’ll learn about Publishable API Keys and their usage. In this document, you’ll learn about Publishable API Keys and their usage.
@@ -1,3 +1,7 @@
---
description: 'Learn about what Regions are and how they are used in a Medusa server. Regions represent at least one country on the Medusa server.'
---
# Regions Overview # Regions Overview
In this document, you’ll learn about Regions and their importance in your Medusa server. In this document, you’ll learn about Regions and their importance in your Medusa server.
@@ -1,3 +1,7 @@
---
description: 'Learn what Sales Channels are and how they can be used in Medusa. Sales Channels allow merchants to separate between the different channels products are sold in.'
---
# Sales Channels # Sales Channels
In this document, you’ll learn about Sales Channels and how they can be used in Medusa. In this document, you’ll learn about Sales Channels and how they can be used in Medusa.
@@ -1,3 +1,8 @@
---
description: 'Learn how to implement sales channels features for admins in Medusa using the REST APIs. This includes how to list sales channels, and create, retrieve, update and delete a sales channel. This also includes how to manage products in a sales channel.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -25,21 +30,18 @@ This guide explains how to perform all these operations using the Admin APIs.
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.mdx) to get started. 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.mdx) 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 ### 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. This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../../medusa-react/overview.md#usage).
### Authenticated Admin User ### Authenticated Admin User
You must be an authenticated admin user before following along with the steps in this guide. You must be an authenticated admin user before following along with the steps in this guide.
@@ -55,7 +57,7 @@ You can create a sales channel by sending a request to the Create a Sales Channe
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.salesChannels.create({ medusa.admin.salesChannels.create({
name: "App", name: "App",
description: "Mobile app", description: "Mobile app",
@@ -65,10 +67,33 @@ medusa.admin.salesChannels.create({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminCreateSalesChannel } from "medusa-react"
const CreateSalesChannel = () => {
const createSalesChannel = useAdminCreateSalesChannel()
// ...
const handleCreate = (name: string, description: string) => {
createSalesChannel.mutate({
name,
description,
})
}
// ...
}
export default CreateSalesChannel
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/admin/sales-channels`, { fetch(`<SERVER_URL>/admin/sales-channels`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -115,17 +140,47 @@ You can list all sales channels by sending a request to the List Sales Channels
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.salesChannels.list() medusa.admin.salesChannels.list()
.then(({ sales_channels, limit, offset, count }) => { .then(({ sales_channels, limit, offset, count }) => {
console.log(sales_channels.length) console.log(sales_channels.length)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { SalesChannel } from "@medusajs/medusa"
import { useAdminSalesChannels } from "medusa-react"
const SalesChannels = () => {
const { sales_channels, isLoading } = useAdminSalesChannels()
return (
<div>
{isLoading && <span>Loading...</span>}
{sales_channels && !sales_channels.length && (
<span>No Sales Channels</span>
)}
{sales_channels && sales_channels.length > 0 && (
<ul>
{sales_channels.map((salesChannel: SalesChannel) => (
<li key={salesChannel.id}>{salesChannel.name}</li>
))}
</ul>
)}
</div>
)
}
export default SalesChannels
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/admin/sales-channels`, { fetch(`<SERVER_URL>/admin/sales-channels`, {
credentials: "include", credentials: "include",
}) })
@@ -157,17 +212,37 @@ You can retrieve a sales channel’s details by its ID using the Get Sales Chann
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.salesChannels.retrieve(salesChannelId) medusa.admin.salesChannels.retrieve(salesChannelId)
.then(({ sales_channel }) => { .then(({ sales_channel }) => {
console.log(sales_channel.id) console.log(sales_channel.id)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminSalesChannel } from "medusa-react"
const SalesChannel = () => {
const { sales_channel, isLoading } = useAdminSalesChannel(salesChannelId)
return (
<div>
{isLoading && <span>Loading...</span>}
{sales_channel && <span>{sales_channel.name}</span>}
</div>
)
}
export default SalesChannel
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}`, { fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}`, {
credentials: "include", credentials: "include",
}) })
@@ -199,7 +274,7 @@ You can update a Sales Channel’s details and attributes by sending a request t
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.salesChannels.update(salesChannelId, { medusa.admin.salesChannels.update(salesChannelId, {
is_disabled: false, is_disabled: false,
}) })
@@ -208,10 +283,32 @@ medusa.admin.salesChannels.update(salesChannelId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminUpdateSalesChannel } from "medusa-react"
const UpdateSalesChannel = () => {
const updateSalesChannel = useAdminUpdateSalesChannel(salesChannelId)
// ...
const handleUpdate = () => {
updateSalesChannel.mutate({
is_disabled: false,
})
}
// ...
}
export default UpdateSalesChannel
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}`, { fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -258,17 +355,37 @@ You can delete a sales channel by sending a request to the Delete Sales Channel
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.salesChannels.delete(salesChannelId) medusa.admin.salesChannels.delete(salesChannelId)
.then(({ id, object, deleted }) => { .then(({ id, object, deleted }) => {
console.log(id) console.log(id)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDeleteSalesChannel } from "medusa-react"
const SalesChannel = () => {
const deleteSalesChannel = useAdminDeleteSalesChannel(salesChannelId)
// ...
const handleDelete = () => {
deleteSalesChannel.mutate()
}
// ...
}
export default SalesChannel
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}`, { fetch(`<SERVER_URL>/admin/sales-channels/${salesChannelId}`, {
method: "DELETE", method: "DELETE",
credentials: "include", credentials: "include",
@@ -303,7 +420,7 @@ To add a product to a sales channel, send a request to the Sales Channel’s Add
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.salesChannels.addProducts(salesChannelId, { medusa.admin.salesChannels.addProducts(salesChannelId, {
product_ids: [ product_ids: [
{ {
@@ -316,10 +433,36 @@ medusa.admin.salesChannels.addProducts(salesChannelId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminAddProductsToSalesChannel } from "medusa-react"
const SalesChannel = () => {
const addProducts = useAdminAddProductsToSalesChannel(salesChannelId)
// ...
const handleAddProducts = (productId: string) => {
addProducts.mutate({
product_ids: [
{
id: productId,
},
],
})
}
// ...
}
export default SalesChannel
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch( fetch(
`<SERVER_URL>/admin/sales-channels/${salesChannelId}/products/batch`, `<SERVER_URL>/admin/sales-channels/${salesChannelId}/products/batch`,
{ {
@@ -373,7 +516,7 @@ You can list the products available in a sales channel by sending a request to t
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.products.list({ medusa.admin.products.list({
sales_channel_id: [ sales_channel_id: [
salesChannelId, salesChannelId,
@@ -384,10 +527,41 @@ medusa.admin.products.list({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { Product } from "@medusajs/medusa"
import { PricedProduct } from "@medusajs/medusa/dist/types/pricing"
import { useAdminProducts } from "medusa-react"
const SalesChannelProducts = () => {
const { products, isLoading } = useAdminProducts({
sales_channel_id: [salesChannelId],
})
return (
<div>
{isLoading && <span>Loading...</span>}
{products && products.length > 0 && (
<ul>
{products.map((product: (Product | PricedProduct)) => (
<li key={product.id}>{product.title}</li>
))}
</ul>
)}
{products && !products.length && <span>No Products</span>}
</div>
)
}
export default SalesChannelProducts
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch( fetch(
`<SERVER_URL>/admin/products?sales_channel_id[0]=${salesChannelId}`, `<SERVER_URL>/admin/products?sales_channel_id[0]=${salesChannelId}`,
{ {
@@ -426,7 +600,7 @@ You can delete a product from a sales channel by sending a request to the Sales
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.salesChannels.removeProducts(salesChannelId, { medusa.admin.salesChannels.removeProducts(salesChannelId, {
product_ids: [ product_ids: [
{ {
@@ -439,10 +613,38 @@ medusa.admin.salesChannels.removeProducts(salesChannelId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAdminDeleteProductsFromSalesChannel } from "medusa-react"
const SalesChannel = () => {
const deleteProducts = useAdminDeleteProductsFromSalesChannel(
salesChannelId
)
// ...
const handleDeleteProducts = (productId: string) => {
deleteProducts.mutate({
product_ids: [
{
id: productId,
},
],
})
}
// ...
}
export default SalesChannel
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch( fetch(
`<SERVER_URL>/admin/sales-channels/${salesChannelId}/products/batch`, `<SERVER_URL>/admin/sales-channels/${salesChannelId}/products/batch`,
{ {
@@ -498,7 +700,7 @@ You can filter orders by a specific sales channel by sending a request to the Li
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.admin.orders.list({ medusa.admin.orders.list({
sales_channel_id: [ sales_channel_id: [
salesChannelId, salesChannelId,
@@ -511,10 +713,42 @@ medusa.admin.orders.list({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { Order } from "@medusajs/medusa"
import { useAdminOrders } from "medusa-react"
const SalesChannelOrders = () => {
const { orders, isLoading } = useAdminOrders({
sales_channel_id: [salesChannelId],
offset: 0,
limit: 50,
})
return (
<div>
{isLoading && <span>Loading...</span>}
{orders && orders.length > 0 && (
<ul>
{orders.map((order: Order) => (
<li key={order.id}>{order.display_id}</li>
))}
</ul>
)}
{orders && !orders.length && <span>No Orders</span>}
</div>
)
}
export default SalesChannelOrders
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/admin/orders?sales_channel_id[0]=${salesChannelId}`, { fetch(`<SERVER_URL>/admin/orders?sales_channel_id[0]=${salesChannelId}`, {
credentials: "include", credentials: "include",
}) })
@@ -1,3 +1,8 @@
---
description: 'Learn how to create a scheduled job in the Medusa server. The scheduled job in this example will simply change the status of draft products to published.'
addHowToData: true
---
# How to Create a Scheduled Job # How to Create a Scheduled Job
In this document, you’ll learn how to create a scheduled job in Medusa. In this document, you’ll learn how to create a scheduled job in Medusa.
@@ -1,3 +1,8 @@
---
description: 'Learn how to create a service in Medusa. This guide also includes how to use services in other services, subscribers, and endpoints.'
addHowToData: true
---
# Create a Service # Create a Service
In this document, you’ll learn how you can create a [Service](./overview.md) and use it across your Medusa server just like any of the core services. In this document, you’ll learn how you can create a [Service](./overview.md) and use it across your Medusa server just like any of the core services.
@@ -1,3 +1,7 @@
---
description: 'Learn what Services are in the Medusa server. Services represent bundled helper methods that you want to use across the server.'
---
# Services # Services
In this document, you'll learn about what Services are in Medusa. In this document, you'll learn about what Services are in Medusa.
@@ -1,3 +1,8 @@
---
description: 'Learn how to create a fulfillment provider in the Medusa server. This guide explains the different methods in the fulfillment provider.'
addHowToData: true
---
# How to Add a Fulfillment Provider # How to Add a Fulfillment Provider
In this document, you’ll learn how to add a fulfillment provider to a Medusa server. If you’re unfamiliar with the Shipping architecture in Medusa, make sure to [check out the overview first](overview.md). In this document, you’ll learn how to add a fulfillment provider to a Medusa server. If you’re unfamiliar with the Shipping architecture in Medusa, make sure to [check out the overview first](overview.md).
@@ -1,3 +1,7 @@
---
description: 'Learn how the shipping architecture is implemented in the Medusa server. This includes an overview of what the Fulfillment Provider, Shipping Profile, Shipping Option, and Shipping Methods.'
---
# Shipping Architecture Overview # Shipping Architecture Overview
This document gives an overview of the shipping architecture and its four most important components. This document gives an overview of the shipping architecture and its four most important components.
@@ -1,4 +1,9 @@
# Create a Subscriber ---
description: 'Learn how to create a subscriber in the Medusa server. You can use subscribers to implement functionalities like sending an order confirmation email.'
addHowToData: true
---
# How to Create a Subscriber
In this document, you’ll learn how to create a [Subscriber](overview.md) in your Medusa server that listens to events to perform an action. In this document, you’ll learn how to create a [Subscriber](overview.md) in your Medusa server that listens to events to perform an action.
@@ -1,3 +1,7 @@
---
description: 'Learn about the available events and their data payloads in Medusa. Events can be used to perform an action when the events are triggered.'
---
# Events Reference # Events Reference
This document details all events in Medusa, when they are triggered, and what data your handler method will receive when the event is triggered. This document details all events in Medusa, when they are triggered, and what data your handler method will receive when the event is triggered.
@@ -2068,6 +2072,102 @@ Object of the following format:
--- ---
## Product Category Events
This section holds all events related to product categories.
<table class="reference-table">
<thead>
<tr>
<th>
Event Name
</th>
<th>
Description
</th>
<th>
Event Data Payload
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
`product-category.created`
</td>
<td>
Triggered when a product category is created.
</td>
<td>
Object of the following format:
```js noReport noCopy
{
id, // string ID of category
}
```
</td>
</tr>
<tr>
<td>
`product-category.updated`
</td>
<td>
Triggered when a product category is updated.
</td>
<td>
Object of the following format:
```js noReport noCopy
{
id, // string ID of category
}
```
</td>
</tr>
<tr>
<td>
`product-category.deleted`
</td>
<td>
Triggered when a product category is deleted.
</td>
<td>
Object of the following format:
```js noReport noCopy
{
id, // string ID of category
}
```
</td>
</tr>
</tbody>
</table>
---
## Product Variant Events ## Product Variant Events
This section holds all events related to product variants. This section holds all events related to product variants.
@@ -1,3 +1,7 @@
---
description: 'Learn what subscribers are in the Medusa server. Subscribers are used to listen to triggered events to perform an action.'
---
# Subscribers # Subscribers
In this document, you'll learn what Subscribers are in Medusa. In this document, you'll learn what Subscribers are in Medusa.
@@ -1,3 +1,7 @@
---
description: 'Learn what tax-inclusive pricing is and how it works in Medusa. Tax-inclusive pricing allows merchants to set the final prices for products and shipping options regardless of what tax rate is applicable for the customer.'
---
# Tax Inclusive Pricing # Tax Inclusive Pricing
In this document, you’ll learn how tax-inclusive pricing works in Medusa. In this document, you’ll learn how tax-inclusive pricing works in Medusa.
@@ -1,3 +1,8 @@
---
description: 'Learn how to manually calculate taxes during checkout in the Medusa server. There are different methods including using endpoints or services.'
addHowToData: true
---
# Calculate Taxes Manually in Checkout # Calculate Taxes Manually in Checkout
In this document, you’ll learn how to manually calculate taxes during checkout if you have automatic tax calculation disabled in a region. In this document, you’ll learn how to manually calculate taxes during checkout if you have automatic tax calculation disabled in a region.
@@ -1,5 +1,6 @@
--- ---
hide_table_of_contents: true hide_table_of_contents: true
description: 'Upgrade guides on how to update the Medusa server along with other Medusa components to the latest version.'
--- ---
import DocCardList from '@theme/DocCardList'; import DocCardList from '@theme/DocCardList';
@@ -52,3 +52,36 @@ import { QueryClient } from "@tanstack/react-query"
// this remains the same // this remains the same
const queryClient = new QueryClient() const queryClient = new QueryClient()
``` ```
### Fix No QueryClient set Errors
If you're using a Next.js storefront, you might face the following error after this update when you run your storefront:
```bash
No QueryClient set
```
This is due to an issue related to Tanstack Query shipping `esm` modules in its latest versions and how Next.js uses Webpack.
Although in future versions of `medusa-react` this issue will be fixed, you can add the following into `next.config.js` to fix this error:
```js
const path = require("path")
/** @type {import('next').NextConfig} */
const nextConfig = {
// ... other configs
webpack: (config, options) => {
if (options.isServer) {
config.externals = ["@tanstack/react-query", ...config.externals]
}
const reactQuery = path.resolve(
require.resolve("@tanstack/react-query")
)
config.resolve.alias["@tanstack/react-query"] = reactQuery
return config
},
}
module.exports = nextConfig
```
@@ -1,3 +1,8 @@
---
description: 'Learn how to handle the order claim event in the Medusa server. When the event is triggered, you can send an email to the customer to inform them about it.'
addHowToData: true
---
# How to Handle Order Claim Event # How to Handle Order Claim Event
In this document, you’ll learn how to handle the order claim event and send a confirmation email when the event is triggered. In this document, you’ll learn how to handle the order claim event and send a confirmation email when the event is triggered.
@@ -1,4 +1,9 @@
# Send Gift Card Code to Customer ---
description: 'Learn how to send a gift card code to the customer. Once the customer purchases a gift card, an email can be sent with the code so that they can redeem the gift card.'
addHowToData: true
---
# How to Send Gift Card Code to Customer
In this document, you’ll learn how to send a customer the gift card code they purchased. In this document, you’ll learn how to send a customer the gift card code they purchased.
@@ -1,3 +1,8 @@
---
description: 'Learn how to implement customer account functionalities in your storefront using the REST APIs. This includes implementing customer registration, login, edit profile, and more.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -37,10 +42,16 @@ It's also assumed you already have a storefront set up. It can be a custom store
### JS Client ### JS Client
This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client and JavaScript’s Fetch API. This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
--- ---
## Register a Customer ## Register a Customer
@@ -64,6 +75,38 @@ medusa.customers.create({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCreateCustomer } from "medusa-react"
const RegisterCustomer = () => {
const createCustomer = useCreateCustomer()
// ...
const handleCreate = () => {
// ...
createCustomer.mutate({
first_name,
last_name,
email,
password,
})
}
// ...
return (
<form>
{/* Render form */}
</form>
)
}
export default RegisterCustomer
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -321,6 +364,36 @@ medusa.customers.update({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useUpdateMe } from "medusa-react"
const UpdateCustomer = () => {
const updateCustomer = useUpdateMe()
// ...
const handleUpdate = () => {
// ...
updateCustomer.mutate({
id: customer_id,
first_name,
})
}
// ...
return (
<form>
{/* Render form */}
</form>
)
}
export default UpdateCustomer
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -530,6 +603,35 @@ medusa.customers.listOrders()
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCustomerOrders } from "medusa-react"
import { Order } from "@medusajs/medusa"
const Orders = () => {
// refetch a function that can be used to
// re-retrieve orders after the customer logs in
const { orders, isLoading, refetch } = useCustomerOrders()
return (
<div>
{isLoading && <span>Loading orders...</span>}
{orders?.length && (
<ul>
{orders.map((order: Order) => (
<li key={order.id}>{order.display_id}</li>
))}
</ul>
)}
</div>
)
}
export default Orders
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -1,7 +1,12 @@
---
description: 'Learn how to implement order-edit related features in the storefront using REST APIs. This includes showing the customer order-edit requests, authorizing additional payments, and confirming or declining order edits.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
# How to Handle an Order Edit # How to Handle an Order Edit in Storefront
In this document, you’ll learn how to allow a customer to confirm or decline an Order Edit. In this document, you’ll learn how to allow a customer to confirm or decline an Order Edit.
@@ -51,6 +56,12 @@ This guide includes code snippets to send requests to your Medusa server using M
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
### Previous Steps ### Previous Steps
You must have an existing order edit in the “request” state. You must have an existing order edit in the “request” state.
@@ -72,6 +83,21 @@ medusa.orderEdits.retrieve(orderEditId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```ts
import { useOrderEdit } from "medusa-react"
const OrderEdit = () => {
const { order_edit, isLoading } = useOrderEdit(orderEditId)
// ...
}
export default OrderEdit
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -123,7 +149,7 @@ All data about changes to the original order’s items can be found in `order_ed
Here’s an example of how you can use this data to show the customer the requested edits to the order: Here’s an example of how you can use this data to show the customer the requested edits to the order:
```jsx ```tsx
<ul> <ul>
{orderEdit.changes.map((itemChange) => ( {orderEdit.changes.map((itemChange) => (
<li key={itemChange.id}> <li key={itemChange.id}>
@@ -184,6 +210,28 @@ medusa.paymentCollections.managePaymentSession(paymentCollectionId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```ts
import { useManagePaymentSession } from "medusa-react"
const OrderEditPayment = () => {
const managePaymentSession = useManagePaymentSession(paymentCollectionId)
// ...
const handleAdditionalPayment = (provider_id: string) => {
managePaymentSession.mutate({
provider_id,
})
}
// ...
}
export default OrderEditPayment
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -224,6 +272,28 @@ medusa.paymentCollection
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```ts
import { useAuthorizePaymentSession } from "medusa-react"
const OrderEditPayment = () => {
const authorizePaymentSession = useAuthorizePaymentSession(
paymentCollectionId
)
// ...
const handleAuthorizePayment = (paymentSessionId: string) => {
authorizePaymentSession.mutate(paymentSessionId)
}
// ...
}
export default OrderEditPayment
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -263,6 +333,26 @@ medusa.orderEdits.complete(orderEditId)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```ts
import { useCompleteOrderEdit } from "medusa-react"
const OrderEdit = () => {
const completeOrderEdit = useCompleteOrderEdit(orderEditId)
// ...
const handleCompleteOrderEdit = () => {
completeOrderEdit.mutate()
}
// ...
}
export default OrderEdit
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -310,6 +400,28 @@ medusa.orderEdits.decline(orderEditId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```ts
import { useDeclineOrderEdit } from "medusa-react"
const OrderEdit = () => {
const declineOrderEdit = useDeclineOrderEdit(orderEditId)
// ...
const handleDeclineOrderEdit = () => {
declineOrderEdit.mutate({
declined_reason: "I am not satisfied",
})
}
// ...
}
export default OrderEdit
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -1,3 +1,8 @@
---
description: 'Learn how to implement the checkout flow in your storefront using the REST APIs. This includes adding steps related to shipping and payment, then placing the order.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -33,6 +38,14 @@ This guide includes code snippets to send requests to your Medusa server using M
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
It's also assumed you already have [used CartProvider higher in your component tree](../../medusa-react/overview.md#cartprovider).
### Previous Steps ### Previous Steps
This document assumes you’ve already taken care of the add-to-cart flow. So, you should have a [cart created](/api/store/#tag/Cart/operation/PostCart) for the customer with at least [one product in it](/api/store/#tag/Cart/operation/PostCartsCartLineItems). This document assumes you’ve already taken care of the add-to-cart flow. So, you should have a [cart created](/api/store/#tag/Cart/operation/PostCart) for the customer with at least [one product in it](/api/store/#tag/Cart/operation/PostCartsCartLineItems).
@@ -52,7 +65,7 @@ After the customer enters their shipping address information, you must send a `P
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.update(cartId, { medusa.carts.update(cartId, {
shipping_address: { shipping_address: {
company, company,
@@ -72,10 +85,44 @@ medusa.carts.update(cartId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
const Cart = () => {
// ...
const { updateCart } = useCart()
const addShippingAddress = (address: Record<string, string>) => {
updateCart.mutate({
shipping_address: {
company: address.company,
first_name: address.first_name,
last_name: address.last_name,
address_1: address.address_1,
address_2: address.address_2,
city: address.city,
country_code: address.country_code,
province: address.province,
postal_code: address.postal_code,
phone: address.phone,
},
})
}
// ...
}
export default Cart
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/carts/${cartId}`, { fetch(`<SERVER_URL>/store/carts/${cartId}`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -121,17 +168,51 @@ You can retrieve the list of shipping options by sending a `GET` request to the
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.shippingOptions.listCartOptions(cartId) medusa.shippingOptions.listCartOptions(cartId)
.then(({ shipping_options }) => { .then(({ shipping_options }) => {
console.log(shipping_options.length) console.log(shipping_options.length)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { ShippingOption } from "@medusajs/medusa"
import { useCartShippingOptions } from "medusa-react"
type Props = {
cartId: string
}
const ShippingOptions = ({ cartId }: Props) => {
const { shipping_options, isLoading } = useCartShippingOptions(cartId)
return (
<div>
{isLoading && <span>Loading...</span>}
{shipping_options && !shipping_options.length && (
<span>No shipping options</span>
)}
{shipping_options && (
<ul>
{shipping_options.map((shipping_option: ShippingOption) => (
<li key={shipping_option.id}>{shipping_option.name}</li>
))}
</ul>
)}
</div>
)
}
export default ShippingOptions
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/shipping-options/${cartId}`, { fetch(`<SERVER_URL>/store/shipping-options/${cartId}`, {
credentials: "include", credentials: "include",
}) })
@@ -153,7 +234,7 @@ Once the customer chooses one of the available shipping options, send a `POST` r
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.addShippingMethod(cartId, { medusa.carts.addShippingMethod(cartId, {
option_id: shippingOptionId, // the ID of the selected option option_id: shippingOptionId, // the ID of the selected option
}) })
@@ -162,10 +243,33 @@ medusa.carts.addShippingMethod(cartId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useAddShippingMethodToCart } from "medusa-react"
// ...
const ShippingOptions = ({ cartId }: Props) => {
// ...
const addShippingMethod = useAddShippingMethodToCart(cartId)
const handleAddShippingMethod = (option_id: string) => {
addShippingMethod.mutate({
option_id,
})
}
// ...
}
export default ShippingOptions
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/carts/${cartId}/shipping-methods`, { fetch(`<SERVER_URL>/store/carts/${cartId}/shipping-methods`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -204,17 +308,47 @@ To initialize the payment sessions, send a `POST` request to the [Initialize Pay
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.createPaymentSessions(cartId) medusa.carts.createPaymentSessions(cartId)
.then(({ cart }) => { .then(({ cart }) => {
console.log(cart.payment_sessions) console.log(cart.payment_sessions)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { PaymentSession } from "@medusajs/medusa"
import { useCart } from "medusa-react"
import { useEffect } from "react"
const PaymentProviders = () => {
const { cart, startCheckout } = useCart()
useEffect(() => {
startCheckout.mutate()
}, [])
return (
<div>
{!cart?.payment_sessions.length && <span>No payment providers</span>}
<ul>
{cart?.payment_sessions.map((paymentSession: PaymentSession) => (
<li key={paymentSession.id}>{paymentSession.provider_id}</li>
))}
</ul>
</div>
)
}
export default PaymentProviders
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/carts/${cartId}/payment-sessions`, { fetch(`<SERVER_URL>/store/carts/${cartId}/payment-sessions`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -237,7 +371,7 @@ When the customer chooses the payment provider they want to complete purchase wi
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.setPaymentSession(cartId, { medusa.carts.setPaymentSession(cartId, {
// retrieved from the payment session selected by the customer // retrieved from the payment session selected by the customer
provider_id: paymentProviderId, provider_id: paymentProviderId,
@@ -247,10 +381,32 @@ medusa.carts.setPaymentSession(cartId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
const PaymentProviders = () => {
const { cart, startCheckout, pay } = useCart()
// ...
const handleSetPaymentSession = (provider_id: string) => {
pay.mutate({
provider_id,
})
}
// ...
}
export default PaymentProviders
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/carts/${cartId}/payment-session`, { fetch(`<SERVER_URL>/store/carts/${cartId}/payment-session`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -290,7 +446,7 @@ If you need to update that data at any point before the purchase is made, send a
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.updatePaymentSession(cartId, paymentProviderId, { medusa.carts.updatePaymentSession(cartId, paymentProviderId, {
data: { data: {
// pass any data you want to add in the `data` attribute // pass any data you want to add in the `data` attribute
@@ -303,12 +459,40 @@ medusa.carts.updatePaymentSession(cartId, paymentProviderId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useUpdatePaymentSession, useCart } from "medusa-react"
// ...
const PaymentProviders = () => {
const { cart } = useCart()
const updatePaymentSession = useUpdatePaymentSession(cart.id)
// ...
const handleUpdatePaymentSession = (
provider_id: string,
data: Record<string, any>
) => {
updatePaymentSession.mutate({
provider_id,
data,
})
}
// ...
}
export default PaymentProviders
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
<!-- eslint-disable max-len --> <!-- eslint-disable max-len -->
```jsx ```ts
fetch( fetch(
`<SERVER_URL>/store/carts/${cartId}/payment-sessions/${paymentProviderId}`, `<SERVER_URL>/store/carts/${cartId}/payment-sessions/${paymentProviderId}`,
{ {
@@ -348,17 +532,38 @@ To complete a cart, send a `POST` request to the [Complete a Cart](/api/store/#t
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.complete(cartId) medusa.carts.complete(cartId)
.then(({ type, data }) => { .then(({ type, data }) => {
console.log(type, data) console.log(type, data)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
// ...
const Cart = () => {
const { completeCheckout } = useCart()
// ...
const handleStartCheckout = () => {
startCheckout.mutate()
}
// ...
}
export default Cart
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/carts/${cartId}/complete`, { fetch(`<SERVER_URL>/store/carts/${cartId}/complete`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -1,7 +1,12 @@
---
description: 'Learn how to implement the order-claim flow in the storefront. This includes allowing customers to claim their orders, and verify a claim to an order.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
# How to Implement Claim Order Flow # How to Implement Claim Order Flow in Storefront
In this document, you’ll learn how to implement the claim order flow in a storefront to allow customers to claim their orders. In this document, you’ll learn how to implement the claim order flow in a storefront to allow customers to claim their orders.
@@ -44,10 +49,16 @@ It is also assumed you already have a storefront set up. It can be a custom stor
### JS Client ### JS Client
This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client and JavaScript’s Fetch API. This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
### Handle Order Claim Request Event ### Handle Order Claim Request Event
When the customer requests to claim the order, an event will be triggered. You should subscribe to this event to send a confirmation email to the customer when the event is triggered. When the customer requests to claim the order, an event will be triggered. You should subscribe to this event to send a confirmation email to the customer when the event is triggered.
@@ -71,7 +82,7 @@ To allow the customer to claim an order, send a request to the Claim an Order en
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```tsx ```ts
medusa.orders.claimOrders({ medusa.orders.claimOrders({
order_ids: [ order_ids: [
order_id, order_id,
@@ -88,7 +99,7 @@ medusa.orders.claimOrders({
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```tsx ```ts
fetch(`<SERVER_URL>/store/orders/batch/customer/token`, { fetch(`<SERVER_URL>/store/orders/batch/customer/token`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -129,7 +140,7 @@ Then, you send a request to the Verify Claim Order endpoint:
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```tsx ```ts
medusa.orders.confirmRequest({ medusa.orders.confirmRequest({
token, token,
}) })
@@ -142,9 +153,31 @@ medusa.orders.confirmRequest({
``` ```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="medusa-react" label="Medusa React">
```tsx ```tsx
import { useGrantOrderAccess } from "medusa-react"
const ClaimOrder = () => {
const grantOrderAccess = useGrantOrderAccess()
// ...
const handleVerifyOrderClaim = (token: string) => {
grantOrderAccess.mutate(({
token,
}))
}
// ...
}
export default ClaimOrder
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<SERVER_URL>/store/orders/customer/confirm`, { fetch(`<SERVER_URL>/store/orders/customer/confirm`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -1,3 +1,8 @@
---
description: 'Learn how to implement discount functionalities in your storefront using the REST APIs. This includes adding a discount to the cart, showing the discount details, and removing the discount from the cart.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -33,10 +38,18 @@ It is also assumed you already have a storefront set up. It can be a custom stor
### JS Client ### JS Client
This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client and JavaScript’s Fetch API. This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
It's also assumed you already have [used CartProvider higher in your component tree](../../medusa-react/overview.md#cartprovider).
### Previous Steps ### Previous Steps
This document assumes you’ve already taken care of the add-to-cart flow. So, you should have a [cart created](/api/store/#tag/Cart/operation/PostCart) for the customer with at least [one product in it](/api/store/#tag/Cart/operation/PostCartsCartLineItems). This document assumes you’ve already taken care of the add-to-cart flow. So, you should have a [cart created](/api/store/#tag/Cart/operation/PostCart) for the customer with at least [one product in it](/api/store/#tag/Cart/operation/PostCartsCartLineItems).
@@ -54,7 +67,7 @@ You can add a discount to a customer’s cart by sending the [Update Cart reques
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.update(cartId, { medusa.carts.update(cartId, {
discounts: [ discounts: [
{ {
@@ -71,10 +84,37 @@ medusa.carts.update(cartId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
const Cart = () => {
// ...
const { updateCart } = useCart()
const addDiscount = (code: string) => {
updateCart.mutate({
discounts: [
{
code,
},
],
})
}
// ...
}
export default Cart
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/carts/${cartId}`, { fetch(`<SERVER_URL>/store/carts/${cartId}`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -218,7 +258,7 @@ You can remove a discount from a customer’s cart using the [Remove Discount re
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.deleteDiscount(cartId, code) medusa.carts.deleteDiscount(cartId, code)
.then(({ cart }) => { .then(({ cart }) => {
console.log(cart.discounts) console.log(cart.discounts)
@@ -228,7 +268,7 @@ medusa.carts.deleteDiscount(cartId, code)
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/carts/${cartId}/discounts/${code}`, { fetch(`<SERVER_URL>/store/carts/${cartId}/discounts/${code}`, {
method: "DELETE", method: "DELETE",
credentials: "include", credentials: "include",
@@ -1,3 +1,8 @@
---
description: 'Learn how to implement gift-card related functionalities in your storefront using the REST APIs. This includes showing the gift card to customers and redeeming the gift card during checkout.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -29,10 +34,18 @@ It is also assumed you already have a storefront set up. It can be a custom stor
### JS Client ### JS Client
This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client and JavaScript’s Fetch API. This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
For requests that use the cart, it's also assumed you already have [used CartProvider higher in your component tree](../../medusa-react/overview.md#cartprovider).
### Previous Steps ### Previous Steps
To use gift cards, you must have a gift card created first. You can follow this documentation to learn how to do it using the admin APIs. To use gift cards, you must have a gift card created first. You can follow this documentation to learn how to do it using the admin APIs.
@@ -64,6 +77,36 @@ medusa.products.list({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { Product } from "@medusajs/medusa"
import { useProducts } from "medusa-react"
const GiftCard = () => {
const { products, isLoading } = useProducts({
is_giftcard: true,
})
return (
<div>
{isLoading && <span>Loading...</span>}
{products && products.length > 0 && (
<ul>
{products.map((product: Product) => (
<li key={product.id}>{product.title}</li>
))}
</ul>
)}
{products && !products.length && <span>No Gift Cards</span>}
</div>
)
}
export default GiftCard
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -118,6 +161,27 @@ medusa.giftCards.retrieve(code)
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useGiftCard } from "medusa-react"
const GiftCard = () => {
const { gift_card, isLoading, isError } = useGiftCard("code")
return (
<div>
{isLoading && <span>Loading...</span>}
{gift_card && <span>{gift_card.value}</span>}
{isError && <span>Gift Card does not exist</span>}
</div>
)
}
export default GiftCard
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -178,6 +242,33 @@ medusa.carts.update(cartId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
const Cart = () => {
// ...
const { updateCart } = useCart()
const setGiftCard = (code: string) => {
updateCart.mutate({
gift_cards: [
{
code,
},
],
})
}
// ...
}
export default Cart
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -1,3 +1,8 @@
---
description: 'Learn how to implement region-related functionalities on your storefront using the REST APIs. This includes showing the customer available regions, showing product prices, and setting the region of a cart.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -29,10 +34,18 @@ It is also assumed you already have a storefront set up. It can be a custom stor
### JS Client ### JS Client
This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client and JavaScript’s Fetch API. This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
For requests that use the cart, it's also assumed you already have [used CartProvider higher in your component tree](../../medusa-react/overview.md#cartprovider).
--- ---
## Show List of Regions ## Show List of Regions
@@ -44,7 +57,7 @@ You can retrieve available regions by sending a request to the [List Regions](/a
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```tsx ```ts
medusa.regions.list() medusa.regions.list()
.then(({ regions }) => { .then(({ regions }) => {
console.log(regions.length) console.log(regions.length)
@@ -53,9 +66,38 @@ medusa.regions.list()
``` ```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="medusa-react" label="Medusa React">
```tsx ```tsx
import { Region } from "@medusajs/medusa"
import { useRegions } from "medusa-react"
const Regions = () => {
const { regions, isLoading } = useRegions()
return (
<div>
{isLoading && <span>Loading...</span>}
{regions?.length && (
<ul>
{regions.map((region: Region) => (
<li key={region.id}>
{region.name}
</li>
))}
</ul>
)}
</div>
)
}
export default Regions
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<SERVER_URL>/store/regions`, { fetch(`<SERVER_URL>/store/regions`, {
credentials: "include", credentials: "include",
}) })
@@ -84,7 +126,7 @@ For example:
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```tsx ```ts
medusa.products.list({ medusa.products.list({
region_id: regionId, region_id: regionId,
}) })
@@ -95,9 +137,32 @@ medusa.products.list({
``` ```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="medusa-react" label="Medusa React">
```tsx ```tsx
import { formatVariantPrice } from "medusa-react"
const Product = () => {
// retrieve the region and variant(s)
// ...
return (
<span>
{formatVariantPrice({
variant, // ProductVariant
region, // Region
})}
</span>
)
}
export default Product
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<SERVER_URL>/store/products?region_id=${regionId}`, { fetch(`<SERVER_URL>/store/products?region_id=${regionId}`, {
credentials: "include", credentials: "include",
}) })
@@ -134,7 +199,7 @@ For example:
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```tsx ```ts
medusa.carts.update(cartId, { medusa.carts.update(cartId, {
region_id: regionId, region_id: regionId,
}) })
@@ -144,9 +209,32 @@ medusa.carts.update(cartId, {
``` ```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="medusa-react" label="Medusa React">
```tsx ```tsx
import { useCart } from "medusa-react"
const Cart = () => {
// ...
const { updateCart } = useCart()
const changeRegionId = (region_id: string) => {
updateCart.mutate({
region_id,
})
}
// ...
}
export default Cart
```
</TabItem>
<TabItem value="fetch" label="Fetch API">
```ts
fetch(`<SERVER_URL>/store/carts/${cartId}`, { fetch(`<SERVER_URL>/store/carts/${cartId}`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -1,3 +1,8 @@
---
description: 'Learn how to implement sales channel functionalities in the storefront using REST APIs. This includes filtering products by Sales Channel and associating a cart with a sales channel.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -32,10 +37,18 @@ It is also assumed you already have a storefront set up. It can be a custom stor
### JS Client ### JS Client
This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client and JavaScript’s Fetch API. This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../medusa-react/overview.md#usage).
For requests that use the cart, it's also assumed you already have [used CartProvider higher in your component tree](../../medusa-react/overview.md#cartprovider).
--- ---
## Filter Products by Sales Channel ## Filter Products by Sales Channel
@@ -45,7 +58,7 @@ To filter products by a specific sales channel, pass the `sales_channel_id` quer
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.products.list({ medusa.products.list({
sales_channel_id: [ sales_channel_id: [
salesChannelId, salesChannelId,
@@ -56,10 +69,42 @@ medusa.products.list({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { Product } from "@medusajs/medusa"
import { useProducts } from "medusa-react"
const Products = () => {
const { products, isLoading } = useProducts({
sales_channel_id: [
salesChannelId,
],
})
return (
<div>
{isLoading && <span>Loading...</span>}
{products && products.length > 0 && (
<ul>
{products.map((product: Product) => (
<li key={product.id}>{product.title}</li>
))}
</ul>
)}
{products && !products.length && <span>No Products</span>}
</div>
)
}
export default Products
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/products?sales_channel_id[0]=${salesChannelId}`) fetch(`<SERVER_URL>/store/products?sales_channel_id[0]=${salesChannelId}`)
.then((response) => response.json()) .then((response) => response.json())
.then(({ products, limit, offset, count }) => { .then(({ products, limit, offset, count }) => {
@@ -86,7 +131,7 @@ To associate a sales channel with a cart while creating it, you can pass the `sa
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.create({ medusa.carts.create({
sales_channel_id: salesChannelId, sales_channel_id: salesChannelId,
}) })
@@ -95,10 +140,36 @@ medusa.carts.create({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
const Cart = () => {
const { cart, createCart } = useCart()
const handleCreateCart = () => {
createCart.mutate(
{
sales_channel_id: salesChannelId,
},
{
onSuccess: ({ cart }) => localStorage.setItem("cart_id", cart.id),
}
)
}
// ...
}
export default Cart
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/carts`, { fetch(`<SERVER_URL>/store/carts`, {
method: "POST", method: "POST",
headers: { headers: {
@@ -126,7 +197,7 @@ You can update the sales channel of an existing cart by passing the `sales_chann
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.update(cartId, { medusa.carts.update(cartId, {
sales_channel_id: salesChannelId, sales_channel_id: salesChannelId,
}) })
@@ -135,10 +206,33 @@ medusa.carts.update(cartId, {
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
const Cart = () => {
// ...
const { updateCart } = useCart()
const changeSalesChannel = (salesChannelId: string) => {
updateCart.mutate({
sales_channel_id: salesChannelId,
})
}
// ...
}
export default Cart
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/carts/${cartId}`, { fetch(`<SERVER_URL>/store/carts/${cartId}`, {
method: "POST", method: "POST",
headers: { headers: {
+4
View File
@@ -1,3 +1,7 @@
---
description: 'Learn how to install the Medusa CLI Tool. Medusa CLI Tool can be used to perform actions such as create a new Medusa server, run migrations, create a new admin user, and more.'
---
# CLI Reference # CLI Reference
This document serves as a reference to the Medusa CLI tool including how to install it and what commands are available. This document serves as a reference to the Medusa CLI tool including how to install it and what commands are available.
@@ -1,5 +1,6 @@
--- ---
description: 'Learn step-by-step.' description: 'Learn step-by-step.'
addHowToData: true
--- ---
# Deploy Medusa Admin on Netlify # Deploy Medusa Admin on Netlify
+1
View File
@@ -1,5 +1,6 @@
--- ---
hide_table_of_contents: true hide_table_of_contents: true
description: 'Learn how to deploy the Medusa Admin to different hosting providers to be used with a deployed Medusa server.'
--- ---
import DocCardList from '@theme/DocCardList'; import DocCardList from '@theme/DocCardList';
@@ -1,5 +1,6 @@
--- ---
description: 'Learn step-by-step.' description: 'Learn step-by-step.'
addHowToData: true
--- ---
# Deploy Your Medusa Server to DigitalOcean Apps # Deploy Your Medusa Server to DigitalOcean Apps
@@ -1,5 +1,6 @@
--- ---
description: 'Learn step-by-step.' description: 'Learn step-by-step.'
addHowToData: true
--- ---
import styles from '../deployment.module.css'; import styles from '../deployment.module.css';
@@ -1,5 +1,6 @@
--- ---
description: 'Learn step-by-step.' description: 'Learn step-by-step.'
addHowToData: true
--- ---
# Deploy Your Medusa Server on Qovery # Deploy Your Medusa Server on Qovery
@@ -1,5 +1,6 @@
--- ---
description: 'Learn step-by-step.' description: 'Learn step-by-step.'
addHowToData: true
--- ---
# Deploy Your Medusa Server to Railway # Deploy Your Medusa Server to Railway
@@ -1,5 +1,6 @@
--- ---
hide_table_of_contents: true hide_table_of_contents: true
description: 'Learn how to deploy your Medusa server to different hosting providers including DigitalOcean, Heroku, Railway, and more.'
--- ---
import DocCardList from '@theme/DocCardList'; import DocCardList from '@theme/DocCardList';
@@ -1,5 +1,6 @@
--- ---
description: 'Learn step-by-step.' description: 'Learn step-by-step.'
addHowToData: true
--- ---
# Deploy Gatsby Storefront on Netlify # Deploy Gatsby Storefront on Netlify
@@ -1,5 +1,6 @@
--- ---
hide_table_of_contents: true hide_table_of_contents: true
description: 'Learn how to deploy your storefronts to different hosting providers to be used with a deployed Medusa server.'
--- ---
import DocCardList from '@theme/DocCardList'; import DocCardList from '@theme/DocCardList';
+233 -19
View File
@@ -1,3 +1,8 @@
---
description: 'Learn how to implement the cart functionality in your storefront using the REST APIs. This includes creating a cart, updating a cart, adding products to the cart, and more.'
addHowToData: true
---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -17,10 +22,6 @@ This document does not cover implementing the checkout flow. You can refer to [t
::: :::
### Glossary
- **Line Item**: When products are added to the cart in Medusa, they are referred to as line items. Line items have, by default, the same properties and attributes as a product. However, you can customize line items specifically for a cart if necessary.
--- ---
## Prerequisites ## Prerequisites
@@ -33,10 +34,18 @@ It is also assumed you already have a storefront set up. It can be a custom stor
### JS Client ### JS Client
This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client and JavaScript’s Fetch API. This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
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). 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).
### Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../medusa-react/overview.md#usage).
It's also assumed you already have [used CartProvider higher in your component tree](../medusa-react/overview.md#cartprovider).
--- ---
## Create a Cart ## Create a Cart
@@ -46,7 +55,7 @@ You can create a cart with the following code snippet:
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.create() medusa.carts.create()
.then(({ cart }) => { .then(({ cart }) => {
localStorage.setItem("cart_id", cart.id) localStorage.setItem("cart_id", cart.id)
@@ -55,10 +64,34 @@ medusa.carts.create()
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
const Cart = () => {
const { cart, createCart } = useCart()
const handleCreateCart = () => {
createCart.mutate(
{}, // create an empty cart
{
onSuccess: ({ cart }) => localStorage.setItem("cart_id", cart.id),
}
)
}
// ...
}
export default Cart
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/carts`, { fetch(`<SERVER_URL>/store/carts`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -94,6 +127,32 @@ medusa.carts.create({
}) })
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
const Cart = () => {
const { cart, createCart } = useCart()
const handleCreateCart = () => {
createCart.mutate(
{
region_id,
},
{
onSuccess: ({ cart }) => localStorage.setItem("cart_id", cart.id),
}
)
}
// ...
}
export default Cart
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -138,7 +197,7 @@ You can retrieve the cart at any given point using its ID with the following cod
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
const id = localStorage.getItem("cart_id") const id = localStorage.getItem("cart_id")
if (id) { if (id) {
@@ -147,10 +206,25 @@ if (id) {
} }
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React" default>
```tsx
import { useGetCart } from "medusa-react"
const Cart = () => {
const { cart, isLoading } = useGetCart(cart_id)
// ...
}
export default Cart
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
const id = localStorage.getItem("cart_id") const id = localStorage.getItem("cart_id")
if (id) { if (id) {
@@ -186,17 +260,40 @@ You can use the following snippet to update any of the cart’s data:
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.update(cartId, { medusa.carts.update(cartId, {
region_id, region_id,
}) })
.then(({ cart }) => setCart(cart)) .then(({ cart }) => setCart(cart))
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
const Cart = () => {
// ...
const { updateCart } = useCart()
const changeRegionId = (region_id: string) => {
updateCart.mutate({
region_id,
})
}
// ...
}
export default Cart
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/carts/${cartId}`, { fetch(`<SERVER_URL>/store/carts/${cartId}`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -229,17 +326,40 @@ You can do that using the same update operation:
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.update(cartId, { medusa.carts.update(cartId, {
customer_id, customer_id,
}) })
.then(({ cart }) => setCart(cart)) .then(({ cart }) => setCart(cart))
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
const Cart = () => {
// ...
const { updateCart } = useCart()
const changeCustomerId = (customer_id: string) => {
updateCart.mutate({
customer_id,
})
}
// ...
}
export default Cart
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/carts/${cartId}`, { fetch(`<SERVER_URL>/store/carts/${cartId}`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -268,17 +388,40 @@ You can do that using the same update operation:
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.update(cartId, { medusa.carts.update(cartId, {
email: "user@example.com", email: "user@example.com",
}) })
.then(({ cart }) => setCart(cart)) .then(({ cart }) => setCart(cart))
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCart } from "medusa-react"
const Cart = () => {
// ...
const { updateCart } = useCart()
const changeEmail = (email: string) => {
updateCart.mutate({
email,
})
}
// ...
}
export default Cart
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/carts/${cartId}`, { fetch(`<SERVER_URL>/store/carts/${cartId}`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -313,6 +456,30 @@ medusa.carts.lineItems.create(cartId, {
.then(({ cart }) => setCart(cart)) .then(({ cart }) => setCart(cart))
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useCreateLineItem } from "medusa-react"
const Cart = () => {
// ...
const createLineItem = useCreateLineItem(cart_id)
const handleAddItem = () => {
createLineItem.mutate({
variant_id,
quantity,
})
}
// ...
}
export default Cart
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
@@ -356,17 +523,41 @@ To update a line item's quantity in the cart, you can use the following code sni
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.lineItems.update(cartId, lineItemId, { medusa.carts.lineItems.update(cartId, lineItemId, {
quantity: 3, quantity: 3,
}) })
.then(({ cart }) => setCart(cart)) .then(({ cart }) => setCart(cart))
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useUpdateLineItem } from "medusa-react"
const Cart = () => {
// ...
const updateLineItem = useUpdateLineItem(cart_id)
const handleUpdateItem = () => {
updateLineItem.mutate({
lineId,
quantity: 3,
})
}
// ...
}
export default Cart
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/carts/${cartId}/line-items/${lineItemId}`, { fetch(`<SERVER_URL>/store/carts/${cartId}/line-items/${lineItemId}`, {
method: "POST", method: "POST",
credentials: "include", credentials: "include",
@@ -397,15 +588,38 @@ To delete a line item from the cart, you can use the following code snippet:
<Tabs groupId="request-type" wrapperClassName="code-tabs"> <Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default> <TabItem value="client" label="Medusa JS Client" default>
```jsx ```ts
medusa.carts.lineItems.delete(cartId, lineItemId) medusa.carts.lineItems.delete(cartId, lineItemId)
.then(({ cart }) => setCart(cart)) .then(({ cart }) => setCart(cart))
``` ```
</TabItem>
<TabItem value="medusa-react" label="Medusa React">
```tsx
import { useDeleteLineItem } from "medusa-react"
const Cart = () => {
// ...
const deleteLineItem = useDeleteLineItem(cart_id)
const handleDeleteItem = () => {
deleteLineItem.mutate({
lineId,
})
}
// ...
}
export default Cart
```
</TabItem> </TabItem>
<TabItem value="fetch" label="Fetch API"> <TabItem value="fetch" label="Fetch API">
```jsx ```ts
fetch(`<SERVER_URL>/store/carts/${cartId}/line-items/${lineItemId}`, { fetch(`<SERVER_URL>/store/carts/${cartId}/line-items/${lineItemId}`, {
method: "DELETE", method: "DELETE",
credentials: "include", credentials: "include",
+1 -1
View File
@@ -1,7 +1,7 @@
--- ---
id: homepage id: homepage
title: Medusa Documentation title: Medusa Documentation
description: "Get an overview of Medusa's features, integrations, and how to use them." description: "Medusa is an open source composable commerce platform. Learn about its features and how to use it."
slug: / slug: /
hide_table_of_contents: true hide_table_of_contents: true
hide_footer: true hide_footer: true
Loaded 100 of 196 files, more files were not shown because too many files have changed in this diff. Show more