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?
| Challenge | RTD 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 DJUST | RTD 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:
- Mapping DJUST data to the format expected by the client's REST API
- Calling the client's REST API with the constructed payload
- Mapping the client's API response back to the DJUST data model
- 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
| # | Event | Data Retrieved | Description |
|---|---|---|---|
| 1 | Product list (custom) | Price | Display personalized prices on the product list |
| 2 | Product detail page (custom) | Price | Display the personalized price on the product detail page |
| 3 | Add / update cart line | Price + Stock | Price retrieval and stock verification for the affected product(s) |
| 4 | Cart synchronization | Price + Stock | Full recalculation of the entire cart (prices, stock, promos) |
| 5 | Transition to CREATED | Stock | Final 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
metadatafield 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 Iddoes not exist in the cart: a new line is created - If the
Offer Price External Idalready 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 Field | Description |
|---|---|
| Account External Id | External identifier of the Account (business entity: company, professional client, or business unit), used to retrieve account-specific pricing |
| Address External Id | External identifier of the delivery address, may influence pricing (e.g., regional taxes, shipping conditions) |
| Variant External Id | External identifier of the product variant to price |
| Product Quantity | Quantity 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 Field | Description |
|---|---|
| Account External Id | External identifier of the Account (business entity: company, professional client, or business unit) |
| Address External Id | External identifier of the delivery address |
| Variant External Id | External identifier of the product variant |
| Product Quantity | Confirmed quantity (may differ from requested if adjusted by the source system) |
| Product Tax Rate | Applicable tax rate (e.g., 20.0 for 20%), used to compute the price including taxes |
| Product Tax Code | Tax code identifier (e.g., "VAT-20"), stored via the Offer Custom Field role |
| Net Unit Price | Unit price excluding taxes, as calculated by the source system |
| Cart Line External Id | Unique 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 Field | Description |
|---|---|
| Account External Id | External identifier of the Account (business entity: company, professional client, or business unit) |
| Variant External Id | External identifier of the product variant to check stock for |
Example payload:
{
"accountExternalId": "ACC-00421",
"lines": [
{
"variantExternalId": "SKU-10042"
},
{
"variantExternalId": "SKU-10098"
}
]
}Response
| RTD Field | Description |
|---|---|
| Account External Id | External identifier of the Account (business entity: company, professional client, or business unit) |
| Variant External Id | External identifier of the product variant |
| Product Stock | Available 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
DRAFTstatus - 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
| Event | Invalid line | Impact |
|---|---|---|
| Add to cart | Line is not added | Blocking warning returned to the Storefront |
| Cart sync | Line is not updated/added | Warning returned; other lines are processed normally |
| Transition to CREATED | Order stays in DRAFT | 400 Bad Request returned with error details |
Quantity Management
The behavior for zero-quantity lines depends on the CART_LINES_0_QUANTITY_AUTHORIZED feature flag:
| Situation | Flag = TRUE | Flag = FALSE |
|---|---|---|
| New line with quantity 0 | Addition allowed | Addition refused (blocking warning) |
| Existing line drops to 0 | Line retained | Line removed (non-blocking warning) |
| Quantity < 0 | Line removed | Line 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)
| Case | Message |
|---|---|
| Price change | The price for this item has been updated from {old} to {new}. |
| Quantity change | The 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 missing | The custom field values could not be processed; {reason}. |
Blocking Warnings (line is NOT updated)
| Case | Message |
|---|---|
| Insufficient stock | There is not enough stock {stock} for quantity {qty} |
| Zero quantity not allowed | Line with 0-quantity is not allowed. |
| Negative quantity | The quantity is lower than 0. |
| Inactive/unknown product or variant | Product variant does not exist OR one of the following is not active: product, product variant. |
| Null price | No valid price information was provided for this line. The item could not be processed. |
| Null stock | No valid stock information was provided for this line. The item could not be processed. |
| Null tax rate | Offer need to have tax custom field value when required. |
| Null tax code | Offer 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
DRAFTstatus. - 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 RateandProduct Tax Codefields returned by the client's API are used to compute the price including taxes. For this to work, you must:- Create two Custom Fields on the Offer entity:
tax_ratetax_code
- Assign the corresponding Custom Field Roles in Settings > Custom field roles > Offer:
- Product tax rate →
tax_rate - Product tax code →
tax_code
- Product tax rate →
- Create two Custom Fields on the Offer entity:
- Minimum data required in DJUST: The following entities must be imported before using RTD: Supplier, Account, Customer User, Products and Product Variants.
Feature Flags
| Flag | Type | Default | Description |
|---|---|---|---|
REAL_TIME_PRICING | Boolean | FALSE | Enables the Real-Time Data module. When TRUE, prices and stock are systematically retrieved in real time. |
CART_LINES_0_QUANTITY_AUTHORIZED | Boolean | FALSE | Allows 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
Updated about 1 month ago
