Order Management & Fulfillment

Order Management & Fulfillment

Come for answers, stay for best practices. All we're missing is you.

 View Only

Architecting an End-to-End Order Fulfillment Platform on IBM Cloud

By Kulasekaran Krishnaraj posted 06/17/26 03:13 AM

  

What We Built

Over the course of several weeks, we deployed a fully operational e-commerce platform on IBM Cloud. The platform handles the complete order lifecycle: a customer browses products on a storefront, places an order with Stripe payment, the order flows through IBM Sterling OMS for orchestration, a warehouse management system handles pick-pack-ship operations, invoices are generated with payment confirmation, and the customer can view their invoice through a portal link on the storefront.

What makes this deployment notable is that every component runs on IBM Cloud. There are no on-premise servers involved. Sterling OMS runs on OpenShift, the Sterling Intelligent Promising service runs on OpenShift alongside it, the warehouse management system (Odoo) runs on OpenShift, the integration middleware runs on Code Engine, and the customer-facing storefront runs on Code Engine. All communication between these systems happens over IBM Cloud's internal network with HTTPS endpoints.

This article documents the infrastructure decisions, the deployment process for each component, and the practical lessons learned from running an enterprise order management platform entirely in the cloud.

Platform Architecture

The platform consists of five major components, deployed across two IBM Cloud services.

IBM Cloud Red Hat OpenShift hosts the stateful, long-running enterprise applications. IBM Sterling OMS Enterprise Edition runs here, deployed through the IBM Operator Hub using the Sterling OMS operator. The Sterling Intelligent Promising (SIP) service also runs on the same OpenShift cluster, deployed through its own operator. Odoo, serving as our warehouse management and invoicing platform, runs as a containerized deployment on the same cluster with a PostgreSQL database.

IBM Code Engine hosts the stateless, event-driven components. The Java integration middleware runs as a Code Engine Application, receiving webhooks from both OMS and Odoo and proxying API calls from the storefront. The React.js e-commerce storefront also runs as a Code Engine Application, served through an NGINX container with static file hosting.

This separation is deliberate. OpenShift provides the persistent storage, operator-managed lifecycle, and enterprise-grade infrastructure that Sterling OMS requires. Code Engine provides the auto-scaling, zero-infrastructure serverless model that suits the middleware and storefront, which are stateless HTTP services that benefit from scaling to zero when idle.

Deploying IBM Sterling OMS on OpenShift

Sterling OMS Enterprise Edition was deployed on a Red Hat OpenShift cluster in the IBM Cloud us-south region. The deployment uses IBM's operator-based installation, which manages the OMS application lifecycle, database schema creation, and configuration through Kubernetes custom resources.

Cluster Setup

The OpenShift cluster was provisioned through the IBM Cloud console with worker nodes sized for the OMS workload. Sterling OMS requires a minimum of 8 GB of memory per application server pod, and the database (DB2 in our case) needs its own allocation. We provisioned a cluster with sufficient capacity to run OMS, the agent servers, and the supporting services concurrently.

Operator Installation

The IBM Sterling OMS operator was installed through the OpenShift OperatorHub. After subscribing to the operator, we created an OMS Environment custom resource that specifies the database connection, Liberty server configuration, and the enterprise features to enable. The operator handles the initial database schema deployment, EAR file building, and Liberty server pod creation.

Accessing OMS

Once deployed, the operator creates OpenShift Routes that expose the OMS REST API and the Application Manager console. The REST API endpoint follows the pattern:

https://oms.<host>/smcfs/restapi

The Order Hub (the modern web-based administration interface) runs on a separate route and provides order search, inventory visibility, and shipment management through the browser. Application Manager, the traditional Swing-based administration tool, is accessed through the same Liberty server.

Agent Server Configuration

Sterling OMS relies on agent servers for background processing: scheduling orders, releasing shipments, sending invoices, and processing payments. In the OpenShift deployment, these agents run as separate pods managed by the operator. The key agents we configured include the Schedule Order agent, Release Order agent, Send To Node agent, Send Invoice agent, and Payment Collection agent, etc.

Each agent is configured with criteria that determine which orders it processes and how frequently it runs. The Send Invoice agent, for example, picks up newly created invoices and triggers our custom service definition that sends the invoice XML to the middleware.

Deploying Sterling Intelligent Promising on OpenShift

Sterling Intelligent Promising (SIP) provides real-time inventory availability and delivery date promising. It was deployed on the same OpenShift cluster using the SIP operator from the IBM Operator Hub.

SIP integrates with Sterling OMS to provide accurate Available-to-Promise (ATP) calculations across multiple fulfillment nodes. When a customer on the storefront checks delivery dates or when OMS needs to source an order, SIP evaluates inventory across all configured ship nodes and returns availability with estimated delivery dates based on carrier transit times.

The SIP operator creates its own set of pods, including the SIP application server and a Cassandra database for inventory state storage. Cassandra was configured with a keyspace for OMS inventory, and the inventory monitor rules in OMS were set up to publish inventory changes to SIP through the Real-Time Availability Monitor (RTAM).

Configuring the connection between OMS and SIP required updating the OMS properties to point to the SIP service endpoint within the cluster, and ensuring that the Cassandra connectivity properties were correctly set in the OMS configuration.

Deploying Odoo on OpenShift

Odoo serves as the warehouse management system and invoicing platform. Unlike Sterling OMS and SIP, Odoo does not have an IBM operator, so it was deployed as a standard containerized application on OpenShift.

The deployment consists of two pods: the Odoo application server running the official Odoo Docker image, and a PostgreSQL database pod for Odoo's data storage. Persistent Volume Claims ensure that database data survives pod restarts. An OpenShift Route exposes the Odoo web interface at:

https://odoo-oms.mycluster-oms-[hash].us-south.containers.appdomain.cloud

Within Odoo, we configured a warehouse (WoodCraft-WH) with three-step outbound shipping (Pick, Pack, Deliver), installed the Inventory and Invoicing modules, and set up automation rules that fire webhook notifications to the middleware when products, inventory, or picking operations change.

The warehouse configuration uses storage locations (Stock, Packing Zone, Output) that map to the physical warehouse layout. When the middleware creates a Pick operation in Odoo, the three-step routing automatically chains Pack and Delivery operations through Odoo's internal procurement engine.

Deploying the Integration Middleware on Code Engine

The Java integration middleware was deployed as an IBM Code Engine Application. Code Engine was chosen over OpenShift for this component because the middleware is a stateless HTTP service that benefits from auto-scaling and does not require persistent storage or operator-managed lifecycle.

Building and Pushing the Image

The middleware uses a multi-stage Docker build. The first stage compiles the Java source with Maven, and the second stage packages the resulting JAR into a minimal Alpine-based JRE image. The image is pushed to IBM Container Registry:

mvn clean package -q -DskipTests
docker build -t oms-middleware:latest .
docker tag oms-middleware:latest us.icr.io/oms-middleware-ns/oms-middleware:latest
ibmcloud cr login
docker push us.icr.io/oms-middleware-ns/oms-middleware:latest

Application Deployment

The Code Engine application was created with environment variables pointing to the OMS and Odoo endpoints on OpenShift, along with credentials stored as environment configuration:

ibmcloud ce application create \
  --name oms-middleware \
  --image us.icr.io/oms-middleware-ns/oms-middleware:latest \
  --registry-secret icr-secret \
  --port 8888 \
  --min-scale 0 \
  --max-scale 3 \
  --cpu 0.5 \
  --memory 1G \
  --env OMS_BASE_URL="https://oms.mycluster..../smcfs/restapi" \
  --env ODOO_URL="https://odoo-oms.mycluster...." \
  --env STRIPE_SECRET_KEY="sk_test_..."

Code Engine provides an HTTPS endpoint automatically, handling TLS termination without any certificate management on our part. The middleware became accessible at:

https://oms-middleware.[project-id].us-south.codeengine.appdomain.cloud

The Role of the Middleware

The middleware handles all communication between the systems. It receives webhook events from Odoo's automation rules for product, inventory, and picking state changes, forwarding them to OMS. It receives shipment and invoice XML from OMS through the Service Definition Framework, creating warehouse operations and invoices in Odoo. It also acts as an API proxy for the storefront, forwarding OMS and Stripe API calls while keeping all credentials server-side.

A deployment script wraps the build, push, and update steps into a single command. After making code changes, running the script rebuilds the JAR, rebuilds the Docker image, pushes to the registry, and triggers a rolling update on Code Engine. The entire cycle takes about two minutes.

Deploying the Storefront on Code Engine

The React.js e-commerce storefront was deployed as a second Code Engine Application. The storefront is a single-page application built with Vite and served through NGINX.

During local development, Vite's built-in proxy handled cross-origin requests to OMS and Stripe. In the cloud deployment, the storefront no longer calls OMS or Stripe directly. All API calls route through the middleware, which handles authentication and CORS headers. This eliminated the need for complex NGINX proxy configurations.

The storefront's Dockerfile builds the React application and copies the static files into an NGINX image:

FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 8080
CMD ["nginx", "-g", "daemon off;"]

The NGINX configuration is minimal because the middleware handles all API proxying. NGINX only needs to serve static files and handle client-side routing:

server {
    listen 8080;
    root /usr/share/nginx/html;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

The storefront's JavaScript code points to the middleware's Code Engine URL for all API calls. No OMS credentials, Stripe secret keys, or internal service URLs appear in the browser-side code.

How the Systems Connect

With all five components deployed, the data flows between them follow specific paths depending on the operation.

When a customer browses products, the storefront calls the middleware's /api proxy, which forwards the request to Sterling OMS's getItemList API on OpenShift. The middleware injects the authentication JWT, adds the required ibm-oms-app header, and returns the response to the browser.

When a customer places an order with payment, the storefront sends the card token to the middleware's /stripe proxy, which calls Stripe's payment intent API with the secret key added server-side. The authorized payment reference is then included in the createOrder call to OMS through the same /api proxy.

When OMS processes the order through its pipeline and reaches the "Send to Node" shipment status, the Service Definition Framework sends the shipment XML to the middleware's /webhook/shipment/sendtonode endpoint on Code Engine. The middleware then calls Odoo's JSON-RPC API on OpenShift to create the warehouse pick operation.

When warehouse staff complete operations in Odoo, the automation rules fire webhook notifications to the middleware's picking endpoints on Code Engine. The middleware traces the operation chain, determines the shipment reference, and calls the appropriate OMS API on OpenShift to update the shipment status or create a container.

After shipment confirmation, the OMS Send Invoice agent sends invoice XML to the middleware, which creates a paid invoice in Odoo, generates portal URLs, and returns them to OMS for storage as Custom Attributes. The storefront retrieves these URLs when displaying order details to the customer.

Operational Considerations

Cold Starts

The Code Engine middleware is configured with min-scale set to zero, meaning it scales down when there are no incoming requests. The first request after an idle period triggers a cold start that takes approximately five to eight seconds due to JVM initialization. For production workloads where this latency is unacceptable, setting min-scale to one keeps at least one instance warm at all times. The storefront has faster cold starts because NGINX starts in under a second.

Deployment Updates

Updating any component follows a consistent pattern. For OpenShift-based services, the operator manages rolling updates when the custom resource is modified. For Code Engine applications, pushing a new image to the registry and running an application update command triggers a new revision with zero-downtime deployment. A shell script automates the middleware's build-push-deploy cycle into a single command.

Monitoring

Middleware logs are available through the Code Engine CLI using the application logs command with a follow flag for real-time streaming. Each webhook event, API call, and error is logged with timestamps, making it straightforward to trace an order's journey through the system. OMS provides its own logging through the OpenShift pod logs, and Odoo logs are accessible through its container's standard output.

What the Platform Looks Like in Practice

A customer visiting the storefront sees a product catalog fetched from Sterling OMS through the middleware proxy. They add items to their cart, enter shipping details, and pay with a credit card through Stripe (. The order is created in OMS, which schedules it, sources it to the WoodCraft warehouse, releases it, creates a shipment with carrier routing, and sends it to the warehouse through our middleware.

A warehouse operator opens Odoo and sees a Pick operation. They confirm the pick, which triggers a Pack operation. They pack the items, which creates a container in OMS with a tracking number. They confirm the delivery, which marks the shipment as shipped in OMS. The OMS payment agent captures the Stripe payment, the invoice agent creates an invoice, and the Send Invoice service sends it to the middleware, which creates a paid invoice in Odoo and stores the portal URL on the OMS order.

Back on the storefront, the customer checks their order status, sees it marked as Shipped, and clicks "View Invoice" to see their paid invoice with a PDF download option. The entire flow, from browse to invoice, runs across five components deployed on two IBM Cloud services, connected by a 5.5 MB Java middleware.

Conclusion

Deploying an enterprise order management platform entirely on IBM Cloud is not only feasible but practical. The combination of OpenShift for stateful enterprise applications and Code Engine for stateless integration and frontend services provides the right abstraction level for each component. Operators simplify the deployment of complex software like Sterling OMS, while Code Engine's serverless model eliminates infrastructure management for the middleware and storefront.

The integration middleware remains the most critical custom component. It translates between systems, manages authentication, and provides a secure API proxy for the storefront. Deployed on Code Engine, it scales with demand and costs nothing when idle. Deployed alongside Sterling OMS and Odoo on the same IBM Cloud account, it benefits from low-latency internal communication without complex networking configuration.

For teams evaluating cloud deployment options for Sterling OMS, the operator-based approach on OpenShift provides a production-ready foundation. For the integration and presentation layers, Code Engine offers a deployment model that is simple enough for rapid iteration during development and robust enough for production traffic.

0 comments
25 views

Permalink