DocumentaciónGuía para DesarrolladoresIntegración Profunda con MedusaJS 2.0

Integración del Motor Comercial Medusa 2.0 y Flujos de Trabajo

Medusa 2.0 es el núcleo de comercio electrónico avanzado encargado de carritos, inventario, pedidos y múltiples métodos de pago.

Nota Importante sobre Medusa 2.0
La plataforma está construida sobre Medusa v2, ofreciendo el potente sistema de Workflows y un rendimiento dos veces más rápido.

1. Arquitectura Modular y Sincronización Inmediata en Medusa v2

El frontend de Next.js se comunica con Medusa mediante el SDK oficial utilizando la Publishable API Key generada durante la instalación.

product-strapi.tsGestión impecable de productos, variantes, opciones de color y tallas.
review-product.tsProcesamiento ágil del carrito de compras y aplicación instantánea de cupones.
wishlist-customer.tsCálculo exacto de direcciones de entrega, impuestos y costos de envío.
question-product.tsActualización del estado del pedido y descuento automático de inventario al completar el pago.
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. Configuración de Variables de Entorno (.env)

Variables obligatorias para conectar el frontend con el núcleo de Medusa:

Variables de Conexión a Medusa en .env
bash
npm run seed
Inicialización del Cliente JS de Medusa
bash
npx medusa exec ./src/scripts/seed-30-products.ts
Ejemplo de Consulta para Obtener Productos
bash
npx medusa exec ./src/scripts/sync-meilisearch.ts
Ejemplo de Operación para Añadir Producto al Carrito
bash
npx medusa exec ./src/scripts/delete-all-products.ts

3. Flujos de Trabajo de Pedidos y Arquitectura Interna

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. Consejos para la Gestión de Productos y Caché de Precios

Los datos del catálogo se almacenan en caché en Next.js con etiquetas como medusa-products y se actualizan al cambiar precios.

Revalidación de Caché de Productos de 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