ДокументацияРуководство РазработчикаГлубокая Интеграция с MedusaJS 2.0

Интеграция коммерческого ядра Medusa 2.0 и рабочие процессы

Medusa 2.0 — это передовое ядро электронной коммерции, управляющее корзинами, складскими остатками, заказами и платежными шлюзами.

Важное примечание о Medusa 2.0
Платформа построена на базе Medusa v2 с новой системой Workflows и двукратным приростом производительности.

1. Модульная архитектура и мгновенная синхронизация в Medusa v2

Фронтенд Next.js взаимодействует с Medusa через официальный SDK с использованием Publishable API Key, сгенерированного при установке.

product-strapi.tsУправление товарами, вариантами, цветовыми опциями и размерными сетками.
review-product.tsБыстрая обработка корзины покупок и мгновенное применение промокодов.
wishlist-customer.tsТочный расчет адресов доставки, налогов и тарифов логистических служб.
question-product.tsОбновление статуса заказа и автоматическое резервирование остатков при оплате.
store-admin/src/links/review-product.ts
typescript
import { defineLink } from "@medusajs/framework/modules-sdk"
import ProductModule from "@medusajs/medusa/product"
import ProductReviewModule from "../modules/product-review"
export default defineLink(
ProductModule.linkable.product,
ProductReviewModule.linkable.productReview
)

2. Настройка переменных окружения (.env)

Обязательные переменные для подключения фронтенда к ядру Medusa:

Переменные подключения к Medusa в .env
bash
npm run seed
Инициализация JS-клиента Medusa
bash
npx medusa exec ./src/scripts/seed-30-products.ts
Пример запроса на получение списка товаров
bash
npx medusa exec ./src/scripts/sync-meilisearch.ts
Пример операции добавления товара в корзину
bash
npx medusa exec ./src/scripts/delete-all-products.ts

3. Рабочие процессы заказов (Workflows) и внутренняя архитектура

src/lib/data/products.ts
typescript
import { sdk } from "@lib/config"
import { HttpTypes } from "@medusajs/types"
import { getAuthHeaders, getCacheOptions } from "./cookies"
import { getLocaleHeader } from "@lib/util/get-locale-header"
import { getRegion, retrieveRegion } from "./regions"
import { isNetworkFetchError, warnMedusaUnreachable } from "@lib/util/medusa-fetch"
export const listProducts = async ({
pageParam = 1,
queryParams,
countryCode,
regionId,
disableAuth = false,
}: {
pageParam?: number
queryParams?: HttpTypes.FindParams & HttpTypes.StoreProductListParams
countryCode?: string
regionId?: string
disableAuth?: boolean
}): Promise<{
response: { products: HttpTypes.StoreProduct[]; count: number }
nextPage: number | null
queryParams?: HttpTypes.FindParams & HttpTypes.StoreProductListParams
}> => {
if (!countryCode && !regionId) {
throw new Error("Country code or region ID is required")
}
const limit = queryParams?.limit || 12
const _pageParam = Math.max(pageParam, 1)
const offset = _pageParam === 1 ? 0 : (_pageParam - 1) * limit
let region: HttpTypes.StoreRegion | undefined | null
if (countryCode) {
region = await getRegion(countryCode, disableAuth)
} else {
region = await retrieveRegion(regionId!, disableAuth)
}
if (!region) {
return { response: { products: [], count: 0 }, nextPage: null }
}
const headers = {
...(disableAuth ? {} : await getAuthHeaders()),
...(await getLocaleHeader(disableAuth)),
} as Record<string, string>
const next = {
...(disableAuth
? { tags: ["store-products"] }
: await getCacheOptions("store-products")),
revalidate: 3600,
}
try {
return await sdk.client
.fetch<{ products: HttpTypes.StoreProduct[]; count: number }>(
`/store/products`,
{
method: "GET",
query: {
limit,
offset,
region_id: region?.id,
fields:
"*variants.calculated_price,+variants.inventory_quantity,*variants.images,*options,*options.values,*variants.options,+metadata,+tags",
...queryParams,
},
headers,
next,
cache: "force-cache",
}
)
.then(({ products, count }) => {
const nextPage = count > offset + limit ? pageParam + 1 : null
return {
response: { products, count },
nextPage,
queryParams,
}
})
} catch (error) {
if (isNetworkFetchError(error)) {
warnMedusaUnreachable("listProducts")
return {
response: { products: [], count: 0 },
nextPage: null,
queryParams,
}
}
throw error
}
}

4. Советы по управлению товарами и кэшированию цен

Данные каталога кэшируются в Next.js с тегами вида medusa-products и автоматически обновляются при изменении цен.

Инвалидация кэша товаров Medusa
env
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password
SMTP_FROM_ADDRESS=noreply@yourdomain.com
CONTACT_FORM_RECIPIENT=info@yourdomain.com
SENDPULSE_API_ID=your_sendpulse_id
SENDPULSE_API_SECRET=your_sendpulse_secret