Prečo prenajímané e-shopy brzdia B2B firmy: Kedy prejsť na vlastný systém

Od nolimeo · 17. februára 2026
banner image

Stredne veľké a rastúce B2B spoločnosti na slovenskom trhu často začínajú svoju e-commerce cestu na prenajímaných krabicových riešeniach. Pre počiatočnú fázu podnikania je to racionálne rozhodnutie: nižšie kapitálové náklady (CAPEX), spustenie v priebehu týždňov a bez potreby hneď riadiť vlastný vývojársky tím.

Problém nastáva v momente, keď sa ročný obrat digitálneho kanála preklopí cez hranicu milióna eur, katalóg narastie na desiatky tisíc položiek a biznis vyžaduje hlbokú integráciu s internými systémami. Vtedy začne monolitická podstata prenajímaných platforiem narážať na svoje fyzické a logické limity.

Tento technický rozbor analyzuje tri kritické úzke hrdlá tradičných SaaS platforiem a ukazuje prechod na headless architektúru ako spôsob, ako znížiť technologický dlh a získať výrazne väčšiu kontrolu nad vlastným biznis modelom.


Bod zlomu: 3 technické limity, ktoré paralyzujú rastúce B2B firmy

Keď prevádzkujete komplexný B2B predaj, vaša obchodná realita sa diametrálne líši od klasického B2C maloobchodu. Každý klient môže mať iné zmluvné podmienky, schvaľovacie procesy a logistické trasy. Tradičné SaaS platformy, ktoré boli primárne navrhnuté pre unifikovaný B2C predaj, sa snažia tieto rozdiely preklenúť vrstvením externých aplikácií a pluginov. To však vytvára nestabilný softvérový ekosystém.

1. Rigidná B2B logika a obmedzenia košíka

Najčastejším problémom prenajímaných riešení je ich neschopnosť prispôsobiť proces objednávky (checkout flow) individuálnym požiadavkám odberateľov. B2B klient bežne vyžaduje:

  • Split platby (rozdelenie platieb): Možnosť zaplatiť časť faktúry vopred zálohou a zvyšok so splatnosťou 14/30 dní podľa vopred schváleného kreditného limitu.
  • Viacnásobné dodacie adresy pre jednu objednávku: Distribúcia tovaru na rôzne pobočky alebo stavby priamo z jedného nákupného košíka.
  • Schvaľovacie hierarchie: Nákupca v strednej firme môže košík naplniť, ale objednávku musí autorizovať jeho finančný manažér priamo v prostredí klientskej zóny.

Ak sa pokúsite tieto toky implementovať do prenajímaného e-shopu, narazíte na uzavretý zdrojový kód. Nemáte možnosť modifikovať databázovú schému košíka ani prepísať natívne validačné pravidlá backendu. Ste nútení použiť generické riešenia, ktoré tlačia vašich klientov do neefektívnych manuálnych krokov.

2. Výkonnostný kolaps (TTFB a LCP) pri rozsiahlych katalógoch a dynamických cenách

Rýchlosť e-shopu úzko súvisí s konverzným pomerom aj organickou viditeľnosťou (SEO). Google pri hodnotení používateľskej skúsenosti zohľadňuje aj čas do prvého bajtu (TTFB, Time to First Byte) a vykreslenie najväčšieho obsahu (LCP, Largest Contentful Paint).

Monolitické e-shopy často uchovávajú väčšinu dát v jednej relačnej databáze. Pri načítaní produktovej stránky musí systém vykonať komplikované dopyty (SQL JOIN-y) naprieč tabuľkami produktov, variantov, skladových zásob, atribútov a najmä individuálnych cenníkov. Ak má e-shop 20 000 položiek a 500 B2B zákazníkov, pričom každý má vlastnú zmluvnú zľavu na konkrétne kategórie, databázový engine môže pri každom zobrazení stránky riešiť veľmi náročné kombinácie.

Monolitická architektúra:
Klient ──> [ Web Server / Monolitický Backend ] ──> [ Obrovská Relačná Databáza ]
              (Prepočty cien, renderovanie HTML, SQL JOIN-y na jednom serveri)
              *Výsledok: vysoké TTFB pri záťaži*

Výsledkom je citeľné spomalenie načítania stránky, najmä pri väčšom katalógu a personalizovaných cenách. V Next.js headless architektúre tento problém riešime oddelením prezentačnej vrstvy, Edge renderingom a dedikovanými vyrovnávacími pamäťami (Redis), čo pri správne navrhnutom indexe a cache stratégii výrazne skracuje odozvu aj pri zložitejšej cenovej matici.

3. Skryté transakčné poplatky a nulová hodnota duševného vlastníctva

Pri prenajímaných platformách často platíte nielen fixný mesačný poplatok, ale aj percentuálny podiel z každého zrealizovaného obratu. Pri vyššom ročnom e-commerce obrate to môže znamenať desiatky tisíc eur ročne za prenájom infraštruktúry a platformy.

Najväčším rizikom je však absencia vlastníctva kódu (vendor lock-in). Všetky investície do úprav e-shopu, integrácií a prispôsobení sú naviazané na platformu tretej strany. Ak sa táto platforma rozhodne zmeniť cenotvorbu, obmedziť API limity alebo ukončiť podporu určitého modulu, vaša firma nemá žiadnu obranu. Nemôžete zobrať databázu a kód a migrovať ho k inému poskytovateľovi, pretože kód nevlastníte.


Architektonické riešenie: Headless a Composable Commerce

Technologické štúdio nolimeo stavia moderné B2B systémy na princípoch Composable Commerce. Tento prístup spočíva v tom, že e-shop nie je jeden monolit, ale skladačka špecializovaných modulov prepojených cez API.

nolimeo Headless Stack:
[ Next.js Frontend (Vercel Edge) ]
        │ (Bleskové API volania)
        ├───────────────────────────┬───────────────────────────┐
        ▼                           ▼                           ▼
[ Medusa.js Engine ]      [ Custom Node.js Middleware ]   [ Payload CMS ]
 (Objednávky, Košíky)       (ERP Prepojenie, Front/Back)  (Obsah, Blog, SEO)
  1. Frontend: Používame Next.js s React Server Components, nasadený na globálnej sieti CDN (Edge rendering). Stránky sú staticky predgenerované a dynamické dáta (napríklad personalizované B2B ceny a stavy zásob) sa dočítavajú asynchrónne cez rýchle API mikroslužby.
  2. Backend: Ako jadro pre biznis logiku využívame moderné open-source frameworky (napr. Medusa.js) postavené na Node.js a PostgreSQL. Celý backend je pod plnou kontrolou nášho tímu a je priamo prispôsobiteľný vašim procesom.
  3. Správa obsahu: Na správu netextového obsahu, dokumentácie a produktových informácií nasadzujeme robustný Payload CMS skrytý za bezpečným API rozhraním.

Ukážka B2B dátového modelu: Flexibilné priraďovanie cien v Drizzle ORM

Pre B2B cenotvorbu navrhujeme schémy, ktoré umožňujú priradiť špecifické ceny priamo zákazníckym skupinám alebo konkrétnym firemným účtom, s podporou množstevných zliav (volume pricing). Nižšie je ukážka schémy v TypeScript pomocou Drizzle ORM:

// src/db/schema.ts
import { pgTable, uuid, varchar, integer, timestamp, foreignKey, index } from "drizzle-orm/pg-core";

// Skupiny zákazníkov (napr. VIP, Veľkoobchod, Stavebniny)
export const customerGroups = pgTable("customer_groups", {
  id: uuid("id").primaryKey().defaultRandom(),
  name: varchar("name", { length: 255 }).notNull(),
  createdAt: timestamp("created_at").defaultNow().notNull(),
});

// B2B Zákazníci s väzbou na ich firmu a cenovú skupinu
export const customers = pgTable("customers", {
  id: uuid("id").primaryKey().defaultRandom(),
  companyName: varchar("company_name", { length: 255 }).notNull(),
  ico: varchar("ico", { length: 8 }).unique().notNull(),
  dic: varchar("dic", { length: 12 }),
  groupId: uuid("group_id").references(() => customerGroups.id, { onDelete: "set null" }),
  creditLimit: integer("credit_limit").default(0).notNull(), // v centoch pre presnosť
  createdAt: timestamp("created_at").defaultNow().notNull(),
});

// Cenníkové pravidlá priradené skupinám
export const priceLists = pgTable("price_lists", {
  id: uuid("id").primaryKey().defaultRandom(),
  name: varchar("name", { length: 255 }).notNull(),
  groupId: uuid("group_id").references(() => customerGroups.id, { onDelete: "cascade" }),
  createdAt: timestamp("created_at").defaultNow().notNull(),
});

// Konkrétne položky v cenníku s podporou množstevných stupňov (Tiered Pricing)
export const priceListPrices = pgTable("price_list_prices", {
  id: uuid("id").primaryKey().defaultRandom(),
  priceListId: uuid("price_list_id").references(() => priceLists.id, { onDelete: "cascade" }),
  variantSku: varchar("variant_sku", { length: 100 }).notNull(),
  amount: integer("amount").notNull(), // cena v centoch (EUR)
  minQuantity: integer("min_quantity").default(1).notNull(), // pre stupňovité zľavy
  createdAt: timestamp("created_at").defaultNow().notNull(),
}, (table) => {
  return {
    skuIdx: index("sku_idx").on(table.variantSku),
    priceListIdx: index("price_list_idx").on(table.priceListId),
  };
});

Tento model umožňuje vývojárom dopytovať ceny pre konkrétneho klienta indexovaným vyhľadávaním bez potreby prepočítavať zložité percentuálne zľavy na strane aplikačného servera za behu.


Odolné integrácie: Ako riešime výpadky lokálnych účtovných systémov (ERP)

Najslabším miestom slovenských e-shopov je ich priame, synchrónne prepojenie na lokálne účtovné systémy. Tradičné e-shopy často volajú API účtovného systému synchrónne počas checkoutu na overenie skladových zásob alebo odoslanie objednávky.

Ak však lokálny účtovný systém spomalí alebo vráti chybu 500 Internal Server Error, čo sa pri starších lokálnych serveroch počas špičiek stáva, zákazník môže vidieť bielu obrazovku, objednávka zlyhá a vzniká riziko nekonzistentných dát o platbe.

V našich projektoch tento problém eliminujeme vybudovaním asynchrónneho Node.js middleware s architektúrou odolnou voči výpadkom (Fault-Tolerant Queue System).

Odolnosť voči výpadkom ERP:
[ Next.js Checkout ] ──> [ Node.js Middleware / Zod Validation ] ──> [ Redis Queue / BullMQ ]
                                                                             │
             ┌───────────────────────────────────────────────────────────────┘
             ▼ (Úspešný pokus)
   [ Lokálne ERP API (Pohoda/KROS) ]
             │
             ▼ (Zlyhanie ERP 500)
   [ Dead Letter Queue (DLQ) ] ──> [ Automatický Retry s Exponential Backoff ]

Ako to funguje v praxi:

  1. Validácia na vstupe (type-safety): Všetky prichádzajúce dáta z ERP validujeme pomocou knižnice Zod. Tým výrazne znižujeme riziko, že neplatný formát dát, napríklad text v poli pre cenu, poškodí databázu e-shopu.
  2. Asynchrónne fronty (Queueing): Objednávka sa zapíše do našej internej PostgreSQL databázy a potvrdí klientovi bez čakania na lokálne ERP. Následne sa zaradí do spracovania v pamäťovej databáze Redis (pomocou nástroja BullMQ).
  3. Dead Letter Queue (DLQ) a retry: Ak ERP vráti chybu, middleware neprijme zlyhanie ako konečný stav. Objednávka zostane vo fronte a systém vykoná opakovaný pokus (retry) s exponenciálnym predlžovaním času (exponential backoff). Ak sa pokusy vyčerpajú, správa sa presunie do Dead Letter Queue a monitorovací systém notifikuje administrátorov cez dohodnutý SLA kanál.

Ukážka robustného Node.js middleware s exponenciálnym retry:

// src/services/erp-sync.service.ts
import { z } from "zod";

// Zod schéma pre prísnu validáciu importovaných produktov z lokálneho ERP
export const ErpProductSchema = z.object({
  id: z.string().uuid(),
  code: z.string().min(1, "Kód produktu nesmie byť prázdny"),
  price_eur: z.number().positive("Cena musí byť kladné číslo"),
  stock_count: z.number().int().nonnegative(),
  vat_rate: z.union([z.literal(20), z.literal(10), z.literal(0)]),
});

export type ErpProduct = z.infer<typeof ErpProductSchema>;

/**
 * Odoslanie dát do lokálneho ERP s podporou exponential backoff retry.
 * Zabraňuje strate objednávok pri výpadkoch internej podnikovej siete.
 */
export async function sendOrderToErpWithRetry(
  orderPayload: Record<string, any>,
  retries = 5,
  delayMs = 1000
): Promise<{ success: boolean; erpRef?: string }> {
  try {
    const response = await fetch(`${process.env.ERP_API_URL}/orders`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${process.env.ERP_API_TOKEN}`,
      },
      body: JSON.stringify(orderPayload),
    });

    if (!response.ok) {
      throw new Error(`ERP odpovedalo chybovým kódom: ${response.status}`);
    }

    const data = await response.json();
    return { success: true, erpRef: data.document_number };

  } catch (error) {
    if (retries <= 0) {
      console.error("Kritické zlyhanie: Objednávka nebola doručená do ERP po 5 pokusoch. Smeruje do DLQ.", error);
      // Tu môže nasledovať upozornenie cez Slack Webhook alebo PagerDuty podľa dohodnutého SLA režimu
      return { success: false };
    }

    console.warn(`Pokus o zápis do ERP zlyhal. Zostáva pokusov: ${retries}. Znova o ${delayMs}ms. Chyba: ${(error as Error).message}`);
    
    // Čakanie s exponenciálnym nárastom intervalu
    await new Promise((resolve) => setTimeout(resolve, delayMs));
    return sendOrderToErpWithRetry(orderPayload, retries - 1, delayMs * 2);
  }
}

Tento prístup výrazne znižuje riziko, že výpadok lokálneho ERP zastaví checkout pre koncového používateľa, napríklad počas zálohovania alebo reštartu lokálnej infraštruktúry.


Bezpečnosť citlivých dát na úrovni databázy: Row Level Security (RLS)

V B2B e-commerce je únik zmluvných cien iného odberateľa nočnou morou pre každého obchodného riaditeľa. Tradičné monolitické e-shopy filtrujú dáta o cenách na aplikačnej úrovni (v kóde). Ak vývojár urobí chybu vo WHERE klauzule alebo v SQL dopyte, jeden prihlásený zákazník môže omylom vidieť veľkoobchodné ceny iného klienta.

Tento problém riešime priamo na úrovni PostgreSQL databázy pomocou Row Level Security (RLS). Databáza v takom nastavení odmietne vrátiť riadky s cenami, ktoré nepatria klientskej skupine prihláseného používateľa, aj keď sa v aplikačnom kóde Next.js objaví chyba.

SQL definícia Row Level Security pre B2B ceny:

-- 1. Povolenie RLS na tabuľke cenníkových položiek
ALTER TABLE price_list_prices ENABLE ROW LEVEL SECURITY;

-- 2. Vytvorenie bezpečnostnej politiky pre čítanie dát
-- Táto politika povolí prihlásenému zákazníkovi vidieť ceny iba vtedy, 
-- ak patrí do skupiny zákazníkov (customer_groups), pre ktorú je cenník určený.
CREATE POLICY b2b_customer_price_isolation ON price_list_prices
    FOR SELECT
    USING (
        price_list_id IN (
            SELECT pl.id 
            FROM price_lists pl
            JOIN customer_groups cg ON pl.group_id = cg.id
            JOIN customers c ON c.group_id = cg.id
            WHERE c.id = current_setting('app.current_customer_id', true)::uuid
        )
    );

Pri každom dopyte na databázu aplikácia nastaví session parameter app.current_customer_id na ID aktuálne overeného klienta. PostgreSQL následne odfiltruje dáta na úrovni databázy bez ohľadu na zložitosť vrstvy API.


Porovnanie: Krabicové SaaS vs. vlastný headless systém

Prechod na headless e-commerce sumarizuje nasledujúca tabuľka:

Parameter Tradičné prenajímané SaaS Vlastný headless systém (nolimeo stack)
Rýchlosť načítania (TTFB) Pomalšia odozva pri veľkých databázach Rýchlejšia odozva vďaka Edge renderovaniu, cache a oddelenej prezentačnej vrstve
Vlastníctvo IP (kódu) Žiadne. Prenájom licencie tretej strany Plné vlastníctvo zdrojového kódu a databázy
B2B prispôsobiteľnosť Obmedzená na šablóny a predinštalované pluginy Vysoká. Kód píšeme podľa procesov firmy
Transakčné poplatky Možný percentuálny poplatok z obratu platforme Bez platformového percenta z obratu pri vlastnej infraštruktúre
Prepojenie s ERP Synchrónne (riziko pádu e-shopu pri chybe ERP) Asynchrónne cez Node.js middleware a Redis fronty
Bezpečnosť cien Filtrovanie na aplikačnej úrovni (riziko úniku) Izolácia priamo na úrovni PostgreSQL databázy (RLS)

Záver: Kedy je čas na strategickú zmenu?

Prechod z prenajímaného e-shopu na vlastnú headless architektúru nie je banálny krok. Vyžaduje počiatočnú investíciu a koordinovaný vývojársky prístup. Pre firmy, ktoré dosiahli bod zlomu, však môže ísť o najrozumnejší technický smer: ich rast začal narážať na mantinely SaaS platforiem a každé spomalenie či výpadok systému ich môže stáť reálne obchodné príležitosti.

Ak vaša spoločnosť čelí technologickému dlhu, ak vám súčasný dodávateľ tvrdí, že zložitejšia B2B cenotvorba „technicky nie je možná“, alebo ak platíte neprimerané percentá z obratu za systém, ktorý nevlastníte, je čas pozrieť sa na vlastnú architektúru. Technologické štúdio nolimeo vie prevziať zodpovednosť za migráciu dát, stabilitu infraštruktúry a bezpečné nasadenie softvéru na mieru.

Napíšte nám a prejdeme si súčasný e-shop, B2B procesy, ERP integrácie aj bezpečný technický smer pre vlastnú headless architektúru.

Máte záujem posunúť váš projekt vpred?