Разработка headless интернет-магазина на Vendure (NestJS/TypeScript)

Представьте: нужно внедрить сложную систему скидок для оптовиков, интегрироваться с 1С и обеспечить работу в 10 странах. Готовые SaaS-решения не подходят — лицензии дороги (например, commercetools берет существенную плату с оборота), а кастомизация ограничена API. Мы, команда с 10-летним опытом в e-

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Разработка headless интернет-магазина на Vendure (NestJS/TypeScript)
Сложный
от 2 недель до 3 месяцев

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1422
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1288
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    984
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1250
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    988
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    1001

Представьте: нужно внедрить сложную систему скидок для оптовиков, интегрироваться с 1С и обеспечить работу в 10 странах. Готовые SaaS-решения не подходят — лицензии дороги (например, commercetools берет существенную плату с оборота), а кастомизация ограничена API. Мы, команда с 10-летним опытом в e-commerce, часто сталкиваемся с такими задачами и предлагаем Vendure — open-source фреймворк на NestJS и TypeScript. Он дает полный контроль: от схемы БД до GraphQL-резолверов. Экономия на лицензиях по сравнению с SaaS может составлять до 70% при оборотах от $500k в год. В одном из проектов мы заменили commercetools на Vendure для крупного b2b-магазина. Результат — экономия $15k в месяц и возможность реализовать специфическую логику расчета налогов без костылей.

Какие проблемы решаем?

Мультитенантность. Когда нужно вести несколько магазинов на одном ядре (разные регионы, бренды), Vendure предлагает механизм Channels. Каждый канал изолирует каталог, цены, валюту, налоги и платёжные методы. Один инстанс легко обслуживает десятки магазинов с раздельными сущностями. Переключение происходит через заголовок vendure-token в запросах к Shop API. Типичная ошибка новичков — не указать токен, тогда запрос обрабатывается в канале по умолчанию, что ведет к путанице.

Гибкая логика налогов и доставки. Стандартные решения не всегда покрывают требования. Vendure позволяет подменять TaxCalculationStrategy и ShippingCalculator через плагины. Мы реализовали кастомный расчет налогов для товаров с разными ставками в зависимости от региона и типа покупателя.

Интеграция с платежными системами. Из коробки — Stripe. Через кастомные обработчики можно подключить любую систему с API. Мы сделали интеграцию с YooKassa с полным циклом: создание платежа, подтверждение, возврат. Код обработчика — в разделе ниже.

Как мы это делаем: конфигурация и кастомные плагины

Стандартная структура проекта включает каталог plugins для кастомных модулей, email-handlers и payment-handlers. Пример конфигурации:

// src/vendure-config.ts import { VendureConfig } from "@vendure/core"; import { defaultEmailHandlers, EmailPlugin } from "@vendure/email-plugin"; import { AssetServerPlugin } from "@vendure/asset-server-plugin"; import { AdminUiPlugin } from "@vendure/admin-ui-plugin"; export const config: VendureConfig = { apiOptions: { port: 3000, adminApiPath: "admin-api", shopApiPath: "shop-api", adminApiPlayground: process.env.NODE_ENV === "development", }, authOptions: { tokenMethod: ["bearer", "cookie"], superadminCredentials: { identifier: process.env.SUPERADMIN_USERNAME!, password: process.env.SUPERADMIN_PASSWORD!, }, cookieOptions: { secret: process.env.COOKIE_SECRET!, }, }, dbConnectionOptions: { type: "postgres", host: process.env.DB_HOST, port: Number(process.env.DB_PORT), database: process.env.DB_NAME, username: process.env.DB_USER, password: process.env.DB_PASSWORD, synchronize: false, migrations: ["dist/migrations/*.js"], }, paymentOptions: { paymentMethodHandlers: [stripePaymentHandler, yookassaPaymentHandler], }, taxOptions: { taxCalculationStrategy: new CustomTaxCalculationStrategy(), }, shippingOptions: { shippingCalculators: [defaultShippingCalculator, tieredShippingCalculator], shippingEligibilityCheckers: [defaultShippingEligibilityChecker], fulfillmentHandlers: [manualFulfillmentHandler], }, plugins: [ AssetServerPlugin.init({ route: "assets", assetUploadDir: path.join(__dirname, "../static/assets"), }), EmailPlugin.init({ devMode: process.env.NODE_ENV === "development", handlers: defaultEmailHandlers, templatePath: path.join(__dirname, "../email/templates"), transport: { type: "smtp", host: process.env.SMTP_HOST!, port: 587, auth: { user: process.env.SMTP_USER!, pass: process.env.SMTP_PASS!, }, }, }), AdminUiPlugin.init({ route: "admin", port: 3002, }), LoyaltyPlugin, B2bPricingPlugin, ErpSyncPlugin, ], }; 

Checkout flow через Shop API

Взаимодействие с корзиной и оформление заказа выполняется через GraphQL. Пример последовательности:

# 1. Добавить товар в заказ mutation AddToOrder($productVariantId: ID!, $quantity: Int!) { addItemToOrder(productVariantId: $productVariantId, quantity: $quantity) { ... on Order { id code totalWithTax lines { id quantity productVariant { name sku } unitPriceWithTax } } ... on ErrorResult { errorCode message } } } # 2. Установить адрес доставки mutation SetShippingAddress($input: CreateAddressInput!) { setOrderShippingAddress(input: $input) { ... on Order { id shippingAddress { fullName streetLine1 city } } ... on NoActiveOrderError { errorCode message } } } # 3. Получить методы доставки и выбрать query GetShippingMethods { eligibleShippingMethods { id name price priceWithTax description } } mutation SetShippingMethod($id: [ID!]!) { setOrderShippingMethod(shippingMethodId: $id) { ... on Order { id shipping shippingWithTax } } } 

Платёжная интеграция (YooKassa)

Пример обработчика для YooKassa:

// src/payment-handlers/yookassa.handler.ts import { CreatePaymentResult, PaymentMethodHandler, LanguageCode } from "@vendure/core"; export const yookassaPaymentHandler = new PaymentMethodHandler({ code: "yookassa", description: [{ languageCode: LanguageCode.ru, value: "YooKassa" }], args: { shopId: { type: "string" }, secretKey: { type: "string", ui: { component: "password-form-input" } }, }, async createPayment(ctx, order, amount, args, metadata): Promise<CreatePaymentResult> { const yookassa = new YooKassa({ shopId: args.shopId, secretKey: args.secretKey, }); const payment = await yookassa.createPayment({ amount: { value: (amount / 100).toFixed(2), currency: order.currencyCode, }, capture: true, confirmation: { type: "redirect", return_url: `${process.env.SHOP_URL}/checkout/confirmation`, }, description: `Заказ #${order.code}`, metadata: { vendure_order_id: order.id }, }); return { amount, state: "Authorized", transactionId: payment.id, metadata: { confirmationUrl: payment.confirmation.confirmation_url }, }; }, async settlePayment(ctx, order, payment, args) { return { success: true }; }, async refundPayment(ctx, order, payment, args, lines, adjustment) { const yookassa = new YooKassa({ shopId: args.shopId, secretKey: args.secretKey }); const refund = await yookassa.createRefund(payment.transactionId, { amount: { value: (adjustment / 100).toFixed(2), currency: order.currencyCode }, }); return { state: "Settled", transactionId: refund.id }; }, }; 

Производительность и масштабирование

Vendure поддерживает разделение на Worker/Server: тяжёлые задачи (email, экспорт, индексация) обрабатываются в отдельном Worker-процессе через Bull. Для Production достаточно 2+ инстанса сервера (load balanced), 1+ воркера и Redis для очередей. Такой подход обеспечивает стабильность при пиковых нагрузках — например, в чёрную пятницу.

Почему Vendure выгоднее SaaS-решений?

SaaS-платформы вроде commercetools удобны, но ежемесячная подписка растет с оборотами. Vendure — единоразовая инвестиция в разработку и хостинг. При значительных оборотах экономия на лицензиях может составлять до 70%. Кроме того, вы не привязаны к вендору — код и данные всегда у вас. По скорости кастомизации бизнес-логики Vendure опережает типичные SaaS-решения в 3-4 раза, так как не требует обходных путей при работе с API.

Характеристика Vendure Commercetools
Модель Self-hosted (open-source) SaaS
Стоимость Бесплатно (лицензия) Существенно дороже
Кастомизация Полная (любая логика через плагины) Ограничена API
Данные Ваш сервер Облако вендора

Типичные ошибки при старте

  • Синхронизация БД включена в production — synchronize: true может перезаписать данные. Всегда используйте миграции.
  • Не настроена очередь для Worker — если не поднять Redis и не запустить Worker, email и фоновые задачи не будут выполняться.
  • Некорректный заголовок vendure-token — для мультитенантности нужно передавать токен канала, иначе запрос упадёт с ошибкой.

Этапы разработки и сроки

Этап Срок
Установка, конфигурация, БД, миграции 2–3 дня
Импорт каталога (Products, Variants, Assets) 3–7 дней
Кастомные плагины (налоги, доставка, промокоды) 5–10 дней
Storefront (Next.js + GraphQL) 10–20 дней
Платёжные интеграции (2–3 провайдера) 4–6 дней
Admin UI кастомизация 2–4 дня
Итого 26–50 дней

Что входит в работу

  • Полная документация: инструкция по развёртыванию, README по конфигурации, API-спецификация в GraphQL Playground.
  • Доступы: выделенный сервер (или рекомендации по облаку), репозиторий с кодом, админка.
  • Обучение команды: воркшоп по администрированию Vendure и работе с Channels.
  • Поддержка: 2 недели после релиза — исправление багов, помощь в деплое обновлений.

Мы обладаем многолетним опытом внедрения Vendure и десятками успешных проектов — от магазинов одежды до b2b-порталов с тысячами позиций. Получите консультацию: оценим ваш проект и предложим архитектуру под ключ. Свяжитесь с нами для предварительной оценки стоимости и сроков.

Подробнее о возможностях Vendure читайте в официальной документации Vendure на GitHub.