31 июля 2026 г.
Продукт

Представляем Модуль интеграций для Medusa

Новый модуль для Medusa: плагины просто объявляют свои настройки, а администраторы управляют ими в Admin, без правок medusa-config и без передеплоя.

Представляем Модуль интеграций для Medusa

Мы в Gorgo более года делаем плагины для Medusa, которые подключают магазины к платёжным провайдерам, службам фулфилмента и ERP-системам. И в каждом всплывал один и тот же вопрос: как передавать плагину параметры и как ими управлять. API-ключи, настройки подключений и другая пользовательская конфигурация обычно задаются через и переменные окружения, поэтому любое изменение требует правки кода и передеплоя. Чтобы этого избежать, для каждого плагина приходится строить собственный UI, пробрасывать API, валидировать поля и писать воркфлоу.

Сегодня мы представляем Модуль интеграций для Medusa, который избавляет от этой рутины. Плагины просто объявляют свои параметры через провайдер модуля, а администратор магазина управляет ими в Admin через сгенерированный интерфейс, без правок и без передеплоя.

Проблема с настройками плагинов

Настройка плагина Medusa обычно сводится к двум проблемам, и обе сложнее, чем должны быть.

  • Управление через и переменные окружения: Любое изменение (новый API-ключ, переключение с теста на боевой режим) требует доступа к коду и полного передеплоя.
  • Сложность разработки UI: Полноценное управление настройками означает формы и модальные окна, валидацию полей, API-роуты и воркфлоу, и всё это пишется и поддерживается отдельно для каждого плагина.

Что делает Модуль интеграций

Модуль интеграций выносит настройки плагина из кода в Admin и базу данных. Плагин описывает нужные ему параметры, администратор магазина задаёт их в разделе Настройки → Интеграции, а во время выполнения плагин читает готовые и провалидированные значения.

Как автор, вы только описываете схему настроек, а UI, хранение, шифрование и валидацию модуль берёт на себя. Если же плагину нужно что-то, чего сгенерированный UI не поддерживает, можно создать кастомный виджет.

Как это работает

Вы объявляете дескриптор через , где перечислены ваши опции и их типы, секции, в которые они группируются, и правила валидации. Из этого одного объявления Admin генерирует страницу настроек: подходящий UI-элемент управления для каждого поля, валидацию, условное отображение и маскированные секреты. Вам не нужно писать ни UI, ни API для CRUD-операций, ни связанные воркфлоу.

Минимальный провайдер состоит из дескриптора и класса, который его поставляет:

src/providers/integration-acme/services/acme.ts
1import { AbstractIntegrationProvider, defineIntegration } from "@gorgo/medusa-integration"
2
3const descriptor = defineIntegration({
4 category: "payment",
5 displayName: "acme.name",
6 supportsMultipleInstances: true,
7
8 options: {
9 apiKey: {
10 type: "string",
11 required: true,
12 secret: true,
13 label: "acme.fields.apiKey",
14 },
15 mode: {
16 type: "enum",
17 values: ["test", "live"],
18 default: "test",
19 label: "acme.fields.mode",
20 },
21 },
22
23 sections: [
24 {
25 id: "credentials",
26 title: "acme.sections.credentials",
27 options: ["apiKey", "mode"]
28 },
29 ],
30
31 testConnection: async ({ options }) => {
32 const ok = await pingAcme(options.apiKey, options.mode)
33 return ok ? { status: "passed" } : { status: "failed", message: "Invalid API key" }
34 },
35})
36
37export class AcmeIntegrationProvider extends AbstractIntegrationProvider {
38 static identifier = "acme"
39 get descriptor() {
40 return descriptor
41 }
42}

Значения вроде являются i18n-ключами и переводятся стандартными средствами локализации Medusa, а сами переводы хранятся в .

Далее, зарегистрируйте провайдер в :

medusa-config.ts
1const ACME_INTEGRATION_ID = "acme-1"
2
3module.exports = defineConfig({
4 plugins: [
5 {
6 resolve: "@acme/medusa-payment-acme",
7 options: {},
8 },
9 {
10 resolve: "@gorgo/medusa-integration",
11 options: {
12 encryptionKey: process.env.INTEGRATION_ENCRYPTION_KEY,
13 providers: [
14 {
15 resolve: "@acme/medusa-payment-acme/providers/integration-acme",
16 id: ACME_INTEGRATION_ID,
17 },
18 ],
19 },
20 },
21 ],
22 modules: [
23 {
24 resolve: "@medusajs/medusa/payment",
25 options: {
26 providers: [
27 {
28 resolve: "@acme/medusa-payment-acme/providers/payment-acme",
29 id: "acme",
30 options: {
31 id: ACME_INTEGRATION_ID // совпадает с id провайдера интеграции выше
32 },
33 },
34 ],
35 },
36 },
37 ],
38})

Здесь задаёт ключ экземпляра интеграции. Тот же нужно передать потребителю, в примере это платёжный провайдер. Именно по нему модуль находит и возвращает значения параметров нужной интеграции. Эти два задаются в независимых местах конфигурации, поэтому синхронизировать их нужно вручную, и это удобнее делать через константу.

(здесь ) задаёт ключ AES-256-GCM, которым модуль шифрует секреты в базе. Задайте его в переменных окружения и не меняйте, иначе сохранённые секреты станут нечитаемыми.

Во время работы плагин читает значения своих параметров где угодно через и получает типизированный расшифрованный объект. Неполные или отключённые настройки не резолвятся, поэтому незаполненный черновик не будет возвращён.

src/providers/payment-acme/services/acme.ts
1import { resolveIntegrationOptions } from "@gorgo/medusa-integration"
2
3abstract class AcmeBase extends AbstractPaymentProvider {
4 constructor(options) {
5 super(options)
6 const { apiKey, mode } = await resolveIntegrationOptions({
7 identifier: "acme",
8 instance_id: options.id
9 })
10 }
11
12 // ...
13}

Что вы получаете

Один дескриптор даёт вашему плагину полноценный интерфейс настроек:

  1. Управление настройками в разделе Настройки → Интеграции, без правок и без передеплоя.
  2. Гибкая типизация параметров, условное отображение, обязательность полей и правила валидации.
  3. Хранение секретов в зашифрованном виде (AES-256-GCM), без передачи в браузер.
  4. Поддержка нескольких экземпляров настроек для магазинов, у которых заведено сразу по несколько аккаунтов в сторонних сервисах.
  5. Кнопка «Проверить соединение» для тестирования подключения.
  6. Кастомные виджеты для UI, когда нужен UI за пределами стандартного.
  7. Типизированный, уже расшифрованный конфиг, который резолвится по запросу.

Для авторов плагинов

Если вы уже поддерживаете плагин для Medusa, переход на Модуль интеграций сводится к простому переносу существующих опций в дескриптор провайдера модуля. А читать их нужно через там, где сейчас вы читаете переменные окружения или . Все свои провайдеры мы мигрировали именно так (платежи, фулфилмент и ERP), а полный пример приложения Medusa со всеми подключёнными провайдерами можно посмотреть в репозитории.

Пошаговое руководство проводит через весь процесс миграции.

Поиск интеграций в Admin

Модуль также отображает каталог доступных интеграций прямо в Admin. Администраторы магазина могут найти ваш плагин и установить его с помощью небольшой инструкции. А поскольку UI настроек генерируется, ваш плагин выглядит аккуратно и нативно, в одном стиле с Medusa Admin.

Поиск интеграций в Admin

Как начать

Установите модуль:

npm install @gorgo/medusa-integration

Далее объявите настройки вашего плагина и другие метаданные, подключите его в качестве провайдера Модуля интеграций и переключите на чтение параметров через . Полное руководство по установке и использованию описано в документации, а исходники на GitHub.

Что дальше

Модуль интеграций сейчас в бете, и мы активно его развиваем, добавляем встроенные интеграции и расширяем каталог. Если вы разрабатываете плагин для Medusa, мы поможем перейти на модуль. Если у вас магазин на Medusa, попробуйте его и расскажите, чего не хватает.

Присоединяйтесь к обсуждению в Telegram-сообществе Medusa. Issues и Pull Request'ы всегда приветствуются в репозитории на GitHub.