docs: create docs workspace (#5174)

* docs: migrate ui docs to docs universe

* created yarn workspace

* added eslint and tsconfig configurations

* fix eslint configurations

* fixed eslint configurations

* shared tailwind configurations

* added shared ui package

* added more shared components

* migrating more components

* made details components shared

* move InlineCode component

* moved InputText

* moved Loading component

* Moved Modal component

* moved Select components

* Moved Tooltip component

* moved Search components

* moved ColorMode provider

* Moved Notification components and providers

* used icons package

* use UI colors in api-reference

* moved Navbar component

* used Navbar and Search in UI docs

* added Feedback to UI docs

* general enhancements

* fix color mode

* added copy colors file from ui-preset

* added features and enhancements to UI docs

* move Sidebar component and provider

* general fixes and preparations for deployment

* update docusaurus version

* adjusted versions

* fix output directory

* remove rootDirectory property

* fix yarn.lock

* moved code component

* added vale for all docs MD and MDX

* fix tests

* fix vale error

* fix deployment errors

* change ignore commands

* add output directory

* fix docs test

* general fixes

* content fixes

* fix announcement script

* added changeset

* fix vale checks

* added nofilter option

* fix vale error
This commit is contained in:
Shahed Nasser
2023-09-21 20:57:15 +03:00
committed by GitHub
parent 19c5d5ba36
commit fa7c94b4cc
3209 changed files with 32188 additions and 31018 deletions

View File

@@ -0,0 +1,7 @@
import DocCardList from '@theme/DocCardList';
# Analytics Plugins
If you can't find your analytics provider, try checking the [Community Plugins Library](https://medusajs.com/plugins/?filters=Analytics&categories=Analytics).
<DocCardList />

View File

@@ -0,0 +1,211 @@
---
description: 'Learn how to integrate Segment with the Medusa backend. Learn how to add custom tracking with Segment and Medusa.'
addHowToData: true
---
# Segment
In this document, youll 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.
## Overview
[Segment](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-segment) is a powerful Customer Data Platform that allows users to collect, transform, send and archive their customer data.
Segment allows users to manage different tracking and marketing tools using one API and interface, making it very simple to try out and integrate with different services in your ecommerce stack.
Common integration use cases that can be implemented with Segment include:
- Google Analytics
- Mailchimp
- Zendesk
- Data warehousing for advanced data analytics and segmentation through services like Snowflake
The Segment plugin in Medusa allows you to track ecommerce events and record them in Segment. Then, you can push these events to other destinations using Segment.
### Events That the Segment Plugin Tracks
By default, the Segment plugin tracks the following events:
1. `order.placed`: Triggered when an order is placed.
2. `order.shipment_created`: Triggered when a shipment is created for an order.
3. `claim.created`: Triggered when a new claim is created.
4. `order.items_returned`: Triggered when an item in an order is returned.
5. `order.canceled`: Triggered when an order is canceled.
6. `swap.created`: Triggered when a swap is created.
7. `swap.shipment_created`: Triggered when a shipment is created for a swap.
8. `swap.payment_completed`: Triggered when payment for a swap is completed.
:::tip
Check out the [Event Reference](../../development/events/events-list.md) to learn about all available events in Medusa.
:::
---
## Prerequisites
### Medusa Backend
It is assumed you already have a Medusa backend installed. If not, please follow the [Quickstart guide](../../development/backend/install.mdx) to get started in minutes. The Medusa backend must also have an event bus module installed, which is available when using the default Medusa starter.
### Segment Account
You need to [create a Segment account](https://app.segment.com/signup/) to follow along with the tutorial. Segment offers a free plan to get started quickly.
---
## Create a Segment Source
On your Segment dashboard, choose Catalog from the sidebar under Connections.
![Under Connections in the sidebar choose Catalog](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000661/Medusa%20Docs/Segment/rAeJkP3_ybyutz.png)
Then, in the catalog list find the Backend category and choose Node.js from the list.
![Choose Node.js under the Backend category](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000672/Medusa%20Docs/Segment/6RxQbW6_wjphte.png)
This opens a new side menu. In the side menu, click on Add Source.
![Click on Add Source in the side menu showing information about the Node.js source](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000683/Medusa%20Docs/Segment/0VZJnpd_ehagat.png)
This opens a new page to create a Node.js source. Enter the name of the source then click Add Source.
![Enter a name under the Name field then click on the Add Source button](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000693/Medusa%20Docs/Segment/u2hzkB5_t59yhj.png)
On the new source dashboard, you should find a Write Key. Youll use this key in the next section after you install the Segment plugin on your Medusa backend.
![The Write Key is available on the new source's page](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000708/Medusa%20Docs/Segment/OTJVsz7_v95qla.png)
### Optional: Add Destination
After you create the Segment source, you can add destinations. This is where the data is sent when you send them to Segment. You can add more than one destination.
To add a destination, on the same Segment source page, click on Add Destination in the Destinations section.
![Click on the Add Destination button on the source page](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000718/Medusa%20Docs/Segment/FrKlUxh_zlnkww.png)
You can then choose from a list of destinations such as Google Universal Analytics or Facebook Pixel.
![List of some of the available destinations in Segment's catalog](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000730/Medusa%20Docs/Segment/y2YnPUh_mgfqdo.png)
The process of integrating each destination is different, so you must follow the steps detailed in Segment for each destination you choose.
---
## Install the Segment Plugin
In the directory of your Medusa backend, run the following command to install the Segment plugin:
```bash npm2yarn
npm install medusa-plugin-segment
```
Then, add the following environment variable:
```bash
SEGMENT_WRITE_KEY=<YOUR_SEGMENT_WRITE_KEY>
```
Where `<YOUR_SEGMENT_WRITE_KEY>` is the Write Key shown on the page of the Segment source you created in the previous section.
Finally, in `medusa-config.js`, add the following new item to the `plugins` array:
```jsx title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-plugin-segment`,
options: {
write_key: process.env.SEGMENT_WRITE_KEY,
},
},
]
```
---
## Test the Plugin
Run your backend with the following command:
```bash
npx medusa develop
```
Then, try triggering one of the [mentioned events earlier in this document](#events-that-the-segment-plugin-tracks). For example, you can place an order either using the [REST APIs](https://docs.medusajs.com/api/store) or using the [Next.js Starter Template](../../starters/nextjs-medusa-starter.mdx).
After you place an order, on the Segment source that you created, click on the Debugger tab. You should see at least one event triggered for each order you place. If you click on the event, you can see the order details are passed to the event.
![The order completed event is recorded on the Segment source](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000743/Medusa%20Docs/Segment/LQVJTGg_i5jyge.png)
If you added a destination, you can also check your destination to make sure the data is reflected there.
:::note
If the data is not appearing on the destination, the issue is related to your configuration between the Segment source and destination and not related to the Segment plugin. Go over the steps that Segment showed you when you added the destination to figure out the issue.
:::
---
## Add Custom Tracking
In some cases, you might want to track more events or custom events. You can do that using the `SegmentService` provided by the Segment Plugin.
For example, you can add the following subscriber to listen to the `customer.created` event and add tracking for every customer created:
```jsx title=src/subscribers/customer.ts
class CustomerSubscriber {
constructor({ segmentService, eventBusService }) {
this.segmentService = segmentService
eventBusService.subscribe(
"customer.created",
this.handleCustomer
)
}
handleCustomer = async (data) => {
const customerData = data
delete customerData["password_hash"]
this.segmentService.track({
event: "Customer Created",
userId: data.id,
properties: customerData,
})
}
}
export default CustomerSubscriber
```
You resolve the `SegmentService` using dependency injection. Then, when the `customer.created` event is triggered, you use the `track` method available in the `SegmentService` to send tracking data to Segment.
:::info
Services can be resolved and used in Subscribers, endpoints, and other Services. Learn [how to resolve services in the Services documentation](../../development/services/create-service.mdx#using-your-custom-service).
:::
`track` accepts an object of data, where the keys `event` and `userId` are required. Instead of `userId`, you can use `anonymousId` to pass an anonymous user ID.
If you want to pass additional data to Segment, pass them under the `properties` object key.
The `SegmentService` also provides the method `identify` to tie a user to their actions or specific traits.
### Test Custom Tracking
After adding the above subscriber, run your backend again if it isnt running and create a customer using the REST APIs or one of the Medusa storefronts. If you check the Debugger in your Segment source, you should see a new event “Customer Created” tracked. If you click on it, youll see the data you passed to the `track` method.
![The customer created event is recorded on the Segment source](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000759/Medusa%20Docs/Segment/4LD41xE_qungdw.png)
---
## See Also
- [Services Overview](../../development/services/create-service.mdx)
- [Subscribers Overview](../../development/events/create-subscriber.md)
- [Events Reference](../../development/events/events-list.md)
- [Deploy the Medusa backend](../../deployments/server/index.mdx)

View File

@@ -0,0 +1,335 @@
---
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
In this document, youll learn how to customize the Contentful integration with Medusa and how to customize the Gatsby storefront that is connected to Contentful.
:::warning
This guide covers how to customize the Gatsby storefront which is now deprecated. It's recommended to integrate Contentful into either the Next.js Starter Template or your custom storefront.
:::
## Overview
Part of what makes the integration between Medusa and Contentful powerful is that its completely customizable.
On the backend, you can create Contentful migrations that allow you to add or edit Content Types in Contentful. Although this can be done through Contentfuls interface, this solution allows you to create a reusable codebase for your store that is independent of a specific Contentful Space.
On your storefront, you can add any necessary components that can render the Content Types you create.
As an example to explain this process, in this documentation, youll create a migration that creates a Rich Text content model in Contentful and edits the Page and Product content models to allow using Rich Text content as a tile in pages and products. Then, youll modify the Gatsby storefront to render the Rich Text content model.
---
## Prerequisites
Its assumed you already have set up a Medusa backend integrated with Contentful and have a Gatsby storefront integrated with Contentful. If not, [please follow this documentation first](index.md).
---
## Create a Contentful Migration
The Contentful migrations are located in the `contentful-migrations` directory in the Medusa Contentful backend starter. So, if you want to create your own Contentful migrations, you can create them under that directory.
Heres an example of a migration created in a new file `contentful-migrations/rich-text.js`:
```jsx title=contentful-migrations/rich-text.js
#! /usr/bin/env node
require("dotenv").config()
const { runMigration } = require("contentful-migration")
const options = {
spaceId: process.env.CONTENTFUL_SPACE_ID,
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
environment: process.env.CONTENTFUL_ENVIRONMENT,
yes: true,
}
const migration = async () => {
await runMigration({
...options,
migrationFunction: function (migration, context) {
// create Rich Text content model
const richText = migration
.createContentType("richText")
.name("Rich Text")
.displayField("title")
richText
.createField("title")
.name("Title (Internal)")
.type("Symbol")
richText
.createField("body")
.name("Body")
.type("RichText")
// edit Page content model
const page = migration.editContentType("page")
page.editField("contentModules").items({
type: "Link",
linkType: "Entry",
validations: [
{
linkContentType: [
"hero", "tileSection", "richText",
],
},
],
})
// edit Product content model
const product = migration.editContentType("product")
product
.createField("contentModules")
.name("Content Modules")
.type("Array")
.items({
type: "Link",
linkType: "Entry",
validations: [
{
linkContentType: ["richText"],
},
],
})
},
})
}
migration()
```
This example creates a new content model Rich Text that has two fields: title and body. It also edits the Page content model to allow using Rich Text content models on the page.
In addition, it edits the Product content model by adding a new field `contentModules`. This field accepts an array of sections that can be of type Rich Text. This allows you to display rich details on a product page.
You can also add other types of content models the `contentModules` should accept. For example, to accept `tileSection` add it to the `linkContentType` option:
```jsx
product
.createField("contentModules")
.name("Content Modules")
.type("Array")
.items({
type: "Link",
linkType: "Entry",
validations: [
{
linkContentType: ["richText", "tileSection"],
},
],
})
```
### Run a Contentful Migration
To run a Contentful Migration that you create you can use the following command:
```bash
node <file_path>
```
Where `<file_path>` is the path of the file you created.
To run the Contentful migration in the previous example, you can use the following command:
```bash
node contentful-migrations/rich-text.js
```
This runs the Contentful migration in that file and makes the necessary changes in your Contentful Space.
### Test if Contentful Migration Worked
To check if the above migration worked, in your Contentful Space dashboard go to Content Models from the navigation bar. You should see the new content model Rich Text.
The above migration also allows you to add Rich Text content to pages. To test this out:
1. Go to Content from the navigation bar.
2. Choose Page in the select field next to the search bar. This shows the available pages in your Contentful Space.
3. Choose one of the pages. For example, the About page.
4. Scroll down to the Add content button. If you click on it, you should be able to choose Rich Text under New Content.
5. Click on Rich Text and a new form will open to create new Rich Text content. It has the same fields that you defined in the migration file.
6. After adding the content you want, click on the Publish button on the right then go back to the About page editor.
7. Similarly, in the About page editor, click on the Publish Changes button on the right to view these changes later in the storefront.
8. Similarly, you can add Rich Text content to any product page.
---
## Render New Content Models in the Storefront
After creating a new content model in your Contentful Space, you must add the necessary component to render it in your Gatsby storefront.
### Create Component
To render the Rich Text content you created in the previous example, create the file `src/components/rich-text/rich-text.js` with the following content:
```jsx title=src/components/rich-text/rich-text.js
import React from "react"
import {
renderRichText,
} from "gatsby-source-contentful/rich-text"
const RichText = ({ data }) => {
return (
<div style={{
maxWidth: "870px",
margin: "0 auto",
paddingTop: "20px",
paddingBottom: "20px",
}}>
{data.body ? renderRichText(data.body) : ""}
</div>
)
}
export default RichText
```
This creates the component `RichText` responsible for rendering the Rich Text content model. Notice that the fields of the content model are available under the `data` prop variable.
### Render Component in a Page
Since the Rich Text model can be added to any page, you must edit `src/pages/{ContentfulPage.slug}.js` to show it.
In `src/pages/{ContentfulPage.slug}.js`, import the `RichText` component at the top of the file:
```jsx title=src/pages/{ContentfulPage.slug}.js
import RichText from "../components/rich-text/rich-text"
```
Then, in the returned JSX add a new case to the switch statement:
```jsx title=src/pages/{ContentfulPage.slug}.js
switch (cm.internal.type) {
// ...
case "ContentfulRichText":
return <RichText key={cm.id} data={cm} />
default:
return null
}
```
If the content model of a tile is Rich Text, youll display it with the `RichText` component.
Finally, to retrieve all necessary data of the Rich Text content, in the `query` GraphQL variable add the following after the `... on ContentfulTileSection` fragment:
```jsx title=src/pages/{ContentfulPage.slug}.js
export const query = graphql`
# find the following line
... on ContentfulTileSection {
}
# add the following
... on ContentfulRichText {
id
body {
raw
}
internal {
type
}
}
}
}
}
`
```
### Test Rich Text in Page Content
To test this out, run your Medusa backend by running this command in its directory:
```bash npm2yarn
npx medusa develop
```
Then run the Gatsby storefront by running this command in its directory:
```bash npm2yarn
npm run start
```
This runs the Gatsby storefront on `localhost:8000`. Go to the storefront in your browser and open the About page. You should see the Rich Text content you added.
### Render Component in a Product Page
In the example migration, you also edited the product page to include a new Content Modules field that allows inserting Rich Text content.
To render them on the Product Page, add the following in the GraphQL query defined in the `query` variable inside `product`:
```jsx title=src/pages/{ContentfulPage.slug}.js
export const query = graphql`
query ($id: String!) {
product: contentfulProduct(id: { eq: $id }) {
# Other fields
contentModules {
... on ContentfulRichText {
id
body {
raw
}
internal {
type
}
}
}
}
}
`
```
:::note
If you added other accepted Content Models to the `contentModules` field of the Product content type, make sure to add them here.
:::
Then, in `src/views/product.js` import the `RichText` component:
```jsx title=src/views/product.js
import RichText from "../components/rich-text/rich-text"
```
And in the returned JSX add the following before the last `</div>`:
```jsx title=src/views/product.js
<div className={styles.contentModules}>
{product.contentModules?.map((cm) => {
switch (cm.internal.type) {
case "ContentfulRichText":
return <RichText key={cm.id} data={cm} />
default:
return null
}
})}
</div>
```
:::note
If you added other accepted Content Models to the `contentModules` field of the Product content type, make sure to add cases for them here to display them.
:::
This loops over `contentModules` and if the type of the content is Rich Text, it is rendered with the `RichText` component.
### Test Rich Text on a Product Page
Restart the Gatsby storefront then open a product that you added Rich Text content to. You should see the Rich Text component at the end of the page.
---
## See Also
- How to deploy your Medusa backend to [Heroku](../../../deployments/server/deploying-on-heroku.mdx), or [DigitalOcean](../../../deployments/server/deploying-on-digital-ocean.md), or [other providers](../../../deployments/server/index.mdx)

View File

@@ -0,0 +1,297 @@
---
description: 'Learn how to integrate Contentful with the Medusa backend and a Gatsby storefront. Contentful is a headless CMS backend that provides rich CMS functionalities.'
addHowToData: true
---
# Contentful
In this document, youll learn how to integrate a Medusa backend with Contentful to add rich Content Management System (CMS) functionalities
## Overview
[Contentful](https://www.contentful.com/) is a headless CMS service that allows developers to integrate rich CMS functionalities into any platform.
By integrating Contentful to Medusa, you can benefit from powerful features in your ecommerce store including detailed product CMS details, easy-to-use interface to use for static content and pages, localization, and much more.
---
## Prerequisites
### Needed Accounts
- [Contentful](https://www.contentful.com/sign-up/) account with a space created. A space is created by default when you create a new account.
### Required Tools
- PostgreSQL with an empty database created. You can follow [this documentation to learn how to install it for your operating system](../../../development/backend/prepare-environment.mdx#postgres).
- Redis. You can follow [their documentation to learn how to install it](https://redis.io/docs/getting-started/installation/).
- Gits CLI tool. You can follow [this documentation to learn how to install it for your operating system](../../../development/backend/prepare-environment.mdx#git).
- Gatsbys CLI tool. You can follow [this documentation to install it](https://www.gatsbyjs.com/docs/reference/gatsby-cli/#how-to-use-gatsby-cli).
- Medusas CLI tool. You can follow [this documentation to install it](../../../cli/reference.mdx#how-to-install-cli-tool).
---
## Install Medusa Backend Using Contentful Starter
Instead of using the default Medusa backend starter, you must use the [Contentful starter](https://github.com/medusajs/medusa-starter-contentful) to install a backend that is ready to be used with Contentful. This backend contains all the necessary files to make the integration work.
In your terminal, run the following command to install the backend:
```bash
npx @medusajs/medusa-cli@latest new medusa-contentful https://github.com/medusajs/medusa-starter-contentful
```
This installs a new Medusa backend in the directory `medusa-contentful`.
### Add Contentful Environment Variables
Change to the `medusa-contentful` directory. In `.env` youll find three variables:
```bash title=.env
CONTENTFUL_SPACE_ID=
CONTENTFUL_ACCESS_TOKEN=
CONTENTFUL_ENV=
```
#### Value of CONTENTFUL_ENV
Set the value for `CONTENTFUL_ENV` to `master`.
#### Value of CONTENTFUL_SPACE_ID
To retrieve the value of `CONTENTFUL_SPACE_ID`:
1. Go to your [Contentful Space dashboard](https://app.contentful.com/). Then, choose Settings in the navigation bar and select API keys from the dropdown.
2. On the APIs page, click Add API Key.
3. In the form, enter a name for the API key and click Save.
4. Copy the value of Space ID and set it as the value of `CONTENTFUL_SPACE_ID`.
#### Value of CONTENTFUL_ACCESS_TOKEN
To retrieve the value of `CONTENTFUL_ACCESS_TOKEN`:
1. Go back to the API Keys page and click on the Content management tokens tab.
2. Click on Generate personal token.
3. In the pop-up that opens, enter a name for the token.
4. Click the Generate button. A personal access token will be generated. Use it to set the value of `CONTENTFUL_ACCESS_TOKEN`.
:::warning
Once you close the pop-up, you wont be able to get the value of the personal access token again. Make sure to copy it first.
:::
### Configure Redis
In `.env` set the value of your Redis URL:
```bash
REDIS_URL=<YOUR_REDIS_URL>
```
Where `<YOUR_REDIS_URL>` is the URL of your Redis service.
:::tip
The default Redis URL is `redis://localhost:6379`.
:::
### Configure PostgreSQL
In `.env` set the value of your PostgreSQL URL:
```bash
DATABASE_URL=<YOUR_DB_URL>
```
Where `<YOUR_DB_URL>` is the URL of your PostgreSQL database.
:::tip
You can find the format of the PostgreSQL database URL in [PostgreSQLs documentation](https://www.postgresql.org/docs/current/libpq-connect.html).
:::
Then, in `medusa-config.js` in the exported object, add the PostgreSQL database configurations:
```jsx title=medusa-config.js
module.exports = {
projectConfig: {
// ...
database_url: DATABASE_URL,
database_type: "postgres",
},
}
```
### Migrate Content Types to Contentful
The Contentful starter provides the necessary scripts to create content types in your Contentful space.
Run the following commands to migrate the content types into Contentful:
```bash
npm run migrate:contentful
```
Once this command finishes executing, in your Contentful Space dashboard click on Content Model in the navigation bar. You should see a list of new content models added.
### Seed Content to Contentful
The next step is to seed the Contentful Space with some content data.
Run the following command to seed some data into it:
```bash
npm run seed:contentful
```
After this command finishes running, in your Contentful Space dashboard click on Content in the navigation bar. You should see a list of new content added.
### (Optional) Seed Medusa Database
This step seeds your Medusa database with demo data to easily add products as well as other data to your Medusa backend.
Run the following command to seed the Medusa database:
```bash
npm run seed
```
### Start the Backend
To start the backend run the following command:
```bash
npx medusa develop
```
If you seeded the database with demo data, you should see that events related to the products are triggered.
The Contentful integration ensures a sync between the Medusa backend and Contentful. So, when new products are added to Medusa, these products will be added to your Contentful Space as well.
---
## (Optional) Add Products with the Medusa Admin
Using the Medusa admin, you can add products to your Medusa backend. This will trigger product events that subsequently add these products to Contentful.
---
## (Optional) Two-way Sync with Contentful
This section explains how you can establish a two-way sync between Medusa and Contentful. This would ensure that not only is the data updated from the Medusa backend to Contentful, but also ensure the updates are relayed from Contentful to the Medusa backend.
However, to perform this sync, it's required that you deploy your backend so that it can be publicly accessible. You can learn how to do that through the [backend deployment](../../../deployments/server/index.mdx) guides.
Configuring two-way sync requires configuring Webhooks in Contentful. To do that:
1. On your Contentful Space Dashboard, click on Settings from the navigation bar, then choose Webhooks.
2. Click on the Add Webhook button.
3. In the form, enter a name for the webhook.
4. In the URL field, choose the method `POST` and in the input next to it enter the URL `<BACKEND_URL>/hooks/contentful` where `<BACKEND_URL>` is the URL of your production Medusa backend.
5. Scroll down to find the Content Type select field. Choose `application/json` as its value.
6. You can leave the rest of the fields the same and click on the Save button.
Now, every time you change a products data on your Contentful Space it will be updated on your Medusa backend as well.
---
## Manage Contentful Data
### Publish Products
Products added through the integration with the Medusa backend are by default saved as drafts. To show them on the storefront, you must set them as published.
To do that, open your Contentful Space Dashboard and click on Content in the Navigation bar. Then, change Any to Product in the select field next to the search bar. This shows only the content of the type Product, rather than all content.
Click on the checkbox at the top of the table to select all products then click Publish to publish these products.
### Added Featured Products
On the homepage of the storefront, theres a featured products tile that shows a set of products. Before running the storefront, you must add at least one product to the list.
To do that:
1. Open your Contentful Space Dashboard and click on Content in the Navigation bar.
2. Set the select field next to the search bar Any and search for Featured Products. You should find one content of the type Tile Section.
3. Click on the result. You should find on the page an empty Tiles section where you can add tiles and products.
4. Click on the "Add content" button, then on "Add existing content" from the dropdown.
5. Pick some of the products you want to show on the homepage.
6. Once youre done adding products, click on Publish changes in the right sidebar.
---
## Setup Gatsby Storefront
:::warning
This Gatsby storefront is deprecated. It's recommended to integrate Contentful into either the Next.js Starter Template or your custom storefront.
:::
In this section, youll set up the Gatsby storefront of your Medusa backend.
In your terminal in a different directory of the Medusa backend, run the following command:
```bash
gatsby new medusa-contentful-storefront https://github.com/medusajs/medusa-contentful-storefront
```
This will install the storefront in the directory `medusa-contentful-storefront`.
### Set Contentful Environment Variables
Change to the newly created directory and rename `.env.template`:
```bash
mv .env.template .env
```
Then, open `.env`. You should find the following environment variables:
```bash title=.env
CONTENTFUL_SPACE_ID=
CONTENTFUL_ACCESS_TOKEN=
```
The value of `CONTENTFUL_SPACE_ID` is the same value you [retrieved while setting up the Medusa backend](#value-of-contentful_space_id).
To retrieve the value of `CONTENTFUL_ACCESS_TOKEN`:
1. On your Contentful Space dashboard click on Settings in the navigation bar then choose API keys.
2. Choose the API key you created in the previous section.
3. You should find the field "Content Delivery API - access token”. Copy its value and set it as the value of `CONTENTFUL_ACCESS_TOKEN`.
### Start Storefront
Make sure the Medusa backend is still running. Then, start the storefront:
```bash npm2yarn
npm run start
```
This starts the storefront at `localhost:8000`. Open it in your browser and you should see on the homepage the Featured Product section with the products you chose on Contentful.
---
## Make Changes to Content
You can update the CMS content of your storefront in your Contentful Space. This includes the CMS pages or product details.
:::note
If you make changes to the data while your Gatsby storefront is running, the changes are not reflected instantly. Thats because the data is fetched from Contentful during build time. Instead, you must restart your Gatsby storefront to see the changes you make.
:::
---
## Whats Next
Learn [How to customize your Contentful backend and storefront](./customize-contentful.md).
## See Also
- How to deploy your Medusa backend to [Heroku](../../../deployments/server/deploying-on-heroku.mdx), or [DigitalOcean](../../../deployments/server/deploying-on-digital-ocean.md), or [other providers](../../../deployments/server/index.mdx)

View File

@@ -0,0 +1,7 @@
import DocCardList from '@theme/DocCardList';
# CMS Plugins
If you can't find your CMS provider, try checking the [Community Plugins Library](https://medusajs.com/plugins/?filters=CMS&categories=CMS).
<DocCardList />

View File

@@ -0,0 +1,202 @@
---
description: 'Learn how to integrate Strapi with the Medusa backend. Learn how to install the plugin and test two-way sync between the ecommerce and CMS services.'
addHowToData: true
---
# Strapi
In this document, youll learn how to integrate Strapi with Medusa to add rich Content Management System (CMS) functionalities.
:::info
This plugin is a [community plugin](https://github.com/Deathwish98/medusa-plugin-strapi) and is not managed by the official Medusa team. At the moment, it supports v4 of Strapi.
:::
## Overview
[Strapi](https://strapi.io/) is an open source headless CMS service that allows developers to have complete control over their content models. It can be integrated into many other frameworks, including Medusa.
By integrating Strapi to Medusa, you can benefit from powerful features in your ecommerce store including detailed product CMS details, [two-way sync](#test-two-way-sync), an easy-to-use interface to use for static content and pages, and much more.
---
## Prerequisites
### Medusa CLI
[Medusas CLI tool](../../cli/reference.mdx#how-to-install-cli-tool) is required to set up a new Medusa backend.
### Redis
Redis is required for the Strapi plugin to work as expected on your Medusa backend. If you dont have it installed, you can learn [how to install it in this documentation](../../development/backend/prepare-environment.mdx#redis).
---
## Create Strapi Project
The first step is to create a Strapi project using the Medusa template:
```bash
npx create-strapi-app strapi-medusa --template shahednasser/strapi-medusa-template
```
This creates the Strapi project in the directory `strapi-medusa`.
Once the installation is finished, the Strapi development backend will run on `localhost:1337`. A new page will also open in your default browser to create a new admin user and log in.
![Create User Form in Strapi](https://res.cloudinary.com/dza7lstvk/image/upload/v1668001083/Medusa%20Docs/Strapi/9pFE1Ij_h2dicv.png)
Once you log in, you can access the Strapi dashboard.
### Create a Strapi User
The Strapi plugin in Medusa requires the credentials of a Strapi user. To create a new user, go to Content Manager, then choose User under Collection Types.
![Showing the users under Content Manager](https://res.cloudinary.com/dza7lstvk/image/upload/v1668001096/Medusa%20Docs/Strapi/YyGJPUf_mr5sx7.png)
Click on the Create new entry button at the top right. This opens a new form to enter the users details.
![Create User Form on Strapi](https://res.cloudinary.com/dza7lstvk/image/upload/v1668001105/Medusa%20Docs/Strapi/mdMhSlV_vy7ygv.png)
Enter the users username, email, and password. Once youre done, click on the Save button at the top right.
---
## Modify Permissions
By default, created users have the “Authenticated” role. Before you start using the Strapi plugin on your Medusa backend, you must modify this roles permissions to allow making changes to Medusas models in Strapi.
On your Strapi dashboard, go to Settings → Roles → Authenticated. Then, under the Permissions section, expand the accordion of each content model type and check the Select All checkbox.
![An example of modifying permissions on the Product content type](https://res.cloudinary.com/dza7lstvk/image/upload/v1668001116/Medusa%20Docs/Strapi/QgckXqS_wlyxe8.png)
Once youre done, click the Save button at the top right.
---
## Create Medusa Backend
:::note
You can use the Strapi plugin on an existing Medusa backend, however, existing data (such as existing products) will not be imported. Only newer data will be imported.
:::
To create your Medusa backend, run the following command:
```bash
npx @medusajs/medusa-cli@latest new medusa-backend
```
### Configure your Backend
Once the command is done executing, change to the newly created `medusa-backend` directory:
```bash
cd medusa-backend
```
You must then configure your backend to:
- Connect to a PostgreSQL database, as explained [here](../../development/backend/configurations.md#database-configuration)
- Install and configure an event-bus module, as explained [here](../../development/backend/configurations.md#recommended-event-bus-modules)
### Run Migrations
After configuring the connection to the database, you must run migrations to add the necessary database schema definitions in your database. To do that, run the following command in the `medusa-backend` directory:
```bash
npx @medusajs/medusa-cli@latest migrations run
```
You can optionally seed your database with demo data by running the `seed` command:
```bash
npx @medusajs/medusa-cli@latest seed --seed-file=data/seed.json
```
---
## Install the Strapi Plugin
In the directory of your Medusa backend, run the following command to install the Strapi plugin:
```bash npm2yarn
npm install medusa-plugin-strapi
```
Then, add the following environment variables:
```bash
STRAPI_USER=<STRAPI_IDENTIFIER>
STRAPI_PASSWORD=<STRAPI_PASSWORD>
STRAPI_PROTOCOL=http # Optional
STRAPI_URL=<STRAPI_URL> # Optional
STRAPI_PORT=<STRAPI_PORT> # Optional
```
Where:
- `<STRAPI_IDENTIFIER>` is either the email address or username of the user you created in the previous step.
- `<STRAPI_PASSWORD>` is the password of the user you created in the previous step.
- `<STRAPI_PROTOCOL>` is the protocol of your Strapi backend. If youre using a local Strapi backend, set this to `http`. The default value is `https`.
- `<STRAPI_URL>` is the URL of your Strapi backend. By default, the URL is `localhost`.
- `<STRAPI_PORT>` is the port the Strapi backend runs on. By default, the port is `1337`.
Finally, open `medusa-config.js` and add the following new item to the `plugins` array:
```jsx title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-plugin-strapi`,
options: {
strapi_medusa_user: process.env.STRAPI_USER,
strapi_medusa_password: process.env.STRAPI_PASSWORD,
strapi_url: process.env.STRAPI_URL, // optional
strapi_port: process.env.STRAPI_PORT, // optional
strapi_protocol: process.env.STRAPI_PROTOCOL, // optional
},
},
]
```
---
## Run Medusa Backend
Make sure the Strapi backend is still running. If not, you can run the following command to run the Strapi backend in the directory of the Strapi project:
```bash npm2yarn
npm run develop
```
Then, in the directory of your Medusa backend, run the following command to start the Medusa backend:
```bash npm2yarn
npx medusa develop
```
Once you start your Medusa backend, if you ran the `--seed` command when you created your Medusa backend, youll see that `product.created` events have been triggered along with similar events. This will update Strapi with the products you seeded.
---
## Test Two-Way Sync
This plugin ensures a two-way sync between the Medusa backend and the Strapi backend. So, if you update data on Strapi, it will be reflected on your Medusa backend, and vice-versa.
### Update Products on Strapi
Try updating any products on Strapi by going to Content Manager → Products and choosing a product from the list. Then, make changes to the product and click Save. If you view the products on your backend now, either using the [REST APIs](https://docs.medusajs.com/api/admin#products_getproducts) or using [the Medusa Admin](../../user-guide/products/index.mdx), youll see that the product has been updated.
### Update Products on Medusa
If you try to update products on Medusa either using the [REST APIs](https://docs.medusajs.com/api/admin#products_postproductsproduct) or using [the Medusa Admin](../../user-guide/products/manage.mdx), youll see that the product is also updated on Strapi.
---
## See Also
- [Deploy the Medusa backend](../../deployments/server/index.mdx)
- [Create your own plugin](../../development/plugins/create.mdx)

View File

@@ -0,0 +1,154 @@
---
addHowToData: true
---
# Brightpearl
This document will guide you through installing the Brightpearl plugin on your Medusa backend.
## Overview
[Brightpearl](https://www.brightpearl.com/) is a Retail Operations Platform. It can be integrated to a business's different sales channels to provide features related to inventory management, automation, analytics and reporting, and more.
Medusa provides an official Brightpearl plugin with the following features:
- Send and sync orders with Brightpearl.
- Listen for inventory and stock movements in Brightpearl.
- Handle order returns through Brightpearl.
---
## Prerequisites
### Medusa Backend
A Medusa backend is required to be set up before following along with this document. You can follow the [quickstart guide](../../create-medusa-app.mdx) to get started in minutes.
### Brightpearl Account
Using this plugin requires having a [Webshipper account](https://www.brightpearl.com/) with access to development keys and resources.
---
## Install Plugin
In the directory of your Medusa backend, run the following command to install the plugin:
```bash npm2yarn
npm install medusa-plugin-brightpearl
```
Finally, add the plugin to the `plugins` array in `medusa-config.js`:
```js title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-plugin-brightpearl`,
options: {
account: process.env.BRIGHTPEARL_ACCOUNT,
backend_url: process.env.BRIGHTPEARL_BACKEND_URL,
channel_id: process.env.BRIGHTPEARL_CHANNEL_ID,
event_owner: process.env.BRIGHTPEARL_EVENT_OWNER,
warehouse: process.env.BRIGHTPEARL_WAREHOUSE,
// optional
default_status_id:
process.env.BRIGHTPEARL_DEFAULT_STATUS_ID,
swap_status_id:
process.env.BRIGHTPEARL_SWAP_STATUS_ID,
claim_status_id:
process.env.BRIGHTPEARL_CLAIM_STATUS_ID,
payment_method_code:
process.env.BRIGHTPEARL_PAYMENT_METHOD_CODE,
sales_account_code:
process.env.BRIGHTPEARL_SALES_ACCOUNT_CODE,
shipping_account_code:
process.env.BRIGHTPEARL_SHIPPING_ACCOUNT_CODE,
discount_account_code:
process.env.BRIGHTPEARL_DISCOUNT_ACCOUNT_CODE,
gift_card_account_code:
process.env.BRIGHTPEARL_GIFT_CARD_ACCOUNT_CODE,
inventory_sync_cron:
process.env.BRIGHTPEARL_INVENTORY_SYNC_CRON,
cost_price_list:
process.env.BRIGHTPEARL_COST_PRICE_LIST,
base_currency:
process.env.BRIGHTPEARL_BASE_CURRENCY,
},
},
]
```
The plugin accepts the following options:
- `account`: (required) is a string indicating your account ID. You can refer to [Brightpearl's documentation](https://help.brightpearl.com/s/article/360028541892#:~:text=Your%20account%20ID%20can%20be,your%20email%20address%20and%20password.) on how to retrieve it.
- `channel_id`: (required) is a string indicating the ID of the channel to map sales and credits to.
- `backend_url`: (required) is a string indicating the URL of your Medusa backend. This is useful for webhooks.
- `event_owner`: (required) is a string indicating the ID of the contact used when sending the [Goods-Out Note Event](https://api-docs.brightpearl.com/warehouse/goods-out-note%20event/post.html).
- `warehouse`: (required) is a string indicating the ID of the warehouse to allocate order items' inventory from.
- `default_status_id`: (default: `3`) is a string indicating the ID of the status to assign new orders. This value will also be used on swaps or claims if their respective options, `swap_status_id` and `claim_status_id`, are not provided.
- `swap_status_id`: (default: `3`) is a string indicating the ID of the status to assign new swaps. If not provided and `default_status_id` is provided, the value of `default_status_id` will be used.
- `claim_status_id`: (default: `3`) is a string indicating the ID of the status to assign new claims. If not provided and `default_status_id` is provided, the value of `default_status_id` will be used.
- `payment_method_code`: (default: `1220`) is a string indicating the payment method code to register payments with.
- `sales_account_code`: (default: `4000`) is a string indicating the nominal code to assign line items to.
- `shipping_account_code`: (default: `4040`) is a string indicating the nominal code to assign shipping lines to.
- `discount_account_code`: (optional) is a string indicating the nominal code to use for discount-type refunds.
- `gift_card_account_code`: (default: `4000`) is a string indicating the nominal code to use for gift card products and redeems.
- `inventory_sync_cron`: (optional) is a string indicating a cron pattern that should be used to create a scheduled job for syncing inventory. If not provided, the scheduled job will not be created.
- `cost_price_list`: (default: `1`) is a string indicating the ID of the price list to assign to created claims.
- `base_currency`: (default: `EUR`) is a string indicating the ISO 3 character code of the currency to assign to created claims.
Make sure to add the necessary environment variables for the above options in `.env`:
```bash
BRIGHTPEARL_ACCOUNT=<YOUR_ACCOUNT>
BRIGHTPEARL_CHANNEL_ID=<YOUR_CHANNEL_ID>
BRIGHTPEARL_BACKEND_URL=<YOUR_BACKEND_URL>
BRIGHTPEARL_EVENT_OWNER=<YOUR_EVENT_OWNER>
BRIGHTPEARL_WAREHOUSE=<YOUR_WAREHOUSE>
BRIGHTPEARL_DEFAULT_STATUS_ID=<YOUR_DEFAULT_STATUS_ID>
BRIGHTPEARL_SWAP_STATUS_ID=<YOUR_SWAP_STATUS_ID>
BRIGHTPEARL_CLAIM_STATUS_ID=<YOUR_CLAIM_STATUS_ID>
BRIGHTPEARL_PAYMENT_METHOD_CODE=<YOUR_PAYMENT_METHOD_CODE>
BRIGHTPEARL_SALES_ACCOUNT_CODE=<YOUR_SALES_ACCOUNT_CODE>
BRIGHTPEARL_SHIPPING_ACCOUNT_CODE=<YOUR_SHIPPING_ACCOUNT_CODE>
BRIGHTPEARL_DISCOUNT_ACCOUNT_CODE=<YOUR_DISCOUNT_ACCOUNT_CODE>
BRIGHTPEARL_GIFT_CARD_ACCOUNT_CODE=<YOUR_GIFT_CARD_ACCOUNT_CODE>
BRIGHTPEARL_INVENTORY_SYNC_CRON=<YOUR_INVENTORY_SYNC_CRON>
BRIGHTPEARL_COST_PRICE_LIST=<YOUR_COST_PRICE_LIST>
BRIGHTPEARL_BASE_CURRENCY=<YOUR_BASE_CURRENCY>
```
---
## Test the Plugin
To test the plugin, run the following command in the directory of the Medusa backend to start the backend:
```bash
npx medusa develop
```
Then, place an order either using a [storefront](../../starters/nextjs-medusa-starter.mdx) or the [Store REST APIs](https://docs.medusajs.com/api/store). The order should appear on Brightpearl.
---
## How the Plugin Works
### OAuth
The plugin registers an OAuth app in Medusa allowing installation at `<BACKEND_URL>/a/settings/apps`, where `<BACKEND_URL>` is the URL of your Medusa backend.
The OAuth tokens are refreshed every hour to prevent unauthorized requests.
### Orders and Fulfillments
When an order is created in the Medusa backend, it'll automatically be sent to Brightpearl and allocated there. Once allocated, it is up to Brightpearl to figure out how the order is to be fulfilled. The plugin listens for Goods-Out notes and tries to map each of these to a Medusa order. If the matching succeeds, the Medusa backend will send the order to the fulfillment provider associated with the shipping method selected by the Customer.
### Order Returns
When line items in an order are returned, the plugin will generate a sales credit in Brightpearl.
### Products
The plugin doesn't automatically create products in Medusa, but listens for inventory changes in Brightpearl. Then, the plugin updates each product variant to reflect the inventory quantity listed in Brightpearl, thereby ensuring that the inventory levels in Medusa are always in sync with Brightpearl.

View File

@@ -0,0 +1,5 @@
import DocCardList from '@theme/DocCardList';
# ERP Plugins
<DocCardList />

View File

@@ -0,0 +1,7 @@
import DocCardList from '@theme/DocCardList';
# File Service Plugins
If you can't find your file service or storage provider, try checking the [Community Plugins Library](https://medusajs.com/plugins/?filters=Storage&categories=Storage). You can also [create your own file service](../../development/file-service/create-file-service.md).
<DocCardList />

View File

@@ -0,0 +1,105 @@
---
description: 'Learn how to install the local file service to upload images and assets locally on your Medusa backend.'
addHowToData: true
---
# Local File Storage
This document will guide you through installing the local file storage plugin on your Medusa backend.
## Overview
To upload and manage file assets in Medusa, you need a file service plugin responsible for hosting the files. Without a file service plugin, you will face issues while working with Medusa, such as when uploading images for products.
Medusa provides three different options to handle your file storage. The local file storage plugin makes it easy to upload file assets locally during development.
:::note
For production, it's recommended to use a file service plugin that hosts your images on a third-party service. This file service doesn't handle advanced features such as private uploads, which means you can't use it for functionalities like import or export products. Check [the file service plugins](./index.mdx) for available other options to use.
:::
---
## Prerequisites
A Medusa backend is required to be set up before following along with this document. You can follow the [quickstart guide](../../create-medusa-app.mdx) to get started in minutes.
---
## Install Plugin
In the directory of your Medusa backend, run the following command to install the local file service plugin:
```bash npm2yarn
npm install @medusajs/file-local
```
Then, configure your `medusa-config.js` to include the plugin with the required options:
```js title=medusa-config.js
const plugins = [
// ...
{
resolve: `@medusajs/file-local`,
options: {
// optional
},
},
]
```
:::caution
If you have multiple storage plugins configured, the last plugin declared in the `medusa-config.js` file will be used.
:::
### Options
You can pass the plugin the following options:
- `upload_dir`: a string indicating the relative path to upload the files to. By default, it's `uploads/images`.
- `backend_url`: a string indicating the URL of your backend. This is helpful if you deploy your backend or change the port used. By default, it's `http://localhost:9000`.
---
## Test the Plugin
Run your Medusa backend alongside the [Medusa Admin](../../admin/quickstart.mdx) to try out your new file service. Upon editing or creating products, you can now upload thumbnails and images, that are stored locally in your backend.
The files will be stored under the `upload_dir` specified in the plugin options (if no option is specified, they'll be stored in the `uploads/images` directory by default.)
---
## Next.js Starter Template Configuration
If youre using a [Next.js Starter Template](../../starters/nextjs-medusa-starter.mdx), you need to add an additional configuration that adds the backend's domain name into the configured images domain names. This is because all URLs of product images will be from the Medusa backend.
If this configuration is not added, youll receive the error ["next/image Un-configured Host”](https://nextjs.org/docs/messages/next-image-unconfigured-host).
In `next.config.js` add the following option in the exported object:
```jsx title=next.config.js
const { withStoreConfig } = require("./store-config")
// ...
module.exports = withStoreConfig({
// ...
images: {
domains: [
// ...
"<BACKEND_URL>",
],
},
})
```
Where `<BACKEND_URL>` is the URL of your backend. If you're running the backend locally, the value would be `localhost`.
---
## See Also
- Check out [more plugins](../overview.mdx) you can add to your store.

View File

@@ -0,0 +1,226 @@
---
description: 'Learn how to integrate MinIO with the Medusa backend. Learn how to install the MinIO plugin on the Medusa backend and configure it.'
addHowToData: true
---
# MinIO
This document will guide you through installing the MinIO file service plugin on your Medusa backend.
## Overview
To upload and manage file assets in Medusa, you need a file service plugin responsible for hosting the files. Without a file service plugin, you will face issues while working with Medusa, such as when uploading images for products.
Medusa provides three different options to handle your file storage. This document will focus on setting up [MinIO](https://min.io) on your local machine and connecting Medusa to it.
---
## Prerequisites
A Medusa backend is required to be set up before following along with this document. You can follow the [quickstart guide](../../development/backend/install.mdx) to get started in minutes.
---
## Set up MinIO
You can follow [MinIOs guide to install it](https://docs.min.io/minio/baremetal/quickstart/quickstart.html) on your machine based on your operating system.
After installing it, make sure MinIO is always running when your Medusa backend is running. Its recommended that you set up an alias to quickly start the MinIO backend as instructed at the end of the installation guides in MinIO.
### Change MinIO port
In MinIOs documentation, port `9000` is used for the address of the MinIO backend. However, this collides with the port for the Medusa backend. You must change the port for MinIO to another one (for example, port `9001`).
After setting up and installing MinIO on your system/sub-system, you can run the following command to change MinIO port to `9001` (or any other available port) instead of `9000` to avoid the port clash:
```bash
minio server ~/minio --console-address :9090 --address :9001
```
### Create a MinIO bucket
After installing MinIO and logging into the Console, you can create a bucket that will store the files of your Medusa backend by following these steps:
1. Go to the Buckets page from the sidebar.
2. Click on the “Create Bucket” button.
3. For the Bucket Name field, enter a name for the bucket. By MinIOs requirement, the name can only consist of lower case characters, numbers, dots (`.`), and hyphens (`-`).
4. Click on the Create Bucket button.
5. On the bucket's page, click on the edit icon next to Access Policy.
6. In the pop-up that opens, change the selected value to “public” and click Set.
:::warning
Changing the Access Policy to public will allow anyone to access your bucket. Avoid storing sensitive data in the bucket.
:::
### Generate Access Keys
To generate access keys for your plugin:
1. From the sidebar of your MinIO console, click on Access Keys
2. Click on the "Create access key" button
3. This will open a new form with randomly-generated keys. Click on the Create button.
4. A pop-up will then show the value for your Access Key and Secret Key. Copy them to use in the next section.
:::caution
You will not be able to access the Secret Key after closing the pop-up. So, make sure to store it somewhere to use later when configuring the plugin.
:::
---
## Plugin Installation
In the directory of your Medusa backend, run the following command to install the MinIO plugin:
```bash npm2yarn
npm install medusa-file-minio
```
Then, add the following environment variables in `.env`:
```bash
MINIO_ENDPOINT=<ENDPOINT>
MINIO_BUCKET=<BUCKET>
MINIO_ACCESS_KEY=<ACCESS_KEY>
MINIO_SECRET_KEY=<SECRET_KEY>
```
Where `<ENDPOINT>` is the URL of your MinIO backend, `<BUCKET>` is the name of the bucket you created earlier, and `<ACCESS_KEY>` and `<SECRET_KEY>` are the keys you generated in the previous section.
Finally, configure your `medusa-config.js` to include the plugin with the required options:
```js title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-file-minio`,
options: {
endpoint: process.env.MINIO_ENDPOINT,
bucket: process.env.MINIO_BUCKET,
access_key_id: process.env.MINIO_ACCESS_KEY,
secret_access_key: process.env.MINIO_SECRET_KEY,
},
},
]
```
:::caution
If you have multiple storage plugins configured, the last plugin declared in the `medusa-config.js` file will be used.
:::
---
## Test it Out
Run your Medusa backend alongside the [Medusa Admin](../../admin/quickstart.mdx) to try out your new file service. Upon editing or creating products, you can now upload thumbnails and images, that are stored in a MinIO backend.
![Image Uploaded on Admin](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000429/Medusa%20Docs/MinIO/alabX2i_dzg2mh.png)
---
## Private Buckets
### Handle Exports
Medusa provides export functionalities including exporting products and orders. For exports to work, you must [set up a private bucket](#create-private-bucket).
### Handle Imports
Medusa provides import functionalities including importing products. For imports to work, you must [set the private bucket](#add-private-bucket-environment-variable) to be the same as the public bucket.
### Create Private Bucket
To create a private bucket, follow along the [steps mentioned earlier](#create-a-minio-bucket), but keep Access Policy set to private.
### Add Private Bucket Environment Variable
Add the following environment variable on your Medusa backend:
```bash
MINIO_PRIVATE_BUCKET=exports
```
Then, add a new option to the plugins options in `medusa-config.js`:
```jsx title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-file-minio`,
options: {
// ...
private_bucket: process.env.MINIO_PRIVATE_BUCKET,
},
},
]
```
### Use Different Secret and Access Keys
If you only add the `private_bucket` option, the same secret and access keys that you used for the public bucket will be used to access the private bucket.
If you want to use different keys, set the following environment variables:
```bash
MINIO_PRIVATE_ACCESS_KEY=<YOUR_PRIVATE_ACCESS_KEY>
MINIO_PRIVATE_SECRET_KEY=<YOUR_PRIVATE_SECRET_KEY>
```
Where `<YOUR_PRIVATE_ACCESS_KEY>` and `<YOUR_PRIVATE_SECRET_KEY>` are the access key and secret access key that have access to the private MinIO bucket.
Then, add two new options to the plugins options in `medusa-config.js`:
```jsx title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-file-minio`,
options: {
// ...
private_access_key_id:
process.env.MINIO_PRIVATE_ACCESS_KEY,
private_secret_access_key:
process.env.MINIO_PRIVATE_SECRET_KEY,
},
},
]
```
---
## Next.js Starter Template Configuration
If youre using a [Next.js Starter Template](../../starters/nextjs-medusa-starter.mdx), you need to add an additional configuration that adds the MinIO domain name into the configured images domain names. This is because all URLs of product images will be from the MinIO backend.
If this configuration is not added, youll receive the error ["next/image Un-configured Host”](https://nextjs.org/docs/messages/next-image-unconfigured-host).
In `next.config.js` add the following option in the exported object:
```jsx title=next.config.js
const { withStoreConfig } = require("./store-config")
// ...
module.exports = withStoreConfig({
// ...
images: {
domains: [
// ...
"127.0.0.1",
],
},
})
```
Where `127.0.0.1` is the domain of your local MinIO backend.
---
## See Also
- Check out [more plugins](../overview.mdx) you can add to your store.

View File

@@ -0,0 +1,251 @@
---
description: 'Learn how to integrate the S3 plugin with the Medusa backend. Learn how to configure and use S3 to store images related to the Medusa backend.'
addHowToData: true
---
import Troubleshooting from '@site/src/components/Troubleshooting'
import AclErrorSection from '../../troubleshooting/s3-acl-error.md'
# S3
In this document, youll learn how to install the [S3 plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-file-s3) on your Medusa backend and use it for storage.
## Overview
To upload and manage file assets in Medusa, you need a file service plugin responsible for hosting the files. Without a file service plugin, you will face issues while working with Medusa, such as when uploading images for products.
Medusa provides three different options to handle your file storage. This document focuses on using [S3](https://aws.amazon.com/s3/) to store images and files uploaded to the Medusa backend.
---
## Prerequisites
### Medusa Backend
A Medusa backend is required to be set up before following along with this document. You can follow the [quickstart guide](../../development/backend/install.mdx) to get started in minutes.
### Required Accounts
You need to [create an AWS account](https://console.aws.amazon.com/console/home?nc2=h_ct&src=header-signin) to follow along with this documentation.
---
## Create S3 Bucket
On your AWS Console, search for S3 in the search box at the top. Then, choose the first result you see which should be S3 under the Services category.
![Enter S3 in the search box and choose S3 from the result in the Services category](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000547/Medusa%20Docs/S3/wuPTfQ8_bzbm8n.png)
Then, on the new page that opens, click on Create Bucket button at the top right of the Buckets table.
![Click on the Create bucket button](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000527/Medusa%20Docs/S3/h95D38T_gptwpr.png)
The Create Bucket form will open. In the General Configuration section enter a name for the bucket and choose a region for the bucket. Both of the values of these fields are important as youll use them throughout the documentation.
![Enter bucket name and choose region in the General Configuration section](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000559/Medusa%20Docs/S3/wlxUU8I_m4ngqd.png)
Next, in the Object Ownership section, choose ACLs enabled. Then, two radio buttons will show below it. Choose Bucket owner preferred.
![In the Object Ownership section choose ACLs enabled, then choose Bucket owner preferred for the Object ownership field](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000572/Medusa%20Docs/S3/ChUXQPt_eg8mn1.png)
Then, in the “Block Public Access settings for this bucket” section, uncheck the “Block all public access” checkbox. This shows a warning message at the bottom of the section with another checkbox. Check the checkbox to ensure you understand that objects in the bucket are publicly accessible.
![Uncheck Block all public access and all fields under it, and check the checkbox field "I acknowledge that the current settings might result in this bucket and the objects within becoming public"](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000586/Medusa%20Docs/S3/abHquFh_wypfbx.png)
You can leave the rest of the fields in the form as is and scroll down to the end of the page. Then, click on the Create Bucket button.
---
## Manage Bucket Policies
On the page of the bucket you just created, click on the Permissions tab. Then, scroll down until you find the Bucket policy section. Click on Edit in that section.
![Find the bucket policy section which should be empty and click on the Edit button](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000607/Medusa%20Docs/S3/I6BBLwv_zoknft.png)
In the Edit Bucket Policy page, enter the following in the field:
```json
{
"Version": "2012-10-17",
"Id": "Policy1397632521960",
"Statement": [
{
"Sid": "Stmt1397633323327",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<YOUR_BUCKET_NAME>/*"
}
]
}
```
Make sure to replace `<YOUR_BUCKET_NAME>` with the name of the bucket you created.
Once youre done, scroll down and click on the Save changes button.
### User Permissions
Your user must have the `AmazonS3FullAccess` policy attached to it. You can refer to [this guide](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-and-attach-iam-policy.html) to learn how to add a policy if necessary.
### Obtain Access Keys
You must obtain access keys for your user as youll use them to integrate the S3 plugin in Medusa with your bucket. To obtain the Access Key ID and the Secret Access Key, check out [this guide](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys).
---
## Install the S3 Plugin
In the directory of your Medusa backend, run the following command to install the S3 Plugin:
```bash npm2yarn
npm install medusa-file-s3
```
Then, in `medusa-config.js`, add to the `plugins` array the following new item:
```jsx title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-file-s3`,
options: {
s3_url: process.env.S3_URL,
bucket: process.env.S3_BUCKET,
region: process.env.S3_REGION,
access_key_id: process.env.S3_ACCESS_KEY_ID,
secret_access_key: process.env.S3_SECRET_ACCESS_KEY,
cache_control: process.env.S3_CACHE_CONTROL,
download_file_duration:
process.env.S3_DOWNLOAD_FILE_DURATION,
},
},
]
```
Where:
1. `s3_url` (required) is the URL to your bucket. Its in the form `https://<BUCKET_NAME>.s3.<REGION>.amazonaws.com`, where `<BUCKET_NAME>` is the name of the bucket and the `<REGION>` is the region the bucket is created in. If youre not sure which region, on your buckets page on S3 click on Properties. You can then find the region under AWS Region. Make sure to only copy the code (for example, `us-east-1`).
2. `bucket` (required) is the name of the bucket you created.
3. `region` (required) is the region code of your bucket. For example, `us-east-1`.
4. `access_key_id` (required) is the Access Key ID that you created for your user.
5. `secret_access_key` (required) is the Secret Access Key that you created for your user.
6. `cache_control` (default: `max-age=31536000`) is the value for caching the objects in a web browser or CDN network. For example: cache object for 10 hours, `max-age=36000`
7. `download_file_duration` (optional) is the expiry duration for a download URL. For example, you can set the value to ``3600`` if you want the download URL to expire in 1 hour.
Make sure to also set these values in your environment variables as well:
```bash
S3_URL=<YOUR_BUCKET_URL>
S3_BUCKET=<YOUR_BUCKET_NAME>
S3_REGION=<YOUR_BUCKET_REGION>
S3_ACCESS_KEY_ID=<YOUR_ACCESS_KEY_ID>
S3_SECRET_ACCESS_KEY=<YOUR_SECRET_ACCESS_KEY>
S3_CACHE_CONTROL=<YOUR_CACHE_CONTROL>
S3_DOWNLOAD_FILE_DURATION=<YOUR_DOWNLOAD_FILE_DURATION_AMOUNT>
```
:::caution
If you have multiple storage plugins configured, the last plugin declared in the `medusa-config.js` file will be used.
:::
### Add AWS Configurations
You can pass additional AWS configurations, such as `customUserAgent`, in the plugin's options under the property `aws_config_object`. This property is an object that accepts [AWS Configurations](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Config.html) as its properties.
For example:
```jsx title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-file-s3`,
options: {
s3_url: process.env.S3_URL,
bucket: process.env.S3_BUCKET,
aws_config_object: {
customUserAgent: process.env.S3_CUSTOM_AGENT,
},
},
},
]
```
Make sure to define `S3_CUSTOM_AGENT` in your environment variables first.
---
## Test the S3 Plugin
Run your Medusa backend with the following command:
```bash npm2yarn
npx medusa develop
```
Then, you can either test the plugin using the [REST APIs](https://docs.medusajs.com/api/store) or using the [Medusa Admin](../../admin/quickstart.mdx).
On the Medusa Admin, create a new product and, in the Images section, upload an image then click Save. If the integration was successful, the product image will be uploaded successfully.
![An image is successfully uploaded on the Medusa Admin](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000619/Medusa%20Docs/S3/zPC9qFH_dgqf76.png)
You can also check that the image was uploaded on the S3 buckets page.
![Image is now available in the S3 Bucket](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000630/Medusa%20Docs/S3/NJZ5bP8_ovv9rc.png)
---
## Next.js Starter Template Configuration
If youre using a [Next.js Starter Template](../../starters/nextjs-medusa-starter.mdx), you need to add an additional configuration that adds the S3 bucket domain name into the configured images domain names. This is because all URLs of product images will be from the S3 bucket.
If this configuration is not added, youll receive the error ["next/image Un-configured Host”](https://nextjs.org/docs/messages/next-image-unconfigured-host).
In `next.config.js` add the following option in the exported object:
```jsx title=next.config.js
const { withStoreConfig } = require("./store-config")
// ...
module.exports = withStoreConfig({
// ...
images: {
domains: [
// ...
"<BUCKET_NAME>.s3.<REGION>.amazonaws.com",
],
},
})
```
Where:
- `<BUCKET_NAME>` is the name of the S3 bucket youre using
- `<REGION>` is the region of the S3 bucket (for example, `eu-west-1`). If your S3 URL doesn't use region in it, you may omit it to be instead `<BUCKET_NAME>.s3.amazonaws.com`.
---
## Troubleshooting
<Troubleshooting
sections={[
{
title: 'Error: AccessControlListNotSupported: The bucket does not allow ACLs',
content: <AclErrorSection />
}
]}
/>
---
## See Also
- Check out [more plugins](../overview.mdx) you can add to your store
- [Deploy the Medusa backend](../../deployments/server/index.mdx)
- Install the [Next.js Starter Template](../../starters/nextjs-medusa-starter.mdx)

View File

@@ -0,0 +1,187 @@
---
description: 'Learn how to integrate Spaces with the Medusa backend. Learn how to install and configure the Spaces plugin on the Medusa backend.'
addHowToData: true
---
# Spaces
In this document, youll learn how to install the [Spaces plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-file-spaces) on your Medusa backend and use it for storage.
<div>
<video width="100%" height="100%" playsinline autoplay muted controls>
<source src="https://user-images.githubusercontent.com/59018053/154808767-7c030254-1879-41fd-a71c-b31c5508d8a4.mp4" type="video/mp4" />
</video>
</div>
## Overview
To manage images in Medusa, you need a file service plugin responsible for hosting the images. Without a file service plugin, you will face issues while working with Medusa, such as when uploading images for products.
Medusa provides three different options to handle your file storage. This document focuses on using [Spaces](https://www.digitalocean.com/products/spaces) to store images and files uploaded to the Medusa backend.
---
## Prerequisites
### Medusa Backend
A Medusa backend is required to be set up before following along with this document. You can follow the [quickstart guide](../../development/backend/install.mdx) to get started in minutes.
### Required Accounts
You need to [create a DigitalOcean account](https://cloud.digitalocean.com/registrations/new) to follow along with this documentation. A credit card is required during registration.
---
## Create DigitalOcean Space
In your DigitalOcean account, click on the Create button at the top right, then choose Spaces from the dropdown.
![Click on the green Create button at the top right, then choose Spaces in the dropdown](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000907/Medusa%20Docs/Spaces/AQqMRoJ_uhkywh.png)
In the Create a Space form, you can choose any of the regions listed. You can alternatively leave all settings as they are and scroll down to the Finalize and Create section.
![The Space form can be left as is and move towards the Finalize and Create section](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000929/Medusa%20Docs/Spaces/ipsIqoA_zeyfkf.png)
In the Finalize and Create section, enter a name for the field “Choose a unique name”. Youll use this name later in the integration with Medusa. Also, select the project you want to add the new Space to.
![Enter a name for the Space in the Choose a unique name field](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000949/Medusa%20Docs/Spaces/NhlRX0h_ptdhpk.png)
Once youre done, click on the Create a Space button. This creates the Space and redirects you to the Spaces page.
---
## Create Space Access Keys
Choose API from the bottom of the sidebar.
![Choose API from the bottom of the sidebar.](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000964/Medusa%20Docs/Spaces/6zNoDOW_tqbeqv.png)
This opens the Application & API page. Scroll down to Spaces Access Keys and click the Generate New Key button.
![In the Spaces access keys section, click the Generate New Key button](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000977/Medusa%20Docs/Spaces/NUocdgh_doi0dq.png)
This shows a table with the Name field editable. Enter a name for the Access Keys and click on the checkmark button to save and generate the Spaces access keys.
![Enter a name for the Space access key in the field under the Name column](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000987/Medusa%20Docs/Spaces/ihJBx0T_xfe4rh.png)
Then, two keys will be available under the Key column of the table. The first one is the Access Key ID and the second is the Secret Access Key. Copy both as youll use them later.
:::caution
The secret access key will not be shown again after you leave the page. Make sure to copy it when you see it or youll need to re-generate a new one.
:::
---
## Install the Spaces Plugin
In the directory of your Medusa backend, run the following command to install the Spaces plugin:
```bash npm2yarn
npm install medusa-file-spaces
```
Then, add the following environment variables:
```bash
SPACE_URL=<YOUR_SPACE_URL>
SPACE_BUCKET=<YOUR_SPACE_NAME>
SPACE_ENDPOINT=<YOUR_SPACE_ENDPOINT>
SPACE_ACCESS_KEY_ID=<YOUR_ACCESS_KEY_ID>
SPACE_SECRET_ACCESS_KEY=<YOUR_SECRET_ACCESS_KEY>
```
Where:
1. `<YOUR_SPACE_URL>` is the URL of your Space which you can find on the Spaces page below the Spaces name.
![The URL is available under the Space's name on the Space's page](https://res.cloudinary.com/dza7lstvk/image/upload/v1668001004/Medusa%20Docs/Spaces/cA3vkvh_maixr0.png)
2. `<YOUR_SPACE_NAME>` is the name of your Space.
3. `<YOUR_SPACE_ENDPOINT>` is your Spaces endpoint which can be found by going to your Spaces page, clicking on the Settings tab, and scrolling to the Endpoint section.
![Endpoint can be found on the Settings tab in the Space's page](https://res.cloudinary.com/dza7lstvk/image/upload/v1668001017/Medusa%20Docs/Spaces/CnvLr6R_tudlhu.png)
4. `<YOUR_ACCESS_KEY_ID>` and `<YOUR_SECRET_ACCESS_KEY>` are the keys you created in the previous section.
Finally, in `medusa-config.js` add a new item to the `plugins` array:
```jsx title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-file-spaces`,
options: {
spaces_url: process.env.SPACE_URL,
bucket: process.env.SPACE_BUCKET,
endpoint: process.env.SPACE_ENDPOINT,
access_key_id: process.env.SPACE_ACCESS_KEY_ID,
secret_access_key: process.env.SPACE_SECRET_ACCESS_KEY,
},
},
]
```
:::caution
If you have multiple storage plugins configured, the last plugin declared in the `medusa-config.js` file will be used.
:::
---
## Test the Space Plugin
Run your Medusa backend with the following command:
```bash npm2yarn
npx medusa develop
```
Then, you can either test the plugin using the [REST APIs](https://docs.medusajs.com/api/store) or using the [Medusa Admin](../../admin/quickstart.mdx).
On the Medusa Admin, create a new product and, in the Images section, upload an image then click Save. If the integration was successful, the product image will be uploaded successfully.
![Image successfully uploaded on Medusa's admin](https://res.cloudinary.com/dza7lstvk/image/upload/v1668001039/Medusa%20Docs/Spaces/oTi4jIw_c6vefa.png)
You can also check that the image was uploaded on the Spaces page.
![Image can be seen on the Space's page on DigitalOcean](https://res.cloudinary.com/dza7lstvk/image/upload/v1668001050/Medusa%20Docs/Spaces/BexmRkg_gimk1d.png)
---
## Next.js Starter Template Configuration
If youre using a [Next.js Starter Template](../../starters/nextjs-medusa-starter.mdx), you need to add an additional configuration that adds the Spaces domain name into the configured images domain names. This is because all URLs of product images will be from the Space.
If this configuration is not added, youll receive the error ["next/image Un-configured Host”](https://nextjs.org/docs/messages/next-image-unconfigured-host).
In `next.config.js` add the following option in the exported object:
```jsx title=next.config.js
const { withStoreConfig } = require("./store-config")
// ...
module.exports = withStoreConfig({
// ...
images: {
domains: [
// ...
"<YOUR_SPACE_DOMAIN>",
],
},
})
```
Where `<YOUR_SPACE_DOMAIN>` is the domain name for your Space which can be retrieved from the Space URL. For example, `medusa-backend.digitaloceanspaces.com`.
---
## See Also
- Check out [more plugins](../overview.mdx) you can add to your store
- [Deploy the Medusa backend on DigitalOcean](../../deployments/server/deploying-on-digital-ocean.md)
- Install the [Next.js Starter Template](../../starters/nextjs-medusa-starter.mdx)

View File

@@ -0,0 +1,7 @@
import DocCardList from '@theme/DocCardList';
# Fulfillment Plugins
If you can't find your fulfillment provider, try checking the [Community Plugins Library](https://medusajs.com/plugins/?filters=Shipping&categories=Shipping). You can also [create your own fulfillment provider](../../modules/carts-and-checkout/backend/add-fulfillment-provider.md).
<DocCardList />

View File

@@ -0,0 +1,56 @@
---
addHowToData: true
---
# Manual Fulfillment Plugin
This document will guide you through installing the manual fulfillment plugin on your Medusa backend.
## Overview
With Medusa, you can create or integrate fulfillment providers as plugins. Medusa also provides the manual fulfillment plugin as a minimal plugin that allows merchants to handle fulfillments manually. This plugin is installed by default in your Medusa backend.
The manual fulfillment plugin is similar to a cash-on-delivery (COD) fulfillment plugin. A merchant can provide shipping options to the customer on checkout, and create fulfillments and shipments for orders. This data is stored in Medusa, but no actual fulfillment actions are performed, such as communicating with a third-party service. The merchant is assumed to handle that themselves.
---
## Prerequisites
A Medusa backend is required to be set up before following along with this document. You can follow the [quickstart guide](../../create-medusa-app.mdx) to get started in minutes.
---
## Install Plugin
In the directory of your Medusa backend, run the following command to install the plugin:
```bash npm2yarn
npm install medusa-fulfillment-manual
```
Finally, add the plugin to the `plugins` array in `medusa-config.js`:
```js title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-fulfillment-manual`,
},
]
```
---
## Test the Plugin
To test the plugin, run the following command in the directory of the Medusa backend to start the backend:
```bash
npx medusa develop
```
Then, you must enable the Manual Fulfillment Provider in at least one region to use it. You can do that using either the [Medusa Admin](../../user-guide/regions/providers.mdx), which is available at `http://localhost:7001` after you run the above command, or the [Admin REST APIs](../../modules/regions-and-currencies/admin/manage-regions.mdx).
After enabling the provider, you must add shipping options for that provider. You can also do that using either the [Medusa Admin](../../user-guide/regions/shipping-options.mdx) or the [Admin REST APIs](../../modules/regions-and-currencies/admin/manage-regions.mdx#add-a-shipping-option-to-a-region).
Finally, try to place an order using either a [storefront](../../starters/nextjs-medusa-starter.mdx) or the [Store APIs](https://docs.medusajs.com/api/store). You should be able to use the shipping options you created for the fullfilment provider.

View File

@@ -0,0 +1,150 @@
---
addHowToData: true
---
# Webshipper
This document will guide you through installing the Webshipper fulfillment plugin on your Medusa backend.
## Overview
[Webshipper](https://webshipper.com/) is a service that allows merchants to connect to multiple carriers through a single Webshipper account. Developers can then integrate webshipper with ecommerce store like Medusa to handle shipping and fulfillment.
Medusa provides an official plugin that allows you to integrate Webshipper in your store. When integrated, you can provide customers with Webshippers' shipping options on checkout, and process and handle fulfillment and shipments of orders through Webshipper.
---
## Prerequisites
### Medusa Backend
A Medusa backend is required to be set up before following along with this document. You can follow the [quickstart guide](../../create-medusa-app.mdx) to get started in minutes.
### Webshipper Account
Using this plugin requires having a [Webshipper account](https://webshipper.com/) with access to development keys and resources.
---
## Install Plugin
In the directory of your Medusa backend, run the following command to install the plugin:
```bash npm2yarn
npm install medusa-fulfillment-webshipper
```
Finally, add the plugin to the `plugins` array in `medusa-config.js`:
```js title=medusa-config.js
const plugins = [
// ...
{
resolve: `install medusa-fulfillment-webshipper`,
options: {
account: process.env.WEBSHIPPER_ACCOUNT,
api_token: process.env.WEBSHIPPER_API_TOKEN,
order_channel_id:
process.env.WEBSHIPPER_ORDER_CHANNEL_ID,
webhook_secret: process.env.WEBSHIPPER_WEBHOOK_SECRET,
return_address: {
// Webshipper Shipping Address fields
},
// optional
coo_countries: process.env.WEBSHIPPER_COO_COUNTRIES,
delete_on_cancel:
process.env.WEBSHIPPER_DELETE_ON_CANCEL !== "false",
document_size: process.env.WEBSHIPPER_DOCUMENT_SIZE,
return_portal: {
id: process.env.WEBSHIPPER_RETURN_PORTAL_ID,
cause_id:
process.env.WEBSHIPPER_RETURN_PORTAL_CAUSE_ID,
refund_method_id:
process.env.WEBSHIPPER_RETURN_REFUND_METHOD_ID,
},
},
},
]
```
The plugin accepts the following options:
- `account`: (required) is a string indicating your account name. If you're unsure of it, it's in the first part of the URL you use when accessing the Webshipper UI which has the format `https://<account name>.webshipper.io`.
- `api_token`: (required) is a string indicating your API token. You can create it from the Webshipper UI under Settings > Access and tokens.
- `order_channel_id`: (required) is a string indicating the ID of the order channel to retrieve shipping rates from.
- `webhook_secret`: (required) is a string indicating the secret used to sign the HMAC in webhooks.
- `return_address`: (required for returns) is an object that indicates the return address that should be used when fulfilling an order return. Refer to [Webshipper's API reference](https://docs.webshipper.io/#shipping_addresses) for accepted properties in this object.
- `coo_countries`: (default: `all`) is a list of ISO 3 character country codes used when attaching a Certificate of Origin. To support all countries you can set the value to `all`.
- `delete_on_cancel`: (default: `false`) is a boolean value that determines whether Webshipper orders should be deleted when its associated Medusa fulfillment is canceled.
- `document_size`: (default: `A4`) is a string indicating the size used when retrieving documents, such as fulfillment documents. The accepted values, based on Webshipoer's documentation, are `100X150`, `100X192`, or `A4`.
- `return_portal`: is an optional object that includes options related to order returns. It includes the following properties:
- `id`: is a string indicating the ID of the return portal to use when fulfilling an order return.
- `cause_id`: is a string indicating the ID of the return cause to use when fulfilling an order return.
- `refund_method_id` is a string indicating the ID of the refund method to use when fulfilling an order return.
Make sure to add the necessary environment variables for the above options in `.env`:
```bash
WEBSHIPPER_ACCOUNT=<YOUR_WEBSHIPPER_ACCOUNT>
WEBSHIPPER_API_TOKEN=<YOUR_WEBSHIPPER_API_TOKEN>
WEBSHIPPER_ORDER_CHANNEL_ID=<YOUR_WEBSHIPPER_ORDER_CHANNEL_ID>
WEBSHIPPER_WEBHOOK_SECRET=<YOUR_WEBSHIPPER_WEBHOOK_SECRET>
WEBSHIPPER_COO_COUNTRIES=<YOUR_WEBSHIPPER_COO_COUNTRIES>
WEBSHIPPER_DELETE_ON_CANCEL=<YOUR_WEBSHIPPER_DELETE_ON_CANCEL>
WEBSHIPPER_DOCUMENT_SIZE=<YOUR_WEBSHIPPER_DOCUMENT_SIZE>
# Return Portal Variables
WEBSHIPPER_RETURN_PORTAL_ID=<YOUR_WEBSHIPPER_RETURN_PORTAL_ID>
WEBSHIPPER_RETURN_PORTAL_CAUSE_ID=<YOUR_WEBSHIPPER_RETURN_PORTAL_CAUSE_ID>
WEBSHIPPER_RETURN_REFUND_METHOD_ID=<YOUR_WEBSHIPPER_RETURN_REFUND_METHOD_ID>
```
---
## Test the Plugin
To test the plugin, run the following command in the directory of the Medusa backend to start the backend:
```bash
npx medusa develop
```
Then, you must enable the Webshipper Fulfillment Provider in at least one region to use it. You can do that using either the [Medusa Admin](../../user-guide/regions/providers.mdx), which is available at `http://localhost:7001` after you run the above command, or the [Admin REST APIs](../../modules/regions-and-currencies/admin/manage-regions.mdx).
After enabling the provider, you must add shipping options for that provider. You can also do that using either the [Medusa Admin](../../user-guide/regions/shipping-options.mdx) or the [Admin REST APIs](../../modules/regions-and-currencies/admin/manage-regions.mdx#add-a-shipping-option-to-a-region).
Finally, try to place an order using either a [storefront](../../starters/nextjs-medusa-starter.mdx) or the [Store APIs](https://docs.medusajs.com/api/store). You should be able to use the shipping options you created for the fullfilment provider.
---
## Personal Customs Numbers
In countries like South Korea, a personal customs number is required to clear customs. The Webshipper plugin is able pass this information to Webshipper given that the number is stored in `order.shipping_address.metadata.personal_customs_no`.
### Adding Field in Checkout Flow
To allow the customer to pass their personal customs number along with the order, you should dynamically show an input field to the customer when they are shopping from a region that requires a personal customs number. Then, make sure that the `metadata` field includes the personal customs number when updating the cart's shipping address.
```ts
const onUpdateAddress = async () => {
const address = {
first_name: "John",
last_name: "Johnson",
// ...,
metadata: {
// TODO the value should be replaced with the
// value entered by the customer
personal_customs_no: "my-customs-number",
},
}
await medusaClient.carts
.update(cartId, {
shipping_address: address,
})
.then(() => {
console.log(
"Webshipper will pass along the customs number"
)
})
}
```

View File

@@ -0,0 +1,7 @@
import DocCardList from '@theme/DocCardList';
# Notifications Plugins
If you can't find your notification provider, try checking the [Community Plugins Library](https://medusajs.com/plugins/?filters=Notification&categories=Notification). You can also [create your own notification service](../../development/notification/create-notification-provider.md).
<DocCardList />

View File

@@ -0,0 +1,209 @@
---
description: 'Learn how to integrate Mailchimp with the Medusa backend. Learn how to install the plugin on the Medusa backend and how to add a subscription form.'
addHowToData: true
---
# Mailchimp
In this document, youll learn about the Mailchimp plugin, what it does, and how to use it.
## Overview
[Mailchimp](https://mailchimp.com) is an email marketing service that can be used to create newsletters and subscriptions.
By integrating Mailchimp with Medusa, customers will be able to subscribe from Medusa to your Mailchimp newsletter and will be automatically added to your Mailchimp subscribers list.
:::note
This plugin is only used to allow your customers to subscribe but does not actually do any email sending. If you want to send emails to customers based on specific events, for example, when an order is placed, you should check out the [SendGrid plugin](./sendgrid.mdx) instead.
:::
---
## Prerequisites
Before going further with this guide make sure you have a Medusa backend set up. You can follow the [Quickstart guide](../../development/backend/install.mdx).
You also need a Mailchimp account, so please [create one](https://mailchimp.com/signup) before you start.
---
## Obtain Mailchimp Keys
To integrate the plugin into Medusa you need two keys: The API Key and the Newsletter list or Audience ID. The API Key acts as a credential for your account, whereas the Newsletter list ID determines which audience should the subscribed customers be added to.
You can follow [this guide](https://mailchimp.com/help/about-api-keys/#Find_or_generate_your_API_key) from Mailchimps documentation to obtain an API Key.
You can follow [this guide](https://mailchimp.com/help/find-audience-id/) from Mailchimps documentation to obtain your Newsletter list or Audience ID.
---
## Install the Plugin
In the directory of your Medusa backend, run the following command to install the Mailchimp plugin:
```bash npm2yarn
npm install medusa-plugin-mailchimp
```
### Add Keys
Open `.env` and add the following keys:
```bash
MAILCHIMP_API_KEY=<YOUR_API_KEY>
MAILCHIMP_NEWSLETTER_LIST_ID=<YOUR_NEWSLETTER_LIST_ID>
```
Make sure to replace `<YOUR_API_KEY>` with your API Key and `<YOUR_NEWSLETTER_LIST_ID>` with your Newsletter list or Audience ID.
### Add Plugin to Medusa Config
Open `medusa-config.js` and add the new plugin into the `plugins` array:
```js title=medusa-config.js
const plugins = [
// ...,
{
resolve: `medusa-plugin-mailchimp`,
options: {
api_key: process.env.MAILCHIMP_API_KEY,
newsletter_list_id:
process.env.MAILCHIMP_NEWSLETTER_LIST_ID,
},
},
]
```
---
## Test it Out
This plugin adds new `POST` and `PUT` endpoints at `/mailchimp/subscribe`. These endpoints require in the body of the request an `email` field. You can also optionally include a `data` object that holds any additional data you want to send to Mailchimp. You can check out [Mailchimps subscription documentation](https://mailchimp.com/developer/marketing/api/list-merges/) for more details on the data you can send.
### Without Additional Data
Try sending a `POST` or `PUT` request to `/mailchimp/subscribe` with the following JSON body:
```json noReport
{
"email": "example@gmail.com"
}
```
If the subscription is successful, a `200` response code will be returned with `OK` message. If the same email address is used again in the `POST`, a `400` response will be returned with an error page. If this can occur in your usecase, use the `PUT` endpoint to prevent this.
![Postman](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000185/Medusa%20Docs/Mailchimp/tpr7uCF_g4rymn.png)
If you check your Mailchimp dashboard, you should find the email added to your Audience list.
![Email Added](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000199/Medusa%20Docs/Mailchimp/ALz6WUq_e4mkcs.png)
### With Additional Data
Heres an example of sending additional data with the subscription:
```json noReport
{
"email": "example@gmail.com",
"data": {
"tags": ["customer"]
}
}
```
All fields inside `data` will be sent to Mailchimps API along with the email.
---
## Use Mailchimp Service
If you want to subscribe to users without using this endpoint or at a specific place in your code, you can use Mailchimps service `mailchimpService` in your endpoints, services, or subscribers. This service has a method `subscribeNewsletter` which lets you use the subscribe functionality.
Heres an example of using the `mailchimpService` inside an endpoint:
```jsx title=src/api/index.ts
const mailchimpService = req.scope.resolve("mailchimpService")
mailchimpService.subscribeNewsletter(
"example@gmail.com",
{ tags: ["customer"] } // optional
)
```
:::tip
You can learn more about how you can use services in your endpoints, services, and subscribers in the [Services documentation](../../development/services/create-service.mdx#using-your-custom-service).
:::
---
## Add Subscription Form
This section has a simple example of adding a subscription form in your storefront. The code is for React-based frameworks but you can use the same logic for your storefronts regardless of the framework you are using.
Youll need to use [axios](https://github.com/axios/axios) to send API requests, so if you dont have it installed make sure you install it first:
```bash npm2yarn
npm install axios
```
Then, in the component you want to add the subscription form add the following code:
```tsx
import axios from "axios"
import { useState } from "react"
export default function NewsletterForm() {
const [email, setEmail] = useState("")
function subscribe(e) {
e.preventDefault()
if (!email) {
return
}
axios.post("http://localhost:9000/mailchimp/subscribe", {
email,
})
.then((e) => {
alert("Subscribed successfully!")
setEmail("")
})
.catch((e) => {
console.error(e)
alert("An error occurred")
})
}
return (
<form onSubmit={subscribe}>
<h2>Sign Up for our newsletter</h2>
<input
type="email"
name="email"
id="email"
placeholder="example@gmail.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<button type="submit">Subscribe</button>
</form>
)
}
```
This will result in a subscription form similar to the following:
![Subscription Form](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000210/Medusa%20Docs/Mailchimp/JHIFEwe_fu4rkv.png)
If you try entering an email and clicking Subscribe, the email will be subscribed to your Mailchimp newsletter successfully.
---
## See Also
- Check out [SendGrid plugin](./sendgrid.mdx) for more Email functionalities.
- [Plugins Overview](../../development/plugins/overview.mdx)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,106 @@
---
description: 'Learn how to integrate Slack with the Medusa backend. Learn how to create and configure a Slack app and install the Slack plugin on the Medusa backend.'
addHowToData: true
---
# 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 backend to start receiving order notifications.
## Overview
When you add this plugin, the store owner can receive order notifications into their Slack workspace.
The notification contains details about the order including:
- Customer's details and address
- Items ordered, their quantity, and the price
- Order totals including Tax amount.
- Promotion details if there are any (this is optional and can be turned off).
The plugin registers a subscriber to the `order.placed` event. When an order is placed, the subscriber handler method uses the ID of the order to retrieve order details mentioned above.
Then, the order notification is sent to Slack using Webhooks. So, you'll need to create a Slack App, add it into your workspace, and activate Incoming Webhooks.
---
## Prerequisites
### Slack Account
To follow along with this guide, you need to have a Slack account with a connected workspace. If you dont have one, you can [create a free account on Slack](https://slack.com/).
### Medusa Backend
This tutorial assumes you already have a Medusa backend installed. If you dont, please follow along with the [quickstart guide](../../development/backend/install.mdx). The Medusa backend must also have an event bus module installed, which is available when using the default Medusa backend starter.
---
## Create Slack App
The first step is to create a Slack app. This app will be connected to your workspace and will have Incoming Webhooks activated to receive notifications from the Medusa backend using a Webhook URL.
Go to [Slack API](https://api.slack.com/) and click Create app. This will take you to a new page with a pop-up. In the pop-up, choose From scratch.
![Create Slack App](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000844/Medusa%20Docs/Slack/liVfwF8_ryzly3.png)
Youll then need to enter some info like the App name and the workspace it will be connected to. Once youre done, the app will be created.
### Activate Incoming Webhooks
To activate Incoming Webhooks, choose Features > Incoming Webhooks from the sidebar. At first, it will be disabled so make sure to enable it by switching the toggle.
![Incoming Webhooks](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000856/Medusa%20Docs/Slack/5Y0nv4p_mugzkb.png)
### Add New Webhook
After activating Incoming Webhooks, on the same page scroll down and click on the Add New Webhook to Workspace button.
![Add New Webhook](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000867/Medusa%20Docs/Slack/sejdIqH_wyqgs5.png)
After that, choose the channel to send the notifications to. You can also choose a DM to send the notifications to. Once youre done click Allow.
![Choose channel or DM](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000882/Medusa%20Docs/Slack/Zw3f5uF_hljfpr.png)
This will create a new Webhook with a URL which you can see in the table at the end of the Incoming Webhooks page. Copy the URL as youll use it in the next section.
---
## Install Slack Plugin
The next step is to install Medusas [Slack plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-slack-notification) into your Medusa backend.
Open the terminal in the Medusa backends directory and run the following command:
```bash npm2yarn
npm install medusa-plugin-slack-notification
```
After that, open `medusa-config.js` and add the new plugin with its configurations in the `plugins` array:
```jsx title=medusa-config.js
const plugins = [
// ...,
{
resolve: `medusa-plugin-slack-notification`,
options: {
show_discount_code: false,
slack_url: `<WEBHOOK_URL>`,
admin_orders_url: `http://localhost:7001/a/orders`,
},
},
]
```
- Make sure to change `<WEBHOOK_URL>` with the Webhook URL you copied after creating the Slack app.
- The `show_discount_code` option enables or disables showing the discount code in the notification sent to Slack.
- The `admin_orders_url` is the prefix of the URL of the order detail pages on your admin panel. If youre using Medusas Admin locally, it should be `http://localhost:7001/a/orders`. This will result in a URL like `http://localhost:7001/a/orders/order_01FYP7DM7PS43H9VQ1PK59ZR5G`.
Thats all you need to do to integrate Slack into Medusa!
---
## See Also
- Install [Medusa's Admin](../../admin/quickstart.mdx) for the full order-management experience.
- Install the [Next.js Starter Template](../../starters/nextjs-medusa-starter.mdx).

View File

@@ -0,0 +1,147 @@
---
description: 'Learn how to integrate Twilio SMS with the Medusa backend. Learn how to install the Twilio SMS plugin and test it out.'
addHowToData: true
---
# Twilio SMS
In this document, youll learn about the Twilio SMS Plugin, what it does, and how to use it in Medusa.
## Overview
[Twilios SMS API](https://www.twilio.com/sms) can be used to send users SMS messages instantly. It has a lot of additional features such as Whatsapp messaging and conversations.
By integrating Twilio SMS into Medusa, youll have easy access to Twilios SMS API to send SMS messages to your users and customers. You can use it to send Order confirmations, verification codes, reset password messages, and more.
:::note
This plugin only gives you access to the Twilio SMS API but does not implement sending messages at any given point. Youll have to add this yourself where you need it. You can look at the [example later in this tutorial](#example-usage-of-the-plugin) to check how you can send an SMS for a new order.
:::
---
## Prerequisites
Before going further with this guide make sure you have a Medusa backend set up. You can follow the [Quickstart guide](../../development/backend/install.mdx) if you dont.
You also must have a [Twilio account created](https://www.twilio.com/sms) so if you dont already please go ahead and create one.
---
## Retrieve Credentials
For the [Twilio SMS plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-twilio-sms), you need three credentials from your Twilio account: Account SID, Auth Token, and a Twilio phone number to send from. You can find these three from your [Twilio Consoles homepage](https://console.twilio.com).
---
## Install Plugin
In the directory of your Medusa backend, run the following command to install [Twilio SMS plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-twilio-sms):
```bash npm2yarn
npm install medusa-plugin-twilio-sms
```
Then, youll need to add your credentials in `.env`:
```bash
TWILIO_SMS_ACCOUNT_SID=<YOUR_ACCOUNT_SID>
TWILIO_SMS_AUTH_TOKEN=<YOUR_AUTH_TOKEN>
TWILIO_SMS_FROM_NUMBER=<YOUR_TWILIO_NUMBER>
```
Make sure to replace `<YOUR_ACCOUNT_SID>`, `<YOUR_AUTH_TOKEN>`, and `<YOUR_TWILIO_NUMBER>` with the credentials you obtained from your Twilio Console.
Finally, add the plugin and its options in the `medusa-config.js` file to the `plugins` array:
```jsx title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-plugin-twilio-sms`,
options: {
account_sid: process.env.TWILIO_SMS_ACCOUNT_SID,
auth_token: process.env.TWILIO_SMS_AUTH_TOKEN,
from_number: process.env.TWILIO_SMS_FROM_NUMBER,
},
},
]
```
---
## Example Usage of the Plugin
This plugin adds the service `twilioSmsService` to your Medusa backend. To send SMS using it, all you have to do is resolve it in your file as explained in the [Services](../../development/services/create-service.mdx#using-your-custom-service) documentation.
In this example, youll create a subscriber that listens to the `order.placed` event and sends an SMS to the customer to confirm their order.
:::tip
For this example to work, you'll need to have an event bus module installed and configured, which should be available by default.
:::
Create the file `src/services/sms.js` in your Medusa backend with the following content:
```jsx title=src/services/sms.js
class SmsSubscriber {
constructor({
twilioSmsService,
orderService,
eventBusService,
}) {
this.twilioSmsService_ = twilioSmsService
this.orderService = orderService
eventBusService.subscribe("order.placed", this.sendSMS)
}
sendSMS = async (data) => {
const order = await this.orderService.retrieve(data.id, {
relations: ["shipping_address"],
})
if (order.shipping_address.phone) {
this.twilioSmsService_.sendSms({
to: order.shipping_address.phone,
body: "We have received your order #" + data.id,
})
}
}
}
export default SmsSubscriber
```
In the `constructor`, you resolve the `twilioSmsService` and `orderService` using dependency injection to use it later in the `sendSMS` method.
You also subscribe to the event `order.placed` and sets the event handler to be `sendSMS`.
In `sendSMS`, you first retrieve the order with its relation to `shipping_address` which contains a `phone` field. If the phone is set, you send an SMS to the customer using the method `sendSms` in the `twilioSmsService`.
This method accepts an object of parameters. These parameters are based on Twilios SMS APIs. You can check their [API documentation](https://www.twilio.com/docs/sms/api/message-resource#create-a-message-resource) for more fields that you can add.
If you create an order now on your storefront, you should receive a message from Twilio on the phone number you entered in the shipping address.
:::tip
If you dont have a storefront set up yet, you can install the [Next.js Starter Template](../../starters/nextjs-medusa-starter.mdx).
:::
:::caution
If youre on a Twilio trial make sure that the phone number you entered on checkout is a [verified Twilio number on your console](https://console.twilio.com/us1/develop/phone-numbers/manage/verified).
:::
![Twilio Dashboard](https://res.cloudinary.com/dza7lstvk/image/upload/v1668001219/Medusa%20Docs/Stripe/MXtQMiL_kb7kxe.png)
---
## See Also
- [Notifications Overview](../../development/notification/overview.mdx).
- Install the [Medusa admin](../../admin/quickstart.mdx) for functionalities like Gift Cards creation, swaps, claims, order return requests, and more.

View File

@@ -0,0 +1,95 @@
---
addHowToData: true
---
# Discount Generator
In this document, youll learn how to install the Discount Generator plugin on your Medusa backend.
## Overview
In Medusa, merchants can create dynamic discounts that act as a template for other discounts. With dynamic discounts, merchants don't have to repeat certain conditions every time they want to create a new discount.
The discount generator plugin allows merchants and developers to generate new discounts from a dynamic discount. This can be done either by envoking the `/discount-code` endpoint or using the `DiscountGeneratorService`.
---
## Prerequisites
Before you follow this guide, you must have a Medusa backend installed. If not, you can follow the [quickstart guide](../../create-medusa-app.mdx) to learn how to do it.
---
## Install Plugin
In the directory of your Medusa backend, run the following command to install the plugin:
```bash npm2yarn
npm install medusa-plugin-discount-generator
```
Finally, add the plugin to the `plugins` array in `medusa-config.js`:
```js title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-plugin-discount-generator`,
},
]
```
---
## Test the Plugin
### Using the Endpoint
The plugin registers a `POST` endpoint `/discount-code`. The endpoint accepts in the request body the parameter `discount_code` which is a string indicating the code of the dynamic discount to generate a new discount from. The endpoint then creates the new discount from the dynamic discount and returns it in the response.
So, to test out the endpoint, run the following command in the root of your project to start the Medusa backend:
```bash
npx medusa develop
```
Then, create a dynamic discount. You can do that either using the [Medusa admin](../../user-guide/discounts/create.mdx) which is available (if installed) at `http://localhost:7001` after starting the backend, or using the [Admin REST APIs](../../modules/discounts/admin/manage-discounts.mdx).
After that, send a `POST` request to the `/discount-code` endpoint, passing the `discount_code` parameter in the request body with the value being the code of the dynamic discount you just created. A new discount will be created with the same attributes as the dynamic discount code and returned in the response.
### Using the DiscountGeneratorService
After installing the plugin, the `DiscountGeneratorService` is registered in the [dependency container](../../development/fundamentals/dependency-injection.md). So, you can resolve and use it in custom services, endpoints, or other resources.
The `DiscountGeneratorService` has one method `generateDiscount`. This method requires passing the code of a dynamic discount as a parameter. It then creates a new discount having the same attributes as the dynamic discount, but with a different, random code.
Here's an example of using the service in an endpoint:
```ts title=src/api/index.ts
import { Request, Response, Router } from "express"
import bodyParser from "body-parser"
export default (rootDirectory: string): Router | Router[] => {
const router = Router()
router.use(
"/generate-discount-code",
bodyParser.json(),
async (req: Request, res: Response) => {
// skipping validation for simplicity
const { dynamicCode } = req.body
const discountGenerator = req.scope.resolve(
"discountGeneratorService"
)
const code = await discountGenerator.generateDiscount(
dynamicCode
)
res.json({
code,
})
})
return router
}
```

View File

@@ -0,0 +1,7 @@
import DocCardList from '@theme/DocCardList';
# Other Plugins
Check the [Community Plugins Library](https://medusajs.com/plugins/?filters=Other&categories=Other&categories=Source) for more plugins.
<DocCardList />

View File

@@ -0,0 +1,143 @@
---
addHowToData: true
---
# IP Lookup (ipstack) Plugin
In this document, youll learn how to install the IP Lookup plugin on your Medusa backend.
## Overview
Location detection in a commerce store is essential for multi-region support. Medusa provides an IP Lookup plugin that integrates the backend with [ipstack](https://ipstack.com/) to allow you to detect a customers location and, ultimately, their region.
This guide explains how you can install and use this plugin.
---
## Prerequisites
### Medusa Backend
Before you follow this guide, you must have a Medusa backend installed. If not, you can follow the [quickstart guide](../../create-medusa-app.mdx) to learn how to do it.
### ipstack Account
You need an [ipstack account](https://ipstack.com/) before using this plugin. You can create a free account with ipstack on their website.
---
## Install Plugin
In the root directory of your Medusa backend, run the following command to install the IP Lookup plugin:
```bash npm2yarn
npm install medusa-plugin-ip-lookup
```
Then, add the following environment variable in `.env`:
```bash
IPSTACK_ACCESS_KEY=<YOUR_ACCESS_KEY>
```
Where `<YOUR_ACCESS_KEY>` is your ipstack accounts access key. Its available in your ipstack dashboard.
Finally, add the IP lookup plugin into the plugins array exported as part of the Medusa configuration in `medusa-config.js`:
```js title=medusa-config.js
const plugins = [
// other plugins...
{
resolve: `medusa-plugin-ip-lookup`,
options: {
access_token: process.env.IPSTACK_ACCESS_KEY,
},
},
]
```
---
## Test the Plugin
The plugin provides two resources: the `IpLookupService` and the `preCartCreation` middleware.
:::note
Due to how Express resolves the current IP when accessing your website from `localhost`, you wont be able to test the plugin locally. You can either use tools like ngrok to expose the `9000` port to be accessed publicly, or you have to test it on a deployed backend.
:::
### IpLookupService
The `IpLookupService` can be used in other services, endpoints, or resources to get the users location by their IP address. It has only one method `lookupIp` that accepts the IP address as a parameter, sends a request to ipstacks API, and returns the retrieved result.
For example, you can use the `IpLookupService` in a custom endpoint and return the users region:
:::tip
You can learn more about creating an endpoint [here](../../development/endpoints/create.mdx).
:::
```ts title=src/api/index.ts
import { Request, Response, Router } from "express"
export default (rootDirectory: string): Router | Router[] => {
const router = Router()
// ...
router.get(
"/store/customer-region",
async (req: Request, res: Response) => {
const ipLookupService = req.scope.resolve(
"ipLookupService"
)
const regionService = req.scope.resolve<RegionService>(
"regionService"
)
const ip = req.headers["x-forwarded-for"] ||
req.socket.remoteAddress
const { data } = await ipLookupService.lookupIp(ip)
if (!data.country_code) {
throw new Error ("Couldn't detect country code.")
}
const region = await regionService
.retrieveByCountryCode(data.country_code)
res.json({
region,
})
}
)
}
```
### preCartCreation
The `preCartCreation` middleware can be added as a middleware to any route to attach the region ID to that route based on the users location. For example, you can use it on the Create Cart endpoint to ensure that the users correct region is attached to the cart.
For example, you can attach it to all `/store` routes to ensure the customers region is always detected:
<!-- eslint-disable @typescript-eslint/no-var-requires -->
```ts title=src/api/index.ts
import { Router } from "express"
const { preCartCreation } = require(
"medusa-plugin-ip-lookup/api/medusa-middleware"
).default
export default (
rootDirectory: string
): Router | Router[] => {
const router = Router()
// ...
router.use("/store", preCartCreation)
return router
}
```

View File

@@ -0,0 +1,177 @@
---
addHowToData: true
---
# Restock Notifications Plugin
In this document, youll learn how to install the restock notification plugin on your Medusa backend.
:::note
This plugin doesn't actually implement the sending of the notification, only the required implementation to trigger restock events and allow customers to subscribe to product variants' stock status. To send the notification, you need to use a [notification plugin](../notifications/).
:::
## Overview
Customers browsing your products may find something that they need, but it's unfortunately out of stock. In this scenario, you can keep them interested in your product and, subsequently, in your store by notifying them when the product is back in stock.
The Restock Notifications plugin provides new endpoints that allow the customer to subscribe to restock notifications of a specific product variant. It also triggers the `restock-notification.restocked` event whenever a product variant's stock quantity is above a specified threshold. The event's payload includes the ID of the product variant and the customer emails subscribed to it. You can pair this with a subscriber that listens to that event and sends a notification to the customer using a [Notification plugin](../notifications/).
---
## Prerequisites
### Medusa Backend
Before you follow this guide, you must have a Medusa backend installed. If not, you can follow the [quickstart guide](../../create-medusa-app.mdx) to learn how to do it.
### Event-Bus Module
To trigger events to the subscribed handler methods, you must have an event-bus module installed. For development purposes, you can use the [Local module](../../development/events/modules/local.md) which should be enabled by default in your Medusa backend.
For production, it's recommended to use the [Redis module](../../development/events/modules/redis.md).
---
## Install Plugin
In the root directory of your Medusa backend, run the following command to install the Restock Notifications plugin:
```bash npm2yarn
npm install medusa-plugin-restock-notification
```
Then, add the plugin into the plugins array exported as part of the Medusa configuration in `medusa-config.js`:
```js title=medusa-config.js
const plugins = [
// other plugins...
{
resolve: `medusa-plugin-restock-notification`,
options: {
// optional options
trigger_delay, // delay time in milliseconds
inventory_required, // minimum restock inventory quantity
},
},
]
```
The plugin accepts the following optional options:
1. `trigger_delay`: a number indicating the time in milliseconds to delay the triggering of the `restock-notification.restocked` event. Default value is `0`.
2. `inventory_required`: a number indicating the minimum inventory quantity to consider a product variant as restocked. Default value is `0`.
Finally, run the migrations of this plugin before you start the Medusa backend:
```bash
npx medusa migrations run
```
---
## Test Plugin
### 1. Run Medusa Backend
In the root of your Medusa backend project, run the following command to start the Medusa backend:
```bash npm2yarn
npm run start
```
### 2. Subscribe to Variant Restock Notifications
Then, send a `POST` request to the endpoint `<BACKEND_URL>/restock-notifications/variants/<VARIANT_ID>` to subscribe to restock notifications of a product variant ID. Note that `<BACKEND_URL>` refers to the URL fo your Medusa backend, which is `http://localhost:9000` during development, and `<VARIANT_ID>` refers to the ID of the product variant you're subscribing to.
:::note
You can only subscribe to product variants that are out-of-stock. Otherwise, you'll receive an error.
:::
The endpoint accepts the following request body parameters:
1. `email`: a string indicating the email that is subscribing to the product variant's restock notification.
2. `sales_channel_id`: an optional string indicating the ID of the sales channel to check the stock quantity in when subscribing. This is useful if you're using multi-warehouse modules, as the product variant's quantity is checked correctly when checking if it's out of stock. Alternatively, you can pass the [publishable API key in the header of the request](../../development/publishable-api-keys/storefront/use-in-requests.md) and the sales channel will be derived from it.
### 3. Trigger Restock Notification
After subscribing to the out-of-stock variant, change its stock quantity to the minimum inventory required to test out the event trigger. The new stock quantity should be any value above `0` if you didn't set the `inventory_required` option.
You can use the [Medusa admin](../../user-guide/products/manage.mdx#manage-product-variants) or the [Admin REST API endpoints](https://docs.medusajs.com/api/admin#products_postproductsproductvariantsvariant) to update the quantity.
After you update the quantity, you can see the `restock-notification.restocked` triggered and logged in the Medusa backend logs. If you've implemented the notification sending, this is where it'll be triggered and a notification will be sent.
---
## Example: Implement Notification Sending with SendGrid
:::note
The SendGrid plugin already listens to and handles the `restock-notification.restocked` event. So, if you install it you don't need to manually create a subscriber that handles this event as explained here. This example is only provided for reference on how you can send a notification to the customer using a Notication plugin.
:::
Here's an example of a subscriber that listens to the `restock-notification.restocked` event and uses the [SendGrid plugin](../notifications/sendgrid.mdx) to send the subscribed customers an email:
```ts title=src/subscribers/restock-notification.ts
import {
EventBusService,
ProductVariantService,
} from "@medusajs/medusa"
type InjectedDependencies = {
eventBusService: EventBusService,
sendgridService: any
productVariantService: ProductVariantService
}
class RestockNotificationSubscriber {
protected sendGridService_: any
protected productVariantService_: ProductVariantService
constructor({
eventBusService,
sendgridService,
productVariantService,
}: InjectedDependencies) {
this.sendGridService_ = sendgridService
this.productVariantService_ = productVariantService
eventBusService.subscribe(
"restock-notification.restocked",
this.handleRestockNotification
)
}
handleRestockNotification = async ({
variant_id,
emails,
}) => {
// retrieve variant
const variant = await this.productVariantService_.retrieve(
variant_id
)
this.sendGridService_.sendEmail({
templateId: "restock-notification",
from: "hello@medusajs.com",
to: emails,
dynamic_template_data: {
// any data necessary for your template...
variant,
},
})
}
}
export default RestockNotificationSubscriber
```
Handler methods subscribed to the `restock-notification.restocked` event, which in this case is the `handleRestockNotification` method, receive the following object data payload as a parameter:
- `variant_id`: The ID of the variant that has been restocked.
- `emails`: An array of strings indicating the email addresses subscribed to the restocked variant. Here, you pass it along to the SendGrid plugin directly to send the email to everyone subscribed. If necessary, you can also retrieve the customer of that email using the `CustomerService`'s [retrieveByEmail](../../references/services/classes/CustomerService.md#retrievebyemail) method.
In the method, you retrieve the variant by its ID using the `ProductVariantService`, then send the email using the SendGrid plugins' `SendGridService`.

View File

@@ -0,0 +1,96 @@
---
addHowToData: true
---
# Wishlist Plugin
In this document, youll learn how to install the Wishlist plugin on your Medusa backend.
## Overview
A wishlist allows customers to save items they like so they can browse and purchase them later. Medusa's wishlist plugin provides the following features:
- Allow a customer to manage their wishlist, including adding or deleting items.
- Allow a customer to share their wishlist with others using a token.
:::tip
Items in the wishlist are added as line items. This allows you to implement functionalities like moving an item from the wishlist to the cart, although this is not implemented by the plugin.
:::
---
## Prerequisites
Before you follow this guide, you must have a Medusa backend installed. If not, you can follow the [quickstart guide](../../create-medusa-app.mdx) to learn how to do it.
---
## Install Plugin
In the directory of your Medusa backend, run the following command to install the plugin:
```bash npm2yarn
npm install medusa-plugin-wishlist
```
Finally, add the plugin to the `plugins` array in `medusa-config.js`:
```js title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-plugin-wishlist`,
},
]
```
---
## Test the Plugin
Before testing the plugin, run the following command in the directory of the Medusa backend to start the backend:
```bash
npx medusa develop
```
The plugin exposes four endpoints.
### Add Item to Wishlist Endpoint
The `POST` endpoint at `/store/customer/<CUSTOMER_ID>/wishlist` allows customers to add items to their existing or new wishlist, where `<CUSTOMER_ID>` is the ID of the customer. It accepts the following body parameters:
- `variant_id`: a string indicating the ID of the product variant to add to the wishlist.
- `quantity`: (optional) a number indicating the quantity of the product variant.
- `metadata`: (optional) any metadata to attach to the wishlist item.
The request returns the full customer object. The wishlist is available at `customer.metadata.wishlist`, where its value is an array of items.
### Delete Item from Wishlist Endpoint
The `DELETE` endpoint at `/store/customer/<CUSTOMER_ID>/wishlist` allows customers to delete items from their wishlist, where `<CUSTOMER_ID>` is the ID of the customer.
The endpoint accepts one request body parameter `index`, which indicates the index of the item in the `customer.metadata.wishlist` array.
The request returns the full customer object. The wishlist is available at `customer.metadata.wishlist`, where its value is an array of items.
#### Generate Share Token Endpoint
The `POST` endpoint at `/store/customer/<CUSTOMER_ID>/wishlist/share-token` allows customers to retrieve a token that can be used to access the wishlist, where `<CUSTOMER_ID>` is the ID of the customer.
The endpoint doesn't accept any request body parameters.
The request returns an object in the response having the property `share_token`, being the token that can be used to access the wishlist.
#### Access Wishlist with Token Endpoint
The `GET` endpoint at `/wishlists/<TOKEN>` allows anyone to access the wishlist using its token, where `<TOKEN>` is the token retrieved from the [Generate Share Token Endpoint](#generate-share-token-endpoint).
The endpoint doesn't accept any request body parameters.
The request returns an object in the response having the following properties:
- `items`: an array of objects, each being an item in the wishlist.
- `first_name`: a string indicating the first name of the customer that this wishlist belongs to.

View File

@@ -0,0 +1,115 @@
---
description: 'Check out available official plugins in Medusa.'
---
import DocCardList from '@theme/DocCardList';
import Icons from '@theme/Icon';
# Plugins
This section includes documentation for official Medusa plugins.
You can learn more about plugins and how they work in the [Plugins Overview documentation](../development/plugins/overview.mdx).
:::tip
Interested in creating a plugin? Learn more in the [Create Plugin documentation](../development/plugins/create).
:::
<!-- vale docs.Acronyms = NO -->
<DocCardList colSize={6} items={[
{
type: 'link',
href: '/plugins/analytics',
label: 'Analytics',
customProps: {
icon: Icons['squares-plus-solid'],
description: 'Check out official Analytics plugins.'
}
},
{
type: 'link',
href: '/plugins/cms',
label: 'CMS',
customProps: {
icon: Icons['squares-plus-solid'],
description: 'Check out official CMS plugins.'
}
},
{
type: 'link',
href: '/plugins/notifications',
label: 'Notifications',
customProps: {
icon: Icons['squares-plus-solid'],
description: 'Check out official Notifications plugins.'
}
},
{
type: 'link',
href: '/plugins/payment',
label: 'Payment',
customProps: {
icon: Icons['squares-plus-solid'],
description: 'Check out official Payment plugins.'
}
},
{
type: 'link',
href: '/plugins/fulfillment',
label: 'Fulfillment',
customProps: {
icon: Icons['squares-plus-solid'],
description: 'Check out official Fulfillment plugins.'
}
},
{
type: 'link',
href: '/plugins/search',
label: 'Search',
customProps: {
icon: Icons['squares-plus-solid'],
description: 'Check out official Search plugins.'
}
},
{
type: 'link',
href: '/plugins/file-service',
label: 'File Service',
customProps: {
icon: Icons['squares-plus-solid'],
description: 'Check out official File Service plugins.'
}
},
{
type: 'link',
href: '/plugins/erp',
label: 'ERP',
customProps: {
icon: Icons['squares-plus-solid'],
description: 'Check out official ERP plugins.'
}
},
{
type: 'link',
href: '/plugins/source',
label: 'Source',
customProps: {
icon: Icons['squares-plus-solid'],
description: 'Check out official Source plugins.'
}
},
{
type: 'link',
href: '/plugins/other',
label: 'Other Plugins',
customProps: {
icon: Icons['squares-plus-solid'],
description: 'Check out other official plugins.'
}
},
]} />
<!-- vale docs.Acronyms = YES -->

View File

@@ -0,0 +1,7 @@
import DocCardList from '@theme/DocCardList';
# Payment Plugins
If you can't find your payment provider, try checking the [Community Plugins Library](https://medusajs.com/plugins/?filters=Payment&categories=Payment). You can also [create your own fulfillment provider](../../modules/carts-and-checkout/backend/add-payment-provider.md).
<DocCardList />

View File

@@ -0,0 +1,99 @@
---
description: 'Learn how to integrate Klarna as a payment provider with the Medusa backend. Learn how to install Klarna and enable the payment provider in a region.'
addHowToData: true
---
# Klarna
In this document, youll learn how to integrate Klarna as a payment provider in Medusa.
:::tip
Following the release of v1.8 of the core Medusa package, the naming of payment providers have changed to payment processors with the introduction of the Payment Processor API. However, plugins or implementation that still don't implement the Payment Processor API are still called payment providers.
:::
## Introduction
[Klarna](https://www.klarna.com/) is a payment provider that allows customers to pay in different ways including direct payment, installment payments, payment after delivery, and more.
You can integrate Klarna into Medusa using the [official plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-payment-klarna).
---
## Prerequisites
### Medusa Components
It is assumed that you already have a Medusa backend installed and set up. If not, you can follow the [quickstart guide](../../development/backend/install.mdx).
In addition, youll need to use the [Medusa Admin](../../admin/quickstart.mdx) to enable the payment provider in later steps. You can alternatively use the [REST APIs](https://docs.medusajs.com/api/admin#regions_postregionsregionpaymentproviders).
### Needed Accounts
- A [Klarna business account](https://portal.klarna.com/)
---
## Install Plugin
On your Medusa backend, run the following command to install the plugin:
```bash
npm install medusa-payment-klarna
```
Then, add the following environment variables:
```bash
KLARNA_BACKEND_URL=<YOUR_KLARNA_BACKEND_URL>
KLARNA_URL=<YOUR_KLARNA_URL>
KLARNA_USER=<YOUR_KLARNA_USER>
KLARNA_PASSWORD=<YOUR_KLARNA_PASSWORD>
KLARNA_TERMS_URL=<YOUR_KLARNA_TERMS_URL>
KLARNA_CHECKOUT_URL=<YOUR_KLARNA_CHECKOUT_URL>
KLARNA_CONFIRMATION_URL=<YOUR_KLARNA_CONFIRMATION_URL>
```
Where:
- `<YOUR_KLARNA_BACKEND_URL>` is your Klarna URL.
- `<YOUR_KLARNA_URL>` is the [base Klarna URL based on your environment](https://docs.klarna.com/api/api-urls/).
- `<YOUR_KLARNA_USER>` and `<YOUR_KLARNA_PASSWORD>` are your [API credentials](https://docs.klarna.com/api/authentication/).
- `<YOUR_KLARNA_TERMS_URL>`, `<YOUR_KLARNA_CHECKOUT_URL>`, and `<YOUR_KLARNA_CONFIRMATION_URL>` are the terms, checkout, and confirmation URL of your Klarna account.
Finally, in `medusa-config.js`, add the Klarna plugin to the `plugins` array with the necessary configurations:
```jsx title=medusa-config.js
const plugins = [
// other plugins...
{
resolve: `medusa-payment-klarna`,
options: {
backend_url: process.env.KLARNA_BACKEND_URL,
url: process.env.KLARNA_URL,
user: process.env.KLARNA_USER,
password: process.env.KLARNA_PASSWORD,
merchant_urls: {
terms: process.env.KLARNA_TERMS_URL,
checkout: process.env.KLARNA_CHECKOUT_URL,
confirmation: process.env.KLARNA_CONFIRMATION_URL,
},
},
},
]
```
---
## Enable Klarna in Regions
To use Klarna in your store, you must enable it in at least one region.
You can follow [this user guide to learn how to enable a payment provider in a region](../../user-guide/regions/providers#manage-payment-providers). You can alternatively use the [REST APIs](https://docs.medusajs.com/api/admin#regions_postregionsregionpaymentproviders).
---
## See Also
- Check out [more plugins](../overview.mdx) you can add to your store.

View File

@@ -0,0 +1,284 @@
---
description: 'Learn how to integrate PayPal with the Medusa backend. Learn how to install the PayPal plugin on the Medusa backend and integrate into a storefront.'
addHowToData: true
---
# PayPal
This document guides you through setting up PayPal as a payment processor in your Medusa backend, admin, and storefront using the [PayPal plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-payment-paypal).
## Overview
[PayPal](https://www.paypal.com) is a payment processor used by millions around the world. It allows customers to purchase orders from your website using their PayPal account rather than the need to enter their card details.
As a developer, you can use PayPals SDKs and APIs to integrate PayPal as a payment method into your ecommerce store. You can test out the payment method in sandbox mode before going live with it as a payment method.
Using the `medusa-payment-paypal` plugin, this guide shows you how to set up your Medusa backend with PayPal as a payment processor.
---
## Prerequisites
Before you proceed with this guide, make sure you create a [PayPal account](https://www.paypal.com). You also need a PayPal Developer account and retrieve the Client ID and Client Secret. You can learn more about how to do that in [PayPals documentation](https://developer.paypal.com/api/rest/).
In addition, you need to configure a webhook listener on your PayPal Developer Dashboard and obtain the webhook ID. This is necessary for Webhooks to work.
Webhooks are used in scenarios where the customer might leave the page during the authorization and before the checkout flow is fully complete. It will then create the order or swap after the payment is authorized if they werent created.
The endpoint for PayPal webhook integration with your Medusa backend should be set to `{BACKEND_URL}/paypal/hooks`. Make sure to replace `{BACKEND_URL}` with the URL to your backend.
Additionally, you need a Medusa backend installed and set up. If not, you can follow the [quickstart guide](../../development/backend/install.mdx) to get started.
You also need [Medusa Admin](../../admin/quickstart.mdx) installed to enable PayPal as a payment processor. You can alternatively use the [REST APIs](https://docs.medusajs.com/api/admin).
---
## Medusa Backend
### Install the PayPal Plugin
In the root of your Medusa backend, run the following command to install the PayPal plugin:
```bash npm2yarn
npm install medusa-payment-paypal
```
### Configure the PayPal Plugin
Next, you need to add configurations for your PayPal plugin.
In the `.env` file add the following new environment variables:
```bash
PAYPAL_SANDBOX=true
PAYPAL_CLIENT_ID=<CLIENT_ID>
PAYPAL_CLIENT_SECRET=<CLIENT_SECRET>
PAYPAL_AUTH_WEBHOOK_ID=<WEBHOOK_ID>
```
Where `<CLIENT_ID>`, `<CLIENT_SECRET>`, and `<WEBHOOK_ID>` are the keys you retrieved from the PayPal Developer dashboard as explained in the [Prerequisites](#prerequisites) section.
Notice that during development its highly recommended to set `PAYPAL_SANDBOX` to `true` and ensure you have [sandbox accounts set up in PayPal](https://developer.paypal.com/api/rest/sandbox/).
Then, in `medusa-config.js`, add the PayPal plugin to the `plugins` array with the configurations necessary:
```jsx title=medusa-config.js
const plugins = [
// other plugins...
{
resolve: `medusa-payment-paypal`,
options: {
sandbox: process.env.PAYPAL_SANDBOX,
clientId: process.env.PAYPAL_CLIENT_ID,
clientSecret: process.env.PAYPAL_CLIENT_SECRET,
authWebhookId: process.env.PAYPAL_AUTH_WEBHOOK_ID,
},
},
]
```
Thats all you need to install PayPal on your Medusa backend!
The PayPal plugin also accepts the following optional configurations:
- `capture`: : a boolean value that indicates whether payment should be captured manually or automatically. By default, it will be false, leading admins to capture the payment manually.
---
## Admin Setup
This section will guide you through adding PayPal as a payment processor in a region using your Medusa admin dashboard.
This step is required for you to be able to use PayPal as a payment processor in your storefront.
### Admin Prerequisites
If you dont have a Medusa admin installed, make sure to follow along with [the guide on how to install it](../../admin/quickstart.mdx) before continuing with this section.
### Add PayPal to Regions
You can refer to [this documentation in the user guide](../../user-guide/regions/providers.mdx#manage-payment-providers) to learn how to add a payment processor like PayPal to a region.
---
## Storefront Setup
This section will take you through the steps to add PayPal as a payment method on the storefront. It includes the steps necessary when using one of Medusas official storefronts as well as your own custom React-based storefront.
### Storefront Prerequisites
All storefronts require that you obtain your PayPal Client ID. You can retrieve it from your PayPal developer dashboard.
### Process Overview
Aside from the Next.js Starter Template, you need to add the implementation with PayPal manually.
:::note
It is recommended to read through the [Frontend Checkout Flow](../../modules/carts-and-checkout/storefront/implement-checkout-flow.mdx) first to fully understand how payment is implemented on the storefront.
:::
Although the next sections have different implementations to add PayPal into your storefront, they essentially follow the same process:
1. Show PayPals button if the PayPal processor is available for the current cart.
2. When the button is clicked, open PayPals payment portal and wait for the customer to authorize the payment.
3. If the payment is authorized successfully, set PayPals [Payment Session](../../modules/carts-and-checkout/payment.md#payment-session) as the session used to perform the payment for the current cart, then update the Payment Session on the backend with the data received from PayPals payment portal. This data is essential to the backend to verify the authorization and perform additional payment processing later such as capturing payment.
4. Complete the cart to create the order.
:::info
In Medusa, by default, payments are authorized during checkout, but the payment is not captured right away. The payment should be manually [captured from the Medusa Admin](#capture-payment).
:::
### Add to Next.js Starter Template
Medusa has a Next.js Starter Template that you can easily use with your Medusa backend. If you dont have the storefront installed, you can follow [this quickstart guide](../../starters/nextjs-medusa-starter.mdx).
In your `.env.local` file (or the file youre using for your environment variables), add the following variable:
```bash title=.env.local
NEXT_PUBLIC_PAYPAL_CLIENT_ID=<YOUR_CLIENT_ID>
```
Make sure to replace `<YOUR_CLIENT_ID>` with your PayPal Client ID.
Now, if you run your Medusa backend and your storefront, on checkout youll be able to use PayPal].
![PayPal Button](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000463/Medusa%20Docs/PayPal/F8OvsOJ_v3ctol.png)
You can test out the payment with PayPal using your sandbox account.
### Add to Custom Storefront
This section guides you to add PayPal into a React-based framework. The instructions are general instructions that you can use in your storefront.
In your storefront, you need to install the [PayPal React components library](https://www.npmjs.com/package/@paypal/react-paypal-js) and the [Medusa JS Client library](https://www.npmjs.com/package/@medusajs/medusa-js):
```bash npm2yarn
npm install @paypal/react-paypal-js @medusajs/medusa-js
```
Then, add the Client ID as an environment variable based on the framework youre using.
Next, create the file that will hold the PayPal component with the following content:
```jsx
import {
PayPalButtons,
PayPalScriptProcessor,
} from "@paypal/react-paypal-js"
import { useEffect, useState } from "react"
import Medusa from "@medusajs/medusa-js"
function Paypal() {
const client = new Medusa()
const [errorMessage, setErrorMessage] = useState(undefined)
const [processing, setProcessing] = useState(false)
const cart = "..." // TODO retrieve the cart here
const handlePayment = (data, actions) => {
actions.order.authorize().then(async (authorization) => {
if (authorization.status !== "COMPLETED") {
setErrorMessage(
`An error occurred, status: ${authorization.status}`
)
setProcessing(false)
return
}
const response = await client
.carts
.setPaymentSession(cart.id, {
"processor_id": "paypal",
})
if (!response.cart) {
setProcessing(false)
return
}
await client
.carts
.updatePaymentSession(cart.id, "paypal", {
data: {
data: {
...authorization,
},
},
})
const { data } = await client.carts.complete(cart.id)
if (!data || data.object !== "order") {
setProcessing(false)
return
}
// order successful
alert("success")
})
}
return (
<div style={{ marginTop: "10px", marginLeft: "10px" }}>
{cart !== undefined && (
<PayPalScriptProcessor options={{
"client-id": "<CLIENT_ID>",
"currency": "EUR",
"intent": "authorize",
}}>
{errorMessage && (
<span className="text-rose-500 mt-4">
{errorMessage}
</span>
)}
<PayPalButtons
style={{ layout: "horizontal" }}
onApprove={handlePayment}
disabled={processing}
/>
</PayPalScriptProcessor>
)}
</div>
)
}
export default Paypal
```
Heres briefly what this code snippet does:
1. At the beginning of the component, the Medusa client is initialized using the JS Client you installed.
2. You also need to retrieve the cart. Ideally, the cart should be managed through a context. So, every time the cart has been updated the cart should be updated in the context to be accessed from all components.
3. This component renders a PayPal button to initialize the payment using PayPal. You use the components from the PayPal React components library to render the button and you pass the `PayPalScriptProcessor` component the Client ID. Make sure to replace `<CLIENT_ID>` with the environment variable you added.
4. When the button is clicked, the `handlePayment` function is executed. In this method, you initialize the payment authorization using `actions.order.authorize()`. It takes the customer to another page to log in with PayPal and authorize the payment.
5. After the payment is authorized successfully on PayPals portal, the fulfillment function passed to `actions.order.authorize().then` will be executed.
6. In the fulfillment function, you first ensure that the payment session for the PayPal payment processor is set as the [selected Payment Session in the cart](https://docs.medusajs.com/api/store#carts_postcartscartpaymentsession). Then, you send a request to the backend to [update the payment session](https://docs.medusajs.com/api/store#carts_postcartscartpaymentsessionupdate) data with the authorization data received from PayPal.
7. You then [complete the cart and place the order](https://docs.medusajs.com/api/store#carts_postcartscartcomplete). If that is done successfully, you just show a success alert. You can change this based on the behavior you want in your storefront.
You can then import this component where you want to show it in your storefront.
If you run the Medusa backend and the storefront backend, you should see the PayPal button on checkout.
![PayPal Button](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000492/Medusa%20Docs/PayPal/PsibgPY_xtqdli.png)
---
## Capture Payments
After the customer places an order, you can see the order on the admin panel. In the payment information under the “Payment” section, you should see a “Capture” button.
![Capture Payment](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000502/Medusa%20Docs/PayPal/Mx357yY_xsandw.png)
Clicking this button lets you capture the payment for an order. You can also refund payments if an order has captured payments.
Refunding or Capturing payments is reflected in your PayPal dashboard as well.
---
## See Also
- Check out [more plugins](../overview.mdx) you can add to your store.

View File

@@ -0,0 +1,400 @@
---
description: 'Learn how to integrate Stripe with the Medusa backend. Learn how to install the Stripe plugin on the Medusa backend and integrate it into a storefront.'
addHowToData: true
---
import Troubleshooting from '@site/src/components/Troubleshooting'
import MissingPaymentProvider from '../../troubleshooting/missing-payment-providers.md'
# Stripe
This document guides you through setting up Stripe payments in your Medusa backend, admin, and storefront using the [Stripe Plugin](https://github.com/medusajs/medusa/tree/master/packages/medusa-payment-stripe).
## Video Guide
You can also follow this video guide to learn how the setup works:
<div>
<video width="100%" height="100%" playsinline autoplay muted controls>
<source src="https://user-images.githubusercontent.com/59018053/154807206-6fbda0a6-bf3e-4e39-9fc2-f11710afe0b9.mp4" type="video/mp4" />
</video>
</div>
## Overview
[Stripe](https://stripe.com/) is a battle-tested and unified platform for transaction handling. Stripe supplies you with the technical components needed to handle transactions safely and all the analytical features necessary to gain insight into your sales. These features are also available in a safe test environment which allows for a concern-free development process.
Using the `medusa-payment-stripe` plugin, this guide shows you how to set up your Medusa project with Stripe as a payment processor.
---
## Prerequisites
Before you proceed with this guide, make sure you create a [Stripe account](https://stripe.com). Youll later retrieve the API Keys and secrets from your account to connect Medusa to your Stripe account.
---
## Medusa Backend
This section guides you over the steps necessary to add Stripe as a payment processor to your Medusa backend.
If you dont have a Medusa backend installed yet, you must follow the [quickstart guide](../../development/backend/install.mdx) first.
### Install the Stripe Plugin
In the root of your Medusa backend, run the following command to install the stripe plugin:
```bash npm2yarn
npm install medusa-payment-stripe
```
### Configure the Stripe Plugin
Next, you need to add configurations for your stripe plugin.
In `medusa-config.js` add the following at the end of the `plugins` array:
```jsx title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-payment-stripe`,
options: {
api_key: process.env.STRIPE_API_KEY,
webhook_secret: process.env.STRIPE_WEBHOOK_SECRET,
},
},
]
```
The Stripe plugin uses two configuration options. The `api_key` is essential to both your development and production environments. As for the `webhook_secret`, its essential for your production environment. So, if youre only using Stripe for development you can skip adding the value for this option at the moment.
:::note
You can learn more about the events that the plugin monitors in [this section](#handled-webhook-events).
:::
Other optional options include:
- `payment_description`: a string that is used as the default description of a payment if none is provided.
- `capture`: a boolean value that indicates whether payment should be captured manually or automatically. By default, it will be `false`, leading admins to capture the payment manually.
- `automatic_payment_methods`: a boolean value that enables Stripe's automatic payment methods. This is useful if you're integrating services like Apple pay or Google pay.
### Retrieve Stripe's Keys
On the [dashboard](https://dashboard.stripe.com) of your Stripe account click on the Developers link at the top right. This will take you to the developer dashboard.
Youll first retrieve the API key. You can find it by choosing API Keys from the sidebar and copying the Secret key.
Next, you need to add the key to your environment variables. In your Medusa backend, create `.env` if it doesnt already exist and add the Stripe key:
```bash
STRIPE_API_KEY=sk_...
```
:::note
If you store environment variables differently on your backend, for example, using the hosting processors UI, then you dont need to add it in `.env`. Add the environment variables in a way relevant to your backend.
:::
Next, if youre installing this plugin for production use, you need to retrieve the Webhook secret. Webhooks allows you to track different events on your Medusa backend, such as failed payments.
Go to Webhooks on Stripes developer dashboard. Then, choose the Add an Endpoint button.
The endpoint for Stripes webhook on your Medusa backend is `{BACKEND_URL}/stripe/hooks`. So, add that endpoint in its field. Make sure to replace `{BACKEND_URL}` with the URL to your backend.
Then, you can add a description. You must select at least one event to listen to. Once youre done, click “Add endpoint”.
After the Webhook is created, youll see "Signing secret" in the Webhook details. Click on "Reveal" to reveal the secret key. Copy that key and in your Medusa backend add the Webhook secret environment variable:
```bash
STRIPE_WEBHOOK_SECRET=whsec_...
```
---
## Admin Setup
This section will guide you through adding Stripe as a payment processor in a region using your Medusa admin dashboard.
This step is required for you to be able to use Stripe as a payment processor in your storefront.
### Admin Prerequisites
If you dont have a Medusa admin installed, make sure to follow along with [the guide on how to install it](https://github.com/medusajs/admin#-quickstart) before continuing with this section.
### Add Stripe to Regions
You can refer to [this documentation in the user guide](../../user-guide/regions/providers.mdx#manage-payment-providers) to learn how to add a payment processor like Stripe to a region.
---
## Storefront Setup
This guide will take you through how to set up Stripe payments in your Medusa storefront. It includes the steps necessary when using one of Medusas official storefronts as well as your own custom React-based storefront.
### Storefront Prerequisites
All storefronts require that you obtain your Stripes Publishable Key. You can retrieve it from your Stripes developer dashboard by choosing API Keys and then copying the Publishable Key.
### Add to Next.js Starter Template
Medusa has a Next.js Starter Template that you can easily use with your Medusa backend. If you dont have the storefront installed, you can follow [this quickstart guide](../../starters/nextjs-medusa-starter).
In your `.env.local` file (or the file youre using for your environment variables), add the following variable:
```bash title=.env.local
NEXT_PUBLIC_STRIPE_KEY=<YOUR_PUBLISHABLE_KEY>
```
Make sure to replace `<YOUR_PUBLISHABLE_KEY>` with your Stripe Publishable Key.
Now, if you run your Medusa backend and your storefront, on checkout youll be able to use Stripe.
![Next.js Stripe Form](https://res.cloudinary.com/dza7lstvk/image/upload/v1668001145/Medusa%20Docs/Stripe/h5mWdJT_n1bktt.png)
### Add to Custom Storefront
This section will go over how to add Stripe into a React-based framework. The instructions are general instructions that you can use in your storefront.
#### Workflow Overview
The integration with stripe must have the following workflow:
1. During checkout when the user reaches the payment section, you should [create payment sessions](https://docs.medusajs.com/api/store#carts_postcartscartpaymentsessions). This will initialize the `payment_sessions` array in the `cart` object received. The `payment_sessions` is an array of available payment processors.
2. If Stripe is available as a payment processor, you should select Stripe as [the payment session](https://docs.medusajs.com/api/store#carts_postcartscartpaymentsession) for the current cart. This will initialize the `payment_session` object in the `cart` object to include data related to Stripe and the current payment session. This includes the payment intent and client secret.
3. After the user enters their card details and submits the form, confirm the payment with Stripe.
4. If the payment is confirmed successfully, [complete the cart](https://docs.medusajs.com/api/store#carts_postcartscartcomplete) in Medusa. Otherwise show an error.
#### Install Dependencies
Before you start the implementations you need to install the necessary dependencies. Youll be using Stripes React libraries to show the UI and handle the payment confirmation:
```bash npm2yarn
npm install --save @stripe/react-stripe-js @stripe/stripe-js
```
Youll also use Medusas JS Client to easily call Medusas REST APIs:
```bash npm2yarn
npm install @medusajs/medusa-js
```
#### Initialize Stripe
In this section, youll initialize Stripe without Medusas checkout workflow. Please note that this is one approach to add Stripe into your React project. You can check out [Stripes React documentation](https://stripe.com/docs/stripe-js/react) for other methods or components.
Create a container component that will hold the payment card component:
```jsx
import { useState } from "react"
import { Elements } from "@stripe/react-stripe-js"
import Form from "./Form"
import { loadStripe } from "@stripe/stripe-js"
const stripePromise = loadStripe("pk_...")
export default function Container() {
const [clientSecret, setClientSecret] = useState()
// TODO set clientSecret
return (
<div>
{clientSecret && (
<Elements stripe={stripePromise} options={{
clientSecret,
}}>
<Form clientSecret={clientSecret} cartId={cartId} />
</Elements>
)}
</div>
)
};
```
In this component, you need to use Stripes `loadStripe` function outside of the components implementation to ensure that Stripe doesnt re-load with every change. The function accepts the Publishable Key.
:::note
Youll probably store this Publishable Key in an environment variable depending on your framework. Its hard-coded here for simplicity.
:::
Then, inside the components implementation, you add a state variable `clientSecret` which youll retrieve in the next section.
Once the clientSecret is set, the `Elements` Stripe component will wrap a `Form` component youll create next. This is necessary because the `Elements` component allows child elements to get access to the cards inputs and their data using Stripes `useElements` hook.
Create a new file for the `Form` component with the following content:
```jsx
import {
CardElement,
useElements,
useStripe,
} from "@stripe/react-stripe-js"
export default function Form({ clientSecret, cartId }) {
const stripe = useStripe()
const elements = useElements()
async function handlePayment(e) {
e.preventDefault()
// TODO handle payment
}
return (
<form>
<CardElement />
<button onClick={handlePayment}>Submit</button>
</form>
)
};
```
This component shows a CardElement component from Stripes React library. You can use `stripe` to be able to confirm the payment later. The `elements` variable will be used to retrieve the entered card details safely.
#### Implement the Workflow
Youll now implement the workflow explained earlier. Youll use Medusas JS Client, so make sure to import it and initialize it in your `Container` component:
```jsx
import Medusa from "@medusajs/medusa-js"
export default function Container() {
const client = new Medusa()
// ...
}
```
:::note
In your storefront, youll probably be managing the Medusa client through a context for better performance.
:::
Then, in the place of the `//TODO` inside the `Container` element, initialize the payment sessions and create a payment session if Stripe is available:
```tsx
client.carts.createPaymentSessions(cart.id)
.then(({ cart }) => {
// check if stripe is selected
const isStripeAvailable = cart.payment_sessions?.some(
(session) => (
session.processor_id === "stripe"
)
)
if (!isStripeAvailable) {
return
}
// select stripe payment session
client.carts.setPaymentSession(cart.id, {
processor_id: "stripe",
}).then(({ cart }) => {
setClientSecret(cart.payment_session.data.client_secret)
})
})
```
:::note
Notice that here its assumed you have access to the `cart` object throughout your storefront. Ideally, the `cart` should be managed through a context. So, every time the cart is updated, for example, when the `createPaymentSessions` or `setPaymentSession` are called, the cart should be updated in the context to be accessed from other elements. In this case, you probably wouldnt need a `clientSecret` state variable as you can use the client secret directly from the `cart` object.
:::
Once the client secret is set, the form will be shown to the user.
The last step in the workflow is confirming the payment with Stripe and if its done successfully, completing the users order. This part is done in the `Form` component.
As youll use Medusas client again make sure to import it and initialize it:
```jsx
import Medusa from "@medusajs/medusa-js"
export default function Form() {
const client = new Medusa()
// ...
}
```
Then, replace the `//TODO` in the `handlePayment` function with the following content:
```jsx
return stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement),
billing_details: {
name,
email,
phone,
address: {
city,
country,
line1,
line2,
postal_code,
},
},
},
}).then(({ error, paymentIntent }) => {
// TODO handle errors
client.carts.complete(cartId).then(
(resp) => console.log(resp)
)
})
```
You use the `confirmCardPayment` method in the `stripe` object. Youll need to pass it the client secret, which you can have access to from the cart object if its available through the context.
This method also requires the customers information like `name`, `email`, and their address. Make sure to place the values for each based on your implementation.
Once the promise resolves you can handle the errors, if there are any. If not, you can complete the customers order using `complete` from Medusas client. This request expects the cart ID which you should have access to as well.
If you run your backend and storefront now, youll see the Stripe UI element and youll be able to make orders.
![Stripe Form](https://res.cloudinary.com/dza7lstvk/image/upload/v1668001190/Medusa%20Docs/Stripe/NOi8THw_xv3zsx.png)
---
## Capture Payments
After the customer places an order, youll be able to see the order on the admin panel. In the payment information under the “Payment” section, you should see a “Capture” button.
![Capture Payment](https://res.cloudinary.com/dza7lstvk/image/upload/v1668001205/Medusa%20Docs/Stripe/Iz55PVZ_p6hiz6.png)
Clicking this button allows you to capture the payment for an order. You can also refund payments if an order has captured payments.
Refunding or Capturing payments is reflected in your Stripes dashboard as well. This gives you access to all of Stripes analytical capabilities.
---
## Handled Webhook Events
This plugin handles the following Stripe webhook events:
- `payment_intent.succeeded`: If the payment is associated with a payment collection, the plugin will capture the payments within it. Otherwise, it checks first if an order is created and, if not, completes the cart which creates the order. It will also capture the payment of the order associated with the cart if it's not captured already.
- `payment_intent.amount_capturable_updated`: If no order is created for the cart associated with the payment, the cart is completed which creates the order.
- `payment_intent.payment_failed`: prints the error message received from Stripe into the logs.
---
## Troubleshooting
<Troubleshooting
sections={[
{
title: 'Stripe not showing in checkout',
content: <MissingPaymentProvider />
}
]}
/>
---
## See Also
- Check out [more plugins](../overview.mdx) you can add to your store.

View File

@@ -0,0 +1,299 @@
---
description: 'Learn how to integrate Algolia with the Medusa backend. Learn how to install the Algolia plugin into the Medusa backend and how to integrate it into a storefront.'
addHowToData: true
---
# Algolia
In this document, youll 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 backend and your storefront.
---
## Overview
[Algolia](https://www.algolia.com/) is a search engine service that allows developers to integrate advanced search functionalities into their websites including typo tolerance, recommended results, and quick responses.
Algolia can be used for a wide range of use cases, including ecommerce websites. By integrating Algolia into your ecommerce website, you can provide your customers with a better user experience and help them find what theyre looking for swifltly.
Through Medusa's flexible plugin system, it is possible to add a search engine to your Medusa backend and storefront using Algolia with just a few steps.
---
## Prerequisites
### Medusa Components
It is required to have a Medusa backend installed before starting with this documentation. If not, please follow along with the [quickstart guide](../../development/backend/install.mdx) to get started in minutes. The Medusa backend must also have an event bus module installed, which is available when using the default Medusa backend starter.
### Algolia Account
You need to [create an Algolia account](https://www.algolia.com/users/sign_up) before you follow this documentation. Algolia offers a free plan to get started quickly.
---
## Create an Algolia App
The first step is to create an Algolia app for your Medusa backend. To create one, open the [Applications page](https://www.algolia.com/account/applications) or, on your dashboard, go to Settings then choose Applications.
On the Applications page, click on the New application button at the top right.
![Click on New application button at the top right](https://res.cloudinary.com/dza7lstvk/image/upload/v1667999820/Medusa%20Docs/Algolia/WxckgS2_eygl8l.png)
In the new page that opens, optionally enter a name for the application and choose a subscription plan. You can choose the Free plan for now, but its recommended to switch to the Pay-as-you-go plan as your business grows.
![Optionally enter a name for the application and choose a subscription plan](https://res.cloudinary.com/dza7lstvk/image/upload/v1667999980/Medusa%20Docs/Algolia/jpM2EBU_fui1lg.png)
Once youre done, click on the Next Step button. If you picked Pay as you go service, youll need to enter billing details before you proceed.
Then, youll be asked to pick a region for your application. Once youre done, click on Review Application Details.
![Select a region then click on Review Application Details at the bottom right](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000005/Medusa%20Docs/Algolia/fahf2J2_qgm7sa.png)
In the last step, youll see a summary of your order. If all looks good, check the checkboxes at the end of the form to indicate that you agree to the terms and conditions. Then, click on the Create Application button.
![Summary of your application's order with the terms and agreement checkboxes checked](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000019/Medusa%20Docs/Algolia/PTI2Swq_a1qbi5.png)
---
## Retrieve API Keys
To retrieve the API keys that youll use in the next sections, go to Settings, then choose API Keys in the Team and Access section.
![Click on API Keys in the Team and Access section of your settings](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000028/Medusa%20Docs/Algolia/gnORibC_msuur5.png)
On this page, youll find the Application ID, Search-Only API Key, and Admin API Key. Youll need the Application ID and Admin API Key for the Medusa backend. As for the storefront, youll need the Application ID and Search-Only API Key.
:::note
If you have more than one application in your Algolia account, make sure youre viewing the keys of the correct application by checking the Application dropdown at the top left.
:::
![Application ID, Search-Only API Key, and Admin API Key can be found in the API Keys page](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000037/Medusa%20Docs/Algolia/i50Irki_jmtyk6.png)
---
## Install the Algolia Plugin
In the directory of your Medusa backend, run the following command to install the Algolia plugin:
```bash npm2yarn
npm install medusa-plugin-algolia
```
Then, add the following environment variables to your Medusa backend:
```bash
ALGOLIA_APP_ID=<YOUR_APP_ID>
ALGOLIA_ADMIN_API_KEY=<YOUR_ADMIN_API_KEY>
```
Where `<YOUR_APP_ID>` and `<YOUR_ADMIN_API_KEY>` are respectively the Application ID and Admin API Key found on the [API Keys page](#retrieve-api-keys).
Finally, in `medusa-config.js` add the following item into the `plugins` array:
```js title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-plugin-algolia`,
options: {
applicationId: process.env.ALGOLIA_APP_ID,
adminApiKey: process.env.ALGOLIA_ADMIN_API_KEY,
settings: {
// index settings...
},
},
},
]
```
### Index Settings
Under the `settings` key of the plugin's options, you can add settings specific to each index. The settings are of the following format:
```js
const plugins = [
// ...
{
resolve: `medusa-plugin-algolia`,
options: {
// other options...
settings: {
indexName: {
indexSettings: {
searchableAttributes,
attributesToRetrieve,
},
transformer,
},
},
},
},
]
```
Where:
- `indexName`: the name of the index to create in Algolia. For example, `products`. Its value is an object containing the following properties:
- `indexSettings`: an object that includes the following properties:
- `searchableAttributes`: an array of strings indicating the attributes in the product entity that can be searched.
- `attributesToRetrieve`: an array of strings indicating the attributes in the product entity that should be retrieved in the search results.
- `transformer`: an optional function that accepts a product as a parameter and returns an object to be indexed. This allows you to have more control over what you're indexing. For example, you can add details related to variants or custom relations, or you can filter out certain products.
Using this index settings structure, you can add more than one index.
:::tip
These settings are just examples of what you can pass to the Algolia provider. If you need to pass more settings to the Algolia SDK you can pass it inside `indexSettings`.
:::
Here's an example of the settings you can use:
```js title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-plugin-algolia`,
options: {
// other options...
settings: {
products: {
indexSettings: {
searchableAttributes: ["title", "description"],
attributesToRetrieve: [
"id",
"title",
"description",
"handle",
"thumbnail",
"variants",
"variant_sku",
"options",
"collection_title",
"collection_handle",
"images",
],
},
transformer: (product) => ({
objectID: product.id,
// other attributes...
}),
},
},
},
},
]
```
---
## Test the Algolia Plugin
Run your Medusa backend with the following command:
```bash npm2yarn
npx medusa develop
```
The quickest way to test that the integration is working is by sending a `POST` request to `/store/products/search`. This endpoint accepts a `q` body parameter of the query to search for and returns in the result the products that match this query.
![Postman request send to the search endpoint that retrieves products using Algolia](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000054/Medusa%20Docs/Algolia/IHeTsi7_ymhb2p.png)
You can also check that the products are properly indexed by opening your Algolia dashboard and choosing Search from the left sidebar. Youll find your products that are on your Medusa backend added there.
:::note
If you have more than one application on your Algolia account, make sure youre viewing the keys of the correct one by checking the Application dropdown at the top left.
:::
![Products from the Medusa backend can be seen on the Algolia dashboard](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000071/Medusa%20Docs/Algolia/wkXzUH0_dowyxj.png)
### Add or Update Products
If you add or update products on your Medusa backend, the addition or update will be reflected in the Algolia indices.
:::note
This feature is only available if you have an event module installed in your Medusa backend, as explained in the Prerequisites section.
:::
---
## Add Search to your Storefront
In this section, youll learn how to add the UI on your storefront to allow searching with Algolia. This section has instructions for Medusas [Next.js Starter Template](../../starters/nextjs-medusa-starter.mdx) as well as React-based frameworks.
### Storefront Prerequisites
It is assumed you already have a storefront set up and working with the Medusa backend, as this section only covers how to add the search UI.
:::tip
If you dont have a storefront set up, you can use the [Next.js Starter Template](../../starters/nextjs-medusa-starter.mdx) that Medusa provides.
:::
### Add to Next.js Starter Template
The Next.js Starter Template has the Algolia integration available out of the box. To get it working, you just need to follow three steps.
First, ensure that the search feature is enabled in `store.config.json`:
```json title=store.config.json
{
"features": {
"search": true
}
}
```
Then, add the necessary environment variables:
```bash
NEXT_PUBLIC_SEARCH_APP_ID=<YOUR_APP_ID>
NEXT_PUBLIC_SEARCH_API_KEY=<YOUR_SEARCH_API_KEY>
NEXT_PUBLIC_SEARCH_INDEX_NAME=products
```
Where `<YOUR_APP_ID>` and `<YOUR_SEARCH_API_KEY>` are respectively the Application ID and Search-Only API Key on the [API Keys page](#retrieve-api-keys).
Finally, change the code in `src/lib/search-client.ts` to the following:
```jsx title=src/lib/search-client.ts
import algoliasearch from "algoliasearch/lite"
const appId = process.env.NEXT_PUBLIC_SEARCH_APP_ID || ""
const apiKey =
process.env.NEXT_PUBLIC_SEARCH_API_KEY || "test_key"
export const searchClient = algoliasearch(appId, apiKey)
export const SEARCH_INDEX_NAME =
process.env.NEXT_PUBLIC_SEARCH_INDEX_NAME || "products"
```
If you run your Next.js Starter Template now while the Medusa backend is running, the search functionality will be available in your storefront.
:::note
To make sure the Next.js Starter Template properly displays the products in the search result, include in the `attributesToRetrieve` setting of the Algolia plugin on the Medusa backend at least the fields `title`, `handle`, `description`, and `thumbnail`.
:::
![Search pop up in the Next.js Starter Template](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000082/Medusa%20Docs/Algolia/1f9qqK6_c0z8zi.png)
### Add to Other Storefronts
To integrate Algolia's search functionalities in your storefront, please refer to [Algolia's InstantSearch.js documentation](https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/). You'll find packages for different frontend frameworks and how you can use them.
---
## See Also
- [Deploy your Medusa backend](../../deployments/server/index.mdx)
- [Deploy your storefront](../../deployments/storefront/index.mdx)

View File

@@ -0,0 +1,7 @@
import DocCardList from '@theme/DocCardList';
# Search Plugins
If you can't find your search provider, try checking the [Community Plugins Library](https://medusajs.com/plugins/?filters=Search&categories=Search). You can also [create your own search service](../../development/search/create.md).
<DocCardList />

View File

@@ -0,0 +1,263 @@
---
description: 'Learn how to integrate MeiliSearch with the Medusa backend. Learn how to install the MeiliSearch plugin on the Medusa backend and integrate it into the storefront.'
addHowToData: true
---
# MeiliSearch
In this document, youll 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 Backend and your storefront.
## Overview
[MeiliSearch](https://www.meilisearch.com/) is a super-fast, open source search engine built in Rust. It comes with a wide range of features including typo-tolerance, filtering, and sorting.
MeiliSearch also provides a pleasant developer experience, as it is extremely intuitive and newcomer-friendly. So, even if you're new to the search engine ecosystem, [their documentation](https://docs.meilisearch.com/) is resourceful enough for everyone to go through and understand.
Through Medusa's flexible plugin system, it is possible to add a search engine to your Medusa backend and storefront using MeiliSearch with just a few steps.
---
## Prerequisites
### Medusa Components
It is required to have a Medusa backend installed before starting with this documentation. If not, please follow along with the [quickstart guide](../../development/backend/install.mdx) to get started in minutes. The Medusa backend must also have an event bus module installed, which is available when using the default Medusa backend starter.
### MeiliSearch Instance
You must install MeiliSearch to use it with Medusa. You can follow [this documentation to install MeiliSearch](https://docs.meilisearch.com/learn/getting_started/quick_start.html#setup-and-installation) either locally or on a cloud.
Furthermore, you should create a master key for your MeiliSearch instance. If you dont have one created, follow [this guide](https://docs.meilisearch.com/learn/security/master_api_keys.html#protecting-a-meilisearch-instance) to create a master key.
---
## Install the MeiliSearch Plugin
In the directory of your Medusa backend, run the following command to install the MeiliSearch plugin:
```bash npm2yarn
npm install medusa-plugin-meilisearch
```
Then, add the following environment variables to your Medusa backend:
```bash
MEILISEARCH_HOST=<YOUR_MEILISEARCH_HOST>
MEILISEARCH_API_KEY=<YOUR_MASTER_KEY>
```
Where `<YOUR_MEILISEARCH_HOST>` is the host of your MeiliSearch instance. By default, if MeiliSearch is installed locally, the host is `http://127.0.0.1:7700`.
`<YOUR_MASTER_KEY>` is the master key of your MeiliSearch instance.
Finally, in `medusa-config.js` add the following item into the `plugins` array:
```jsx title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-plugin-meilisearch`,
options: {
// config object passed when creating an instance
// of the MeiliSearch client
config: {
host: process.env.MEILISEARCH_HOST,
apiKey: process.env.MEILISEARCH_API_KEY,
},
settings: {
// index settings...
},
},
},
]
```
### Index Settings
Under the `settings` key of the plugin's options, you can add settings specific to each index. The settings are of the following format:
```js
const plugins = [
// ...
{
resolve: `medusa-plugin-meilisearch`,
options: {
// other options...
settings: {
indexName: {
indexSettings: {
searchableAttributes,
displayedAttributes,
},
primaryKey,
transformer,
},
},
},
},
]
```
Where:
- `indexName`: the name of the index to create in MeiliSearch. For example, `products`. Its value is an object containing the following properties:
- `indexSettings`: an object that includes the following properties:
- `searchableAttributes`: an array of strings indicating the attributes in the product entity that can be searched.
- `displayedAttributes`: an array of strings indicating the attributes in the product entity that should be displayed in the search results.
- `primaryKey`: an optional string indicating which property acts as a primary key of a document. It's used to enforce unique documents in an index. The default value is `id`. You can learn more in [MeiliSearch's documentation](https://docs.meilisearch.com/learn/core_concepts/primary_key.html#primary-field).
- `transformer`: an optional function that accepts a product as a parameter and returns an object to be indexed. This allows you to have more control over what you're indexing. For example, you can add details related to variants or custom relations, or you can filter out certain products.
Using this index settings structure, you can add more than one index.
:::tip
These settings are just examples of what you can pass to the MeiliSearch provider. If you need to pass more settings to the MeiliSearch SDK you can pass it inside `indexSettings`.
:::
Here's an example of the settings you can use:
```js title=medusa-config.js
const plugins = [
// ...
{
resolve: `medusa-plugin-meilisearch`,
options: {
// other options...
settings: {
products: {
indexSettings: {
searchableAttributes: [
"title",
"description",
"variant_sku",
],
displayedAttributes: [
"title",
"description",
"variant_sku",
"thumbnail",
"handle",
],
},
primaryKey: "id",
transformer: (product) => ({
id: product.id,
// other attributes...
}),
},
},
},
},
]
```
---
## Test MeiliSearch Plugin
Make sure your MeiliSearch instance is running. If youre unsure how to run it, you can check the [installation documentation](https://docs.meilisearch.com/learn/getting_started/quick_start.html#setup-and-installation) for the command to run the MeiliSearch instance.
Then, run the Medusa backend:
```bash npm2yarn
npx medusa develop
```
The quickest way to test that the integration is working is by sending a `POST` request to `/store/products/search`. This endpoint accepts a `q` body parameter of the query to search for and returns in the result the products that match this query.
![Postman request to search endpoint that shows results returned from the search engine](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000265/Medusa%20Docs/MeiliSearch/RCGquxU_um3dvn.png)
You can also check that the products are properly indexed by opening the MeiliSearch host URL in your browser, which is `http://127.0.0.1:7700/` by default. Youll find your products that are on your Medusa backend added there.
![MeiliSearch dashboard showing products from the Medusa backend indexed](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000277/Medusa%20Docs/MeiliSearch/5sk3jyP_i3swkn.png)
### Add or Update Products
If you add or update products on your Medusa backend, the addition or update will be reflected in the MeiliSearch indices.
:::note
This feature is only available if you have an event module installed in your Medusa backend, as explained in the Prerequisites section.
:::
---
## Add Search to your Storefront
In this section, youll learn how to add the UI on your storefront to allow searching with MeiliSearch. This section has instructions for Medusas [Next.js Starter Template](../../starters/nextjs-medusa-starter.mdx) as well as React-based frameworks.
### Storefront Prerequisites
It is assumed you already have a storefront set up and working with the Medusa backend, as this section only covers how to add the search UI.
:::tip
If you dont have a storefront set up, you can use the [Next.js Starter Template](../../starters/nextjs-medusa-starter.mdx) that Medusa provides.
:::
Furthermore, you must create an API key in your MeiliSearch instance that will be used to search on the storefront. To do that, run the following command in your terminal while the MeiliSearch instance is running:
```bash
curl \
-X POST '<MEILISEARCH_HOST>/keys' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <MEILISEARCH_MASTER_KEY>' \
--data-binary '{
"description": "Search products",
"actions": ["search"],
"indexes": ["products"],
"expiresAt": "2024-01-01T00:00:00Z"
}'
```
Make sure to replace `<MEILISEARCH_HOST>` and `<MEILISEARCH_MASTER_KEY>` accordingly.
If this request is successful, the API key will be available under the `key` property returned in the JSON response.
### Add to Next.js Starter Template
The Next.js Starter Template has the MeiliSearch integration available out of the box. To get it working, you just need to follow two steps.
First, ensure that the search feature is enabled in `store.config.json`:
```json title=store.config.json
{
"features": {
"search": true
}
}
```
Then, add the necessary environment variables:
```bash
NEXT_PUBLIC_SEARCH_ENDPOINT=<YOUR_MEILISEARCH_HOST>
NEXT_PUBLIC_SEARCH_API_KEY=<YOUR_API_KEY>
NEXT_PUBLIC_SEARCH_INDEX_NAME=products
```
Make sure to replace `<YOUR_MEILISEARCH_HOST>` with your MeiliSearch host and `<YOUR_API_KEY>` with the API key you created as instructed in the [Storefront Prerequisites](#storefront-prerequisites) section.
If you run your Next.js Starter Template now while the Medusa backend and the MeiliSearch services are running, the search functionality will be available in your storefront.
:::note
To make sure the Next.js Starter Template properly displays the products in the search result, include in the `displayedAttributes` setting of the MeiliSearch plugin on the Medusa backend at least the fields `title`, `handle`, `description`, and `thumbnail`.
:::
![Search Result on Next.js Starter Template](https://res.cloudinary.com/dza7lstvk/image/upload/v1668000298/Medusa%20Docs/MeiliSearch/gQVWvH2_datei5.png)
### Add to Other Storefronts
To integrate MeiliSearch's search functionalities in your storefront, please refer to [MeiliSearch's documentation](https://docs.meilisearch.com/learn/what_is_meilisearch/sdks.html#front-end-tools). They offer different tools that you can use based on the frontend framework of your storefront.
---
## See Also
- [Deploy your Medusa backend](../../deployments/server/index.mdx).
- [Deploy your storefront](../../deployments/storefront/index.mdx).

View File

@@ -0,0 +1,7 @@
import DocCardList from '@theme/DocCardList';
# Source Plugins
Source plugins are plugins that allow you to migrate from other ecommerce platforms to Medusa.
<DocCardList />

View File

@@ -0,0 +1,89 @@
---
addHowToData: true
---
# Shopify Source Plugin
This document will guide you through installing the shopify source plugin on your Medusa backend.
## Overview
If you're migrating from Shopify to Medusa, this plugin will facilitate the process for you. It migrates data related to your products on Shopify to Medusa. It also registers a scheduled job that runs periodically and ensures your data is synced between Shopify and Medusa.
---
## Prerequisites
### Medusa Backend
A Medusa backend is required to be set up before following along with this document. You can follow the [quickstart guide](../../create-medusa-app.mdx) to get started in minutes.
### Shopify Account
Using this plugin requires having a Shopify account with access to development keys and resources.
### Private Shopify App
This plugin authenticates with Shopify through a private app that has Read access to products.
To create a private app:
1. Open your Shopify store's dashboard
2. Choose Apps from the sidebar
3. Scroll down and click on "Manage private apps"
4. If asked, enable private app development.
5. Once enabled, click on the "Create private app" button.
6. In the form, enter the app's name and email.
7. In the Admin API section, click on "Show inactive Admin API permissions" then, for Products, choose "Read Access".
8. Once done, click on the "Save" button.
9. Click the "Create App" button in the pop-up that shows up.
10. Copy the Password to use for the plugin's configurations.
---
## Install Plugin
In the directory of your Medusa backend, run the following command to install the plugin:
```bash npm2yarn
npm install medusa-source-shopify
```
Then, add the following environment variables to `.env`:
```bash
SHOPIFY_DOMAIN=<YOUR_SHOPIFY_DOMAIN>
SHOPIFY_PASSWORD=<YOUR_SHOPIFY_PASSWORD>
```
Where:
- `<YOUR_SHOPIFY_DOMAIN>` is the subdomain of the Shopify store that you're migrating. If you're not sure what it is, your store's domain should be of the format `<DOMAIN>.myshopify.com`. The `<DOMAIN>` is the value of this environment variable.
- `<YOUR_SHOPIFY_PASSWORD>` is the password for the [private app](#private-shopify-app) you created.
Finally, add the plugin to the `plugins` array in `medusa-config.js`:
```js title=medusa-config.js
const plugins = [
// ...,
{
resolve: "medusa-source-shopify",
options: {
domain: process.env.SHOPIFY_DOMAIN,
password: process.env.SHOPIFY_PASSWORD,
},
},
]
```
---
## Test the Plugin
To test the plugin, run the following command in the directory of the Medusa backend to start the backend:
```bash
npx medusa develop
```
As the backend starts, so does the migration script. The products and its data will be migrated into Medusa.