Skip to main content
intermediateUpdated August 11, 2026·11 min read

SAP Commerce Cloud Architecture Overview

SAP Commerce Cloud architecture: platform services, CCv2 aspects, deployment pipelines, cluster topology, and integration patterns.

CCI

Commerce Cloud Integrations

SAP Commerce engineering team

Architecture, integrations, performance, upgrades, and Composable Storefront on SAP Commerce Cloud.

architectureccv2deploymentplatformcloud

SAP Commerce Cloud (formerly Hybris) is a Java-based e-commerce platform built on Spring Framework, deployed on a managed cloud infrastructure (CCv2). This guide covers the core architectural patterns that every commerce architect and developer must understand: platform services, the extension system, CCv2-specific deployment model, and integration patterns.

Platform Services Architecture#

The SAP Commerce platform is built around a service-oriented architecture with three key layers:

  1. Type System: dynamic data model with runtime type definition
  2. Service Layer: business logic, transactions, validation
  3. Facades: simplified API for frontend/integration consumption

Type System#

SAP Commerce uses a custom type system defined in *-items.xml files. Types are compiled into JaLo classes (legacy) and Models (current standard).

xml
<itemtype code="Product" extends="GenericItem">
  <deployment table="products" typecode="1"/>
  <attributes>
    <attribute qualifier="code" type="java.lang.String">
      <modifiers unique="true" optional="false"/>
      <persistence type="property"/>
    </attribute>
    <attribute qualifier="name" type="localized:java.lang.String">
      <persistence type="property"/>
    </attribute>
    <attribute qualifier="catalogVersion" type="CatalogVersion">
      <modifiers optional="false"/>
      <persistence type="property"/>
    </attribute>
  </attributes>
</itemtype>

Key type system concepts:

  • Deployment: table name + typecode (numeric identifier for serialization)
  • Attributes: can be stored (persisted to DB) or dynamic (calculated at runtime)
  • Relations: one-to-many and many-to-many via separate relation items
  • Interceptors: validate, prepare, or react to model changes (lifecycle hooks)
  • Localization: attributes can be localized per language via localized: prefix

Service Layer#

Business logic lives in service beans. Services are Spring-managed, transactional, and testable:

java
@Service
public class DefaultProductService implements ProductService {

  @Resource
  private FlexibleSearchService flexibleSearchService;

  @Resource
  private ModelService modelService;

  @Override
  public ProductModel getProductForCode(String code) {
    final FlexibleSearchQuery query = new FlexibleSearchQuery(
      "SELECT {pk} FROM {Product} WHERE {code} = ?code"
    );
    query.addQueryParameter("code", code);
    return flexibleSearchService.searchUnique(query);
  }

  @Override
  @Transactional
  public void updateProduct(ProductModel product) {
    modelService.save(product);
  }
}

Service layer best practices:

  • Use FlexibleSearch for queries (platform-managed SQL abstraction)
  • Transaction boundaries via @Transactional (Spring TX)
  • Validation via Interceptors and Validators
  • No UI concerns. Service layer is backend-only
  • Avoid direct DAO access. Use ModelService for CRUD

Facades#

Facades simplify service layer complexity for frontends and integrations. They convert Models to DTOs (Data Transfer Objects):

java
@Component
public class DefaultProductFacade implements ProductFacade {

  @Resource
  private ProductService productService;

  @Resource
  private Converter<ProductModel, ProductData> productConverter;

  @Override
  public ProductData getProductForCode(String code) {
    final ProductModel product = productService.getProductForCode(code);
    return productConverter.convert(product);
  }
}

Facades return DTOs (Data Transfer Objects), never models directly. DTOs are serialization-safe, versioned, and decouple the API from internal models.

Extension System#

SAP Commerce is modular. All functionality ships as extensions. Core platform extensions:

ExtensionPurpose
corePlatform kernel, type system, Spring context
catalogCatalogs, categories, classification
basecommerceProduct, price, stock fundamentals
commercefacadesStandard facades + DTOs
commerceservicesStandard services (cart, order, customer)
commercewebservicesOCC REST API (headless commerce)
backofficeAdmin UI framework
acceleratorservicesB2C/B2B storefront foundation
acceleratorstorefrontcommonsStorefront web layer (controllers, tags)

Extension Structure#

plaintext
myextension/
├── extensioninfo.xml          # extension metadata, dependencies
├── project.properties          # build config, cache regions
├── resources/
│   ├── myextension-items.xml  # type system definitions
│   ├── myextension-spring.xml # Spring bean wiring
│   ├── localization/          # i18n bundles
│   └── impex/                 # initial data, migrations
├── src/                        # Java source
├── testsrc/                    # unit/integration tests
└── web/                        # web UI (storefront/backoffice)

Extensions declare dependencies in extensioninfo.xml:

xml
<extension name="myextension">
  <requires-extension name="commerceservices"/>
  <requires-extension name="commercefacades"/>
  <coremodule generated="true" packageroot="com.example.myextension"/>
  <webmodule webroot="/myextension"/>
</extension>

Build order is calculated from dependency graph. Circular dependencies are rejected at compile time.

CCv2 Architecture (SAP Commerce Cloud v2)#

CCv2 is the managed cloud platform for SAP Commerce. It introduces aspects, independently scalable deployment units.

Aspect Model#

An aspect is a logical deployment unit with a specific role. CCv2 supports:

AspectPurposeScalability
accstorefrontCustomer-facing storefront (B2C/B2B)Horizontal (auto-scale)
backofficeAdmin UI for content/catalog managementVertical (fixed instances)
backgroundProcessingAsync jobs (cronjobs, indexing, batch)Horizontal (job-based)
apiOCC REST API (headless commerce)Horizontal (auto-scale)
adminPlatform admin and initialisation tasksVertical (fixed)

Each aspect runs as a separate cluster of nodes with isolated configuration.

Aspect Configuration#

Aspects are configured via manifest.json in the cloud portal repository:

json
{
  "commerceSuiteVersion": "2211.24",
  "aspects": [
    {
      "name": "accstorefront",
      "properties": [
        {
          "key": "spring.session.enabled",
          "value": "true"
        },
        {
          "key": "cluster.node.groups",
          "value": "integration,yHotfolderCandidate"
        }
      ],
      "webapps": [
        {
          "name": "mystorefront",
          "contextPath": ""
        }
      ]
    },
    {
      "name": "backgroundProcessing",
      "properties": [
        {
          "key": "cluster.node.groups",
          "value": "integration,yHotfolderCandidate,backgroundProcessing"
        }
      ]
    }
  ],
  "extensions": ["mystorefront", "mycore"]
}

Key aspect config patterns:

  • cluster.node.groups: controls which cronjobs run on which aspect
  • spring.session.enabled: turns on HTTP session failover, which persists sessions to the database (storedhttpsessions) so a lost node does not log the shopper out
  • webapps: which web applications deploy to this aspect (storefront, backoffice)

CCv2 Build Process#

CCv2 builds are triggered via Git push to the cloud portal repository. Build pipeline:

mermaid
graph LR
    A[Git Push] --> B[Cloud Portal Webhook]
    B --> C[Build Server: ant clean all]
    C --> D[Docker Image Build]
    D --> E[Image Push to Registry]
    E --> F[Deployment to Environment]
    F --> G[Health Check]
    G --> H[Traffic Cutover]

Build stages:

  1. Source checkout: Cloud portal clones the repository
  2. Ant build: ant clean all compiles the platform and every extension in the build path
  3. Docker image: Platform + extensions packaged into Docker image
  4. Image push: Image pushed to CCv2 registry (GCR/ACR)
  5. Deployment: Rolling deployment to target environment
  6. Health check: the platform must answer before the load balancer admits traffic
  7. Traffic cutover: Load balancer switches to new pods

Build artifacts:

  • hybris/bin/platform: compiled platform
  • hybris/data: initial data (ImpEx, media)
  • manifest.json: aspect configuration
  • solr/: Solr core config (if using embedded Solr)

CCv2 Deployment Environments#

CCv2 provides isolated environments for each stage of the SDLC:

EnvironmentPurposeRefresh Strategy
DevelopmentFeature development, integration testingDatabase copy on request (Cloud Portal)
StagingPre-production testing, UATDatabase copy on request (Cloud Portal)
ProductionLive customer trafficBlue/green deployment

Each environment has:

  • Dedicated database (Azure SQL)
  • Dedicated Solr cluster (search index)
  • Dedicated Azure Blob storage (media files)

Environment Variables#

CCv2 injects environment-specific config via environment variables:

properties
# hybris/config/local.properties, for local development only.
# CCv2 runs on Azure SQL, so the driver is the Microsoft one.
db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
db.url=jdbc:sqlserver://localhost:1433;databaseName=commerce

On CCv2 you do not set the datasource yourself. The platform receives it from the environment, and the configuration you control arrives two ways:

  • manifest.json: properties committed with the code, per aspect, and the useConfig block that points at property files in the repository
  • Cloud Portal service configuration: environment-specific values, including secrets, held outside the repository

Anything a Kubernetes habit tells you to set as a pod environment variable belongs in one of those two places instead.

Data Model Patterns#

Product Model#

Products in SAP Commerce are hierarchical:

  • Product (base type): sku, name, description
  • VariantProduct (extends Product): color, size variants
  • ApparelProduct / ElectronicsProduct: domain-specific extensions

Products belong to Catalogs and Categories. Classification via ClassificationClass and ClassificationAttribute for faceted navigation.

Catalog versioning:

  • Staged: content editing, not visible to customers
  • Online: published content, customer-facing

Price Model#

Pricing is multi-dimensional via PriceRow:

plaintext
PriceRow: product + user group + currency + unit + date range → price

Price calculation via PriceFactory and PriceService. Discounts and promotions run on the Drools rule engine (ruleengineservices, promotionengineservices), which compiles rules into a rule module and evaluates them against the cart.

Price resolution order:

  1. User-specific price (B2B negotiated pricing)
  2. User group price (customer segment)
  3. Base price (fallback)

Order Model#

Order lifecycle:

  1. Cart (CartModel): the shopping cart. It is a sibling of OrderModel, not a mode of it; both extend AbstractOrderModel.
  2. Order (OrderModel submitted): placed order
  3. ConsignmentEntry: fulfillment/shipment

Order calculation via CalculationService applies totals, taxes, and discounts in sequence:

  1. Item prices
  2. Discounts (order-level, line-level)
  3. Delivery cost
  4. Taxes
  5. Payment cost

Cluster Topology#

CCv2 runs SAP Commerce in a clustered environment. Key clustering patterns:

Session Replication#

CCv2 does not provision a Redis instance, so the Spring Boot session stores you may have used elsewhere are not on the menu. Two mechanisms carry the session:

MechanismWhat it doesWhere it applies
Sticky sessionsThe load balancer keeps a shopper on the node that holds their sessionAlways on, and the first line of defence
HTTP Session FailoverSpring Session persists the session to the database (storedhttpsessions) so another node can pick it up when one diesOpt-in, per web application

Enable failover per webapp rather than globally, because every persisted session is a database write on the hot path:

properties
spring.session.enabled=true
spring.session.yacceleratorstorefront.save=async

Sticky sessions alone lose the cart when a node restarts mid-deployment. Failover costs write throughput. Pick per application, not per project.

Media Storage#

Media files (images, documents) must be shared across nodes:

  • On-premise: Shared filesystem (NFS)
  • CCv2: Azure Blob Storage or AWS S3

Azure Blob config:

properties
media.default.url.strategy=azure
media.azure.storage.account.connection-string=${AZURE_STORAGE_CONNECTION_STRING}
media.azure.storage.container.name=commerce-media

Task Engine#

The Task Engine runs background jobs (cronjobs). In a cluster:

  • Tasks are locked at the database level (distributed lock)
  • Only one node executes a given task at a time
  • Node groups control which aspect executes which cronjob

Node group assignment:

properties
cluster.node.groups=integration,yHotfolderCandidate,backgroundProcessing

Integration Patterns#

OCC (Omni Commerce Connect)#

Standard REST API for headless storefronts:

  • Base path: /occ/v2/{baseSiteId}/
  • Endpoints: /products, /carts, /users, /orders
  • OAuth2 authentication (client credentials, password grant)
  • Extensible via custom controllers and DTOs

OCC endpoint example:

plaintext
GET /occ/v2/electronics/products/1234?fields=FULL
Authorization: Bearer <token>

Response:

json
{
  "code": "1234",
  "name": "Sample Product",
  "price": {
    "value": 99.99,
    "currencyIso": "USD"
  },
  "stock": {
    "stockLevel": 10
  }
}

ImpEx#

Data import/export DSL (Domain-Specific Language):

plaintext
INSERT_UPDATE Product; code[unique=true]; name; catalogVersion(catalog(id),version)
; product123 ; "Sample Product" ; Default:Staged
; product456 ; "Another Product" ; Default:Staged

INSERT_UPDATE Category; code[unique=true]; name; catalogVersion(catalog(id),version)
; cat001 ; "Electronics" ; Default:Staged

INSERT_UPDATE CategoryProductRelation; source(code,catalogVersion(catalog(id),version)); target(code,catalogVersion(catalog(id),version))
; cat001:Default:Staged ; product123:Default:Staged

Used for:

  • Initial data load (essential data, sample data)
  • Migrations (data model changes)
  • Test data setup (integration tests)
  • Bulk operations (price updates, catalog sync)

Event System#

SAP Commerce publishes Business Events for async processing:

java
@Component
public class OrderPlacedEventListener extends AbstractEventListener<OrderPlacedEvent> {

  @Resource
  private EmailService emailService;

  @Override
  protected void onEvent(OrderPlacedEvent event) {
    final OrderModel order = event.getOrder();
    emailService.sendOrderConfirmation(order);
  }
}

Events are:

  • Synchronous by default: an event published on one node runs its listeners on the caller's thread. Only events implementing ClusterAwareEvent leave the node and go asynchronous, so a slow listener is your slow request.
  • Not transactional by default: the event fires on the change, not on the commit. To wait for the commit, implement TransactionAwareEvent and set publishOnCommitOnly. Otherwise a rolled-back transaction has already told the rest of the system it happened.
  • In-memory: the event bus holds nothing. A listener that is down when the event fires never sees it, and there is no replay. Where you need delivery guarantees, use webhooks or write your own audit record.

Common events:

  • OrderPlacedEvent
  • ProductModifiedEvent
  • CustomerRegisteredEvent
  • CartModifiedEvent

Performance Considerations#

Caching#

SAP Commerce uses multi-layer caching:

Cache TypeMechanismScope
Region CacheEhcacheType system, catalogs, CMS
FlexibleSearch CacheQuery result cacheRead-heavy queries
CMS Page CachePre-rendered pagesStorefront performance

Region cache sizes are set per region, not per extension. The region names are fixed by the platform (entityregion, typesystemregion, querycacheregion and so on):

properties
regioncache.entityregion.size=2000000
regioncache.entityregion.evictionpolicy=LRU

Database Optimization#

  • Use FlexibleSearch with proper indexing (not raw SQL)
  • Avoid N+1 queries. Fetch relations in one query
  • Partition large tables (OrderEntry, PriceRow, CustomerReview)
  • Monitor slow queries via DB Performance Monitoring in HAC

Index example:

sql
CREATE INDEX idx_product_code ON products(p_code);
CREATE INDEX idx_order_user ON orders(p_user);

Clustering Best Practices#

  • Session replication: sticky sessions plus database-backed failover on the storefront webapp; there is no Redis on CCv2
  • Media storage: External blob storage (Azure/S3), not filesystem
  • Task Engine: Assign cronjobs to backgroundProcessing aspect only
  • Health checks: CCv2 runs these for you; your job is to keep startup deterministic so a node is ready when it says it is
  • Logging: Centralized logging (ELK, Splunk) for distributed tracing

Next Steps#

These deeper guides are in development. Topics planned:

  • OCC API Integration Patterns
  • Backoffice Customization
  • Promotion Engine (CAP) deep dive
  • Spartacus / Composable Storefront architecture
  • CCv2 deployment troubleshooting