Real-Time Data (RTD)

This page covers the RTD module architecture, trigger points, sequence flows, data model (request/response mappings with examples), validation rules, connector configuration, and API endpoints.

Overview

The Real-Time Data (RTD) module enables DJUST platform to query your clients' information systems (ERP, WMS, PIM...) in real time via their REST APIs to retrieve pricing and stock data at the exact moment a buyer interacts with the purchasing journey.

Unlike traditional batch synchronization (periodic imports via SFTP or API Connector), RTD ensures that displayed prices and available stock reflect the actual state of the source system at the time of consultation.


Why use Real-Time Data?

ChallengeRTD Solution
Prices depend on multiple variables (e.g. customer, delivery address, ordered quantity, delivery date, contract terms...)Real-time API call with the buyer's full context
Stock levels change constantly (multi-channel warehouse)Stock verification at the time of cart addition and order validation
The source system manages dynamic promotions (sub-items, volume discounts)The source system can return additional lines (promos) automatically added to the cart
Offer Price / Offer Inventory are not available in DJUSTRTD substitutes these entities by fetching data externally

General Architecture

graph LR
    A["🛒 Buyer<br/>(Front)"] <-->|"User actions<br/>& responses"| B["📱 FOC<br/>(Storefront)"]
    B <-->|"API calls<br/>& results"| C["⚙️ DJUST Backend"]
    C <-->|"Mapped<br/>payloads"| E["🏢 Client REST API<br/>(ERP / WMS / PIM)"]

    style A fill:#f9f9f9,stroke:#333
    style B fill:#e8f4fd,stroke:#1a73e8
    style C fill:#e8f4fd,stroke:#1a73e8
    style E fill:#f3e8fd,stroke:#7b1fa2

Internally, DJUST backend includes has a RTD module which acts as a generic connector to the client's REST API. It handles:

  1. Mapping DJUST data to the format expected by the client's REST API
  2. Calling the client's REST API with the constructed payload
  3. Mapping the client's API response back to the DJUST data model
  4. Returning the information for validation and cart update

Trigger Points

RTD is natively invoked at four key moments in the purchasing journey:

timeline
    title Purchasing Journey — RTD Trigger Points
    section Storefront (custom)
        Product List : PRICE
        Product Detail : PRICE
    section Backend (native)
        Add / Update Cart Line : PRICE + STOCK
        Cart Sync : PRICE + STOCK
        Transition to CREATED : STOCK
#EventData RetrievedDescription
1Product list (custom)PriceDisplay personalized prices on the product list
2Product detail page (custom)PriceDisplay the personalized price on the product detail page
3Add / update cart linePrice + StockPrice retrieval and stock verification for the affected product(s)
4Cart synchronizationPrice + StockFull recalculation of the entire cart (prices, stock, promos)
5Transition to CREATEDStockFinal stock verification before order confirmation

Note: RTD can also be triggered on Product List and Product Page to display real-time prices, but this requires a custom implementation on the Storefront side.


Detailed Flows by Event

1. Adding / Updating a Cart Line

This is the most common event. Here is the full flow:

sequenceDiagram
    participant BUYER as Buyer
    participant FOC as Storefront (FOC)
    participant CORE as DJUST Backend
    participant RTD as RTD Module
    participant ERP as Client API (ERP)

    BUYER->>FOC: Adds Product B to cart
    FOC->>CORE: ORDER-150 — PUT /lines (add Product B)

    Note over CORE: --- Price Module ---
    CORE->>RTD: Sends Product B
    RTD->>RTD: Mapping DJUST -> Client (Price)
    RTD->>ERP: POST /price (Product B)
    ERP-->>RTD: Price response for Product B
    RTD-->>CORE: Mapped Product B price

    Note over CORE: --- Stock Module ---
    CORE->>RTD: Sends Product B
    RTD->>RTD: Mapping DJUST -> Client (Stock)
    RTD->>ERP: POST /stock (Product B)
    ERP-->>RTD: Stock response for Product B
    RTD-->>CORE: Mapped Product B stock

    CORE->>CORE: Validation rules
    CORE->>CORE: Cart update

    alt Validations OK
        CORE-->>FOC: 200 OK
    else Insufficient stock or inactive product
        CORE-->>FOC: 200 OK + blocking warning
    else Client API unavailable
        CORE-->>FOC: 503 Service Unavailable
    end

Key points:

  • Price and Stock are handled by two separate DJUST modules, each with its own mapping configuration. This means the client's REST API is always called twice (once for Price, once for Stock), even if the client exposes a single endpoint for both.
  • Price and Stock calls are chained: the Stock call uses information returned by the Price call
  • Only the products affected by the buyer's action are sent to the client's API (DJUST doesn't provide the full cart at this stage)
  • A metadata field allows the Storefront to send additional data required for price calculation (e.g., packaging unit)

2. Cart Synchronization

Synchronization recalculates the entire cart by querying the client's API with all lines.

sequenceDiagram
    participant FOC as Storefront (FOC)
    participant CORE as DJUST Backend
    participant RTD as RTD Module
    participant ERP as Client API (ERP)

    FOC->>CORE: ORDER-223 — PUT /sync (cart sync)
    CORE->>CORE: Retrieve full cart

    Note over CORE: --- Price Module ---
    CORE->>RTD: Sends ENTIRE cart (A, B, C...)
    RTD->>ERP: POST /price (all products)
    ERP-->>RTD: Prices for A, B, C + possible promos P1, P2
    RTD-->>CORE: Mapped prices

    Note over CORE: --- Stock Module ---
    CORE->>RTD: Sends entire cart + new promos
    RTD->>ERP: POST /stock (A, B, C, P1, P2)
    ERP-->>RTD: Stock for all products
    RTD-->>CORE: Mapped stock

    CORE->>CORE: Validations + cart update
    CORE-->>FOC: 200 OK (+ warnings if changes)

Key points:

  • The client's API can add new lines (promos, sub-items) that will be integrated into the cart
  • The client's API can modify quantities of existing lines
  • If an existing line is no longer returned by the client's API, it is removed from the cart
  • Each line is validated independently: a blocking warning on one line does not prevent updates on others

3. Transition to CREATED

This is the final validation before the order is confirmed. Only stock is verified.

sequenceDiagram
    participant FOC as Storefront (FOC)
    participant CORE as DJUST Backend
    participant RTD as RTD Module
    participant ERP as Client API (ERP)

    FOC->>CORE: ORDER-212 — PUT /created (order validation)
    CORE->>CORE: Retrieve cart

    Note over CORE: --- Stock Module ---
    CORE->>RTD: Sends ENTIRE cart
    RTD->>ERP: POST /stock (all products)
    ERP-->>RTD: Stock for all products
    RTD-->>CORE: Mapped stock

    CORE->>CORE: Rule verification

    alt All valid
        CORE-->>CORE: Status -> CREATED
        CORE-->>FOC: 200 OK
    else At least one invalid line
        CORE-->>CORE: Status unchanged (DRAFT)
        CORE-->>FOC: 400 Bad Request + details
    else Client API unavailable
        CORE-->>CORE: Status unchanged (DRAFT)
        CORE-->>FOC: 503 Service Unavailable
    end

Key point: Unlike sync and update, here any invalid line blocks the status change for the entire order.


Data Model

The fields below are an example of a typical mapping. The actual mapping may vary depending on the variables that determine pricing and stock in the client's system.

Mandatory fields

If any of these is missing, the line will not be processed.

  • Price response: variantExternalId, productQuantity, netUnitPrice, cartLineExternalId
  • Stock response: variantExternalId, productStock

Cart Line Identification

Cart line identification relies on the Cart Line External Id field, mapped to the DJUST field Offer Price External Id:

  • If the Offer Price External Id does not exist in the cart: a new line is created
  • If the Offer Price External Id already exists: the corresponding line is updated

This mechanism allows the source system to:

  • Update existing lines
  • Add new lines (promotions, additional offers)
  • Remove lines (by not returning them during a sync)

Price Module

Request example

RTD FieldDescription
Account External IdExternal identifier of the Account (business entity: company, professional client, or business unit), used to retrieve account-specific pricing
Address External IdExternal identifier of the delivery address, may influence pricing (e.g., regional taxes, shipping conditions)
Variant External IdExternal identifier of the product variant to price
Product QuantityQuantity requested by the buyer, used to compute volume-based pricing

Payload:

{
  "accountExternalId": "ACC-00421",
  "addressExternalId": "ADDR-0078",
  "lines": [
    {
      "variantExternalId": "SKU-10042",
      "productQuantity": 12
    },
    {
      "variantExternalId": "SKU-10098",
      "productQuantity": 5
    }
  ]
}

Response

RTD FieldDescription
Account External IdExternal identifier of the Account (business entity: company, professional client, or business unit)
Address External IdExternal identifier of the delivery address
Variant External IdExternal identifier of the product variant
Product QuantityConfirmed quantity (may differ from requested if adjusted by the source system)
Product Tax RateApplicable tax rate (e.g., 20.0 for 20%), used to compute the price including taxes
Product Tax CodeTax code identifier (e.g., "VAT-20"), stored via the Offer Custom Field role
Net Unit PriceUnit price excluding taxes, as calculated by the source system
Cart Line External IdUnique line identifier from the source system, used to match and reconcile cart lines in DJUST

Payload:

{
  "accountExternalId": "ACC-00421",
  "addressExternalId": "ADDR-0078",
  "lines": [
    {
      "variantExternalId": "SKU-10042",
      "productQuantity": 12,
      "netUnitPrice": 24.50,
      "productTaxRate": 20.0,
      "productTaxCode": "VAT-20",
      "cartLineExternalId": "LINE-001"
    },
    {
      "variantExternalId": "SKU-10098",
      "productQuantity": 5,
      "netUnitPrice": 8.75,
      "productTaxRate": 20.0,
      "productTaxCode": "VAT-20",
      "cartLineExternalId": "LINE-002"
    }
  ]
}

Stock Module

Request example

RTD FieldDescription
Account External IdExternal identifier of the Account (business entity: company, professional client, or business unit)
Variant External IdExternal identifier of the product variant to check stock for

Example payload:

{
  "accountExternalId": "ACC-00421",
  "lines": [
    {
      "variantExternalId": "SKU-10042"
    },
    {
      "variantExternalId": "SKU-10098"
    }
  ]
}

Response

RTD FieldDescription
Account External IdExternal identifier of the Account (business entity: company, professional client, or business unit)
Variant External IdExternal identifier of the product variant
Product StockAvailable stock quantity (decimal values are truncated to integer)

Payload:

{
  "accountExternalId": "ACC-00421",
  "lines": [
    {
      "variantExternalId": "SKU-10042",
      "productStock": 150
    },
    {
      "variantExternalId": "SKU-10098",
      "productStock": 42
    }
  ]
}

Client Connector: Mapping

Each client connector defines a bidirectional mapping between the generic RTD model and the specific format of the client's REST API. Only REST APIs are eligible as client connectors for RTD.

Key Concepts

  • Request mapping: transforms DJUST data into the client API payload
  • Response mapping: transforms the client API response into DJUST data
  • Constant values: some fields can be hardcoded in the connector configuration (e.g., application identifier, calculation flags)
  • Custom Fields: client-specific fields are mapped to Custom Fields on Order Lines or Order Logistic

Mandatory Fields

A setting allows you to define for each mapping field whether it must be present in the API call. If a mandatory field is missing, the API call is not triggered.


Validation Rules

Validations

Before updating the cart, the RTD module checks that:

  • The order exists and is in DRAFT status
  • The user is authorized
  • The supplier, product and variant are active
  • The Variant External Id and Cart Line External Id are present
  • The stock is sufficient for the requested quantity
  • The quantity is valid (positive, and a multiple of items per pack if applicable)

Behavior by Context

EventInvalid lineImpact
Add to cartLine is not addedBlocking warning returned to the Storefront
Cart syncLine is not updated/addedWarning returned; other lines are processed normally
Transition to CREATEDOrder stays in DRAFT400 Bad Request returned with error details

Quantity Management

The behavior for zero-quantity lines depends on the CART_LINES_0_QUANTITY_AUTHORIZED feature flag:

SituationFlag = TRUEFlag = FALSE
New line with quantity 0Addition allowedAddition refused (blocking warning)
Existing line drops to 0Line retainedLine removed (non-blocking warning)
Quantity < 0Line removedLine removed

Stock Management

  • Decimal stock values are truncated (e.g., 7.68 -> 7)
  • If the same variant appears on multiple lines, stock is compared against the total ordered quantity for that variant
  • A null stock triggers a blocking warning

Response Handling

Non-blocking Warnings (line is updated)

CaseMessage
Price changeThe price for this item has been updated from {old} to {new}.
Quantity changeThe quantity of this item has changed from {old} to {new}.
New line added (promo)A new line item was returned with a quantity of {X}.
Line removed (absent from response)The line item has been deleted since it was not included in the latest client API response.
Line removed (quantity ≤ 0)This line has been removed because the returned quantity is less than 0, which is not allowed.
Non-required custom field missingThe custom field values could not be processed; {reason}.

Blocking Warnings (line is NOT updated)

CaseMessage
Insufficient stockThere is not enough stock {stock} for quantity {qty}
Zero quantity not allowedLine with 0-quantity is not allowed.
Negative quantityThe quantity is lower than 0.
Inactive/unknown product or variantProduct variant does not exist OR one of the following is not active: product, product variant.
Null priceNo valid price information was provided for this line. The item could not be processed.
Null stockNo valid stock information was provided for this line. The item could not be processed.
Null tax rateOffer need to have tax custom field value when required.
Null tax codeOffer need to have tax code custom field value when required.

Configuration

Prerequisites

  • Checkout V3 required: RTD only works with the Checkout V3 flow. In this model, the cart is a commercial order in DRAFT status.
  • Offer Price & Offer Inventory are ignored: When RTD is active, imported Offer Prices and Offer Inventories are completely bypassed during cart validations. All pricing and stock data comes exclusively from the client's REST API in real time.
  • Tax Custom Fields & Roles: The Product Tax Rate and Product Tax Code fields returned by the client's API are used to compute the price including taxes. For this to work, you must:
    1. Create two Custom Fields on the Offer entity:
      • tax_rate
      • tax_code
    2. Assign the corresponding Custom Field Roles in Settings > Custom field roles > Offer:
      • Product tax ratetax_rate
      • Product tax codetax_code
  • Minimum data required in DJUST: The following entities must be imported before using RTD: Supplier, Account, Customer User, Products and Product Variants.

Feature Flags

FlagTypeDefaultDescription
REAL_TIME_PRICINGBooleanFALSEEnables the Real-Time Data module. When TRUE, prices and stock are systematically retrieved in real time.
CART_LINES_0_QUANTITY_AUTHORIZEDBooleanFALSEAllows order lines with a quantity of 0.

Timeout

A default timeout of 30 seconds is configured for client API calls. Beyond this threshold, a 503 Service Unavailable response is returned.


API Endpoints

Cart Line Update

PUT /v2/shop/commercial-orders/{commercialOrderId}/lines

RTD trigger: Module Price + Module Stock for the affected product(s)

Cart Synchronization

PUT /v1/shop/commercial-orders/{commercialOrderId}/sync

RTD trigger: Module Price + Module Stock for the entire cart

Transition to CREATED

PUT /v1/shop/commercial-orders/{orderCommercialId}/created

RTD trigger: Module Stock for the entire cart