Technical Guide

E-Commerce Platforms & Commerce Systems

A comprehensive guide to building modern e-commerce platforms. Learn about headless commerce architecture, Vendure, catalog management, pricing strategies, checkout optimization, and scaling for high-volume sales.

November 5, 202511 min readOronts Engineering Team

The State of E-Commerce Technology

Most e-commerce platforms are stuck in the past. Monolithic systems where every change risks breaking checkout. Templates that look like every other store. Performance that crawls during peak traffic.

We've migrated enough stores off legacy platforms to know the pain. Shopify's limitations hit fast once you grow. Magento's complexity becomes a liability. WooCommerce was never meant for serious scale.

Modern commerce needs a modern approach: headless architecture, clean data models, and systems built for your business—not the platform's assumptions.

Your commerce platform should adapt to your business, not force your business to adapt to it.

This isn't about technology for technology's sake. It's about building commerce systems that actually scale, perform, and evolve with your needs.

Why Headless Commerce?

In traditional e-commerce, the frontend and backend are fused together. Change the checkout flow? Risk breaking inventory. Add a mobile app? Rebuild everything. Integrate with a marketplace? Good luck.

Headless separates the commerce engine from the presentation layer. The backend handles products, orders, inventory, pricing. The frontend is completely independent—build what you want, how you want.

TraditionalHeadless
Frontend locked to platformAny frontend: web, mobile, kiosk, IoT
Changes risk entire systemChange frontend without touching backend
Limited customizationTotal control over experience
Platform dictates UXYou dictate UX
One channelOmnichannel native

Real Example: Multi-Channel Retailer

A client sells through web, mobile app, in-store kiosks, and Amazon. With a traditional platform, that's four separate systems with sync nightmares.

With headless:

┌─────────────────────────────────────────────┐
│           Commerce Engine (Vendure)         │
│  Products │ Inventory │ Orders │ Customers  │
└─────────────────────────────────────────────┘
              │         │         │
     ┌────────┴───┐ ┌───┴───┐ ┌───┴────┐
     │   Web      │ │ Mobile │ │ Amazon │
     │   (Next.js)│ │ (React │ │  (API) │
     │            │ │ Native)│ │        │
     └────────────┘ └────────┘ └────────┘

One source of truth for inventory. One place for orders. Multiple ways to sell.

Our Platform: Vendure

We build commerce systems on Vendure. Here's why.

Open Source & Extensible

Vendure is open source, written in TypeScript, built on Node.js. You own the code. You can modify anything. No license fees eating your margins.

Built for Customization

Every business has unique requirements. Vendure's plugin architecture lets us add anything without hacking the core.

// Example: Custom plugin for B2B pricing
@VendurePlugin({
  imports: [PluginCommonModule],
  providers: [B2BPricingService],
  configuration: config => {
    config.customFields.Customer.push({
      name: 'priceGroup',
      type: 'string',
      options: [
        { value: 'retail' },
        { value: 'wholesale' },
        { value: 'distributor' }
      ]
    });
    return config;
  }
})
export class B2BPricingPlugin {}

GraphQL Native

Vendure uses GraphQL by default. Clients request exactly what they need—no over-fetching, no under-fetching.

query ProductPage($slug: String!) {
  product(slug: $slug) {
    id
    name
    description
    variants {
      id
      name
      price
      stockLevel
      options {
        name
        value
      }
    }
    assets {
      source
      preview
    }
  }
}

Vendure vs. Alternatives

AspectVendureShopifyMagentocommercetools
CostOpen sourceMonthly fee + %License + hostingUsage-based
OwnershipFullPlatform-ownedLicensePlatform
CustomizationUnlimitedLimitedComplexAPI only
Tech StackTypeScript/NodeLockedPHPAny
HostingYour choiceShopify onlyYour choiceCloud only
Best ForCustom buildsQuick startEnterprise (legacy)Large enterprise

Catalog Management

Your product catalog is the foundation. Get it wrong, and everything downstream suffers.

Product Data Model

Products aren't simple. They have variants, options, attributes, categories, and relationships. We model this properly from the start.

// Product structure example
interface Product {
  id: string;
  name: string;
  slug: string;
  description: string;

  // Variants: actual purchasable items
  variants: ProductVariant[];

  // Options: what differentiates variants
  options: ProductOption[];  // Size, Color, etc.

  // Attributes: searchable/filterable properties
  attributes: ProductAttribute[];  // Brand, Material, etc.

  // Categories: hierarchical organization
  categories: Category[];

  // Assets: images, videos, documents
  assets: Asset[];

  // SEO
  seo: {
    title: string;
    description: string;
    keywords: string[];
  };
}

interface ProductVariant {
  id: string;
  sku: string;
  price: Money;
  stockLevel: number;
  options: SelectedOption[];  // { size: 'L', color: 'Blue' }
}

Faceted Navigation

Customers expect to filter products by multiple attributes simultaneously. This requires proper facet indexing.

Facet TypeExampleImplementation
CategoryElectronics > PhonesHierarchical, breadcrumbs
RangePrice €100-€200Min/max aggregation
Multi-selectColors: Red, BlueArray intersection
BooleanIn stock onlySimple filter
// Search with facets
const results = await search({
  term: 'phone',
  facets: {
    category: ['electronics', 'phones'],
    brand: ['Apple', 'Samsung'],
    priceRange: { min: 500, max: 1000 },
    inStock: true
  },
  sort: { field: 'price', direction: 'ASC' },
  pagination: { page: 1, limit: 24 }
});

// Results include facet counts for UI
results.facets = {
  brand: [
    { value: 'Apple', count: 24 },
    { value: 'Samsung', count: 18 }
  ],
  priceRanges: [
    { range: '500-750', count: 20 },
    { range: '750-1000', count: 22 }
  ]
};

Pricing Architecture

Pricing is where commerce gets complex. Simple retail pricing is the easy case. Real businesses need much more.

Pricing Models We Support

ModelUse CaseComplexity
Fixed PriceStandard retailLow
Customer Group PricingB2B, wholesaleMedium
Volume PricingBuy more, save moreMedium
Dynamic PricingDemand-based, competitor-awareHigh
Contract PricingEnterprise agreementsHigh
Promotional PricingSales, coupons, bundlesMedium
// Complex pricing calculation
async function calculatePrice(
  product: Product,
  customer: Customer,
  quantity: number,
  context: PriceContext
): Promise<Money> {
  let price = product.basePrice;

  // Customer group discount
  if (customer.priceGroup === 'wholesale') {
    price = applyDiscount(price, customer.discount);
  }

  // Volume pricing
  const volumeTier = getVolumeTier(quantity);
  if (volumeTier) {
    price = applyVolumeDiscount(price, volumeTier);
  }

  // Contract pricing override
  const contractPrice = await getContractPrice(product, customer);
  if (contractPrice && contractPrice < price) {
    price = contractPrice;
  }

  // Active promotions
  const promos = await getActivePromotions(product, context);
  price = applyPromotions(price, promos);

  return price;
}

Multi-Currency

International commerce requires proper currency handling. Not just conversion, but localized pricing.

// Currency configuration
const currencyConfig = {
  EUR: { default: true, symbol: '€', position: 'before' },
  USD: { symbol: '$', position: 'before' },
  GBP: { symbol: '£', position: 'before' },
  CHF: { symbol: 'CHF', position: 'after' }
};

// Price per channel/locale
const productPricing = {
  'de-DE': { currency: 'EUR', price: 9900 },  // €99.00
  'en-US': { currency: 'USD', price: 10900 }, // $109.00
  'en-GB': { currency: 'GBP', price: 8500 }   // £85.00
};

Checkout Optimization

Checkout is where money is made or lost. Every friction point costs conversions.

The Checkout Flow

Cart → Customer Info → Shipping → Payment → Confirmation
  │         │             │          │
  └─ Save   └─ Validate   └─ Quote   └─ Process
     state     address       rates      payment

Reducing Friction

ProblemSolutionImpact
Too many stepsSingle-page checkout+15% conversion
No guest checkoutGuest option prominent+30% new customers
Slow loadingOptimized assets, edge caching+10% conversion
Hidden costsShow shipping early-25% cart abandonment
Limited payment optionsMultiple methods+10% conversion
// Guest checkout with account creation option
const checkoutFlow = {
  step1_cart: {
    showSummary: true,
    showEstimatedShipping: true,  // No surprises later
    showPromoCode: true
  },

  step2_info: {
    guestCheckout: true,  // Don't force registration
    addressAutocomplete: true,
    rememberDetails: true
  },

  step3_shipping: {
    showAllOptions: true,
    preselect: 'cheapest',  // or 'fastest'
    showDeliveryDates: true
  },

  step4_payment: {
    methods: ['card', 'paypal', 'klarna', 'applepay', 'googlepay'],
    savePaymentMethod: true,  // For logged-in users
    expressCheckout: true
  }
};

Payment Integration

We integrate with multiple payment providers. No single point of failure, no vendor lock-in.

ProviderBest ForFeatures
StripeGeneral purposeCards, wallets, subscriptions
PayPalConsumer trustPay later, buyer protection
KlarnaBuy now, pay laterInstallments, increased AOV
AdyenEnterprise, globalAll methods, local acquiring

Inventory & Fulfillment

Selling products you don't have ruins customer trust. Inventory management needs to be bulletproof.

Inventory Tracking

interface InventoryLocation {
  id: string;
  name: string;  // 'Main Warehouse', 'Store Berlin'
  type: 'warehouse' | 'store' | 'dropship';
  stock: Map<VariantId, StockLevel>;
}

interface StockLevel {
  available: number;     // Can sell now
  reserved: number;      // In carts, pending orders
  incoming: number;      // On purchase orders
  threshold: number;     // Reorder point
}

// Check availability across locations
async function checkAvailability(
  variant: ProductVariant,
  quantity: number,
  shipTo: Address
): Promise<AvailabilityResult> {
  const locations = await getLocationsByProximity(shipTo);

  for (const location of locations) {
    const stock = await getStock(variant, location);
    if (stock.available >= quantity) {
      return {
        available: true,
        location,
        deliveryEstimate: calculateDelivery(location, shipTo)
      };
    }
  }

  return { available: false, backorderDate: await getBackorderDate(variant) };
}

Order Lifecycle

Created → Paid → Processing → Shipped → Delivered
    │       │         │           │          │
    │       │         │           │          └─ Complete
    │       │         │           └─ Tracking update
    │       │         └─ Pick, pack, ship
    │       └─ Payment captured
    └─ Inventory reserved

Scaling for Traffic

Black Friday traffic kills unprepared stores. We build for 10x your normal load.

Performance Architecture

LayerStrategyImplementation
CDNCache static assets, pagesCloudFront, Fastly
APICache responses, rate limitRedis, API gateway
DatabaseRead replicas, connection poolingPostgreSQL, PgBouncer
SearchDedicated search clusterElasticsearch, Algolia
QueueAsync processingRedis, SQS
// Caching strategy
const cacheConfig = {
  // Product pages: cache with revalidation
  productPage: {
    ttl: 3600,  // 1 hour
    staleWhileRevalidate: 86400,  // Serve stale for 24h while refreshing
    tags: ['products', 'product:${id}']
  },

  // Cart/checkout: no cache
  checkout: {
    cache: false
  },

  // Category pages: short cache
  categoryPage: {
    ttl: 300,  // 5 minutes
    staleWhileRevalidate: 3600
  }
};

Load Testing

We don't guess about performance. We test before launch.

# Load test example with k6
k6 run --vus 500 --duration 10m loadtest.js

# Results we target:
# - P95 response time < 200ms
# - Error rate < 0.1%
# - No degradation under 10x normal load

B2B Commerce

B2B commerce has different requirements than B2C. We handle both.

B2CB2B
Fixed pricesNegotiated prices
Individual buyersBuyer organizations
Immediate paymentNet terms (30/60/90)
Simple checkoutApproval workflows
Guest checkoutAccount required
// B2B organization structure
interface Organization {
  id: string;
  name: string;
  taxId: string;
  creditLimit: Money;
  paymentTerms: 'net30' | 'net60' | 'net90';

  // Multiple buyers per org
  buyers: Buyer[];

  // Approval workflows
  approvalRules: ApprovalRule[];

  // Custom pricing
  priceList: PriceList;

  // Addresses
  shippingAddresses: Address[];
  billingAddress: Address;
}

// Approval workflow
interface ApprovalRule {
  condition: 'orderTotal > 5000' | 'newVendor';
  approvers: User[];
  requireAll: boolean;
}

Getting Started

Here's how we typically build commerce systems:

Phase 1: Discovery & Design (2-4 weeks)

  • Understand your business model, products, customers
  • Map out integrations (ERP, WMS, PIM)
  • Design data model and workflows
  • Plan migration strategy if applicable

Phase 2: Platform Build (8-12 weeks)

  • Vendure setup and customization
  • Custom plugins for your requirements
  • Integration development
  • Admin interface configuration

Phase 3: Frontend Build (6-10 weeks)

  • Design implementation
  • Performance optimization
  • Mobile responsiveness
  • Accessibility compliance

Phase 4: Launch & Optimize

  • Load testing and hardening
  • Migration execution
  • Launch support
  • Ongoing optimization

Conclusion

E-commerce technology should enable your business, not constrain it. With headless architecture and platforms like Vendure, you get full control over your commerce experience while maintaining the flexibility to evolve.

The best commerce platform is invisible to customers. They just get a fast, smooth experience that makes buying easy.

We've built commerce systems handling millions in transactions. If you're outgrowing your current platform or starting fresh, we'd be happy to discuss what modern commerce could look like for your business.

Topics covered

e-commerceheadless commerceVendurecommerce platformscatalog managementcheckout optimizationB2B commercemulti-channel retailcommerce architecture

Ready to implement agentic AI?

Our team specializes in building production-ready AI systems. Let's discuss how we can help you leverage agentic AI for your enterprise.

Start a conversation