It is often useful to embed openCPQ-based configurators into an enterprise application such as an ERP, CRM or e-commerce system. When users work with a configurable product, they get the opportunity to configure the product using an appropriate configurator. The resulting configured product can then be added as an item to a business document such as a quotation, an order or an invoice, or to a shopping cart.
Providing configuration support in an enterprise application involves two aspects:
The data-management functionality must be implemented as an extension to the embedding enterprise application. These systems are typically designed to support extensions like this. Some enterprise applications already come with support for configurability.
Since an implementation of the data-management part depends mostly on the embedding system and not that much on the configurator technology, we will not go into more details here. We will rather concentrate on the interaction between an embedding application and a configurator.
Therefore we recommend to display a configurator in a separate window.
To make this window controllable by the embedding application, it will be inside
It is the embedding application's responsibility to open an
iframe with a
src attribute pointing to the appropriate configurator and to close it again
when it is no more needed.
A nice extra benefit of this approach is that it does not only decouple configurators from the embedding application, but also configurators from each other. In particular it is not necessary that all configurators use the same version of openCPQ or other libraries. So if you want to use a recent version of openCPQ or another library for configuring a new product, you are not forced to upgrade the configurators for your other configurable products. Since the protocol for communicating with configurators is quite simple, it is even possible to implement it for configurators which are not based on openCPQ at all.
Enterprise applications with Web UIs typically use client-side components implementing some given API. Users of such an application can add their own components as long as these components behave as expected. The interfacing between the configurator and the embedder should be implemented as such a component.
Such an embedding component can and should be independent of particular configurable products and their configurators. It should only depend on a generic configurator interface provided by openCPQ and on the extension interface of the enterprise application.
With the decoupling described above the question arises whether the configurator should communicate with the client or the server of the embedding enterprise application.
Enterprise applications often provide protocols for communicating with their servers. However we do not recommend to use this from a configurator. We rather recommend to communicate exclusively with the client component of the embedding application. This is for the following reasons:
A much safer approach is to use cross-window messaging. This also makes it possible to load the configurator from a different server or even from a plain file, which is particularly useful in a development or test environment.
The openCPQ library provides utilities for this messaging.
embed wraps the configurator in a top-level element sending and
receiving these messages:
"ready"message to the parent window when it has been loaded.
"init"message, optionally carrying an initial configuration.
"close"message to the embedding window.
"close" message may contain a new configuration to be stored by the
It can also be passed into another configurator instance via the
message if a user wants to update the configuration later.
To reduce dependencies, configurations are encoded as strings in a format that
is opaque to the embedder.
"close" message may contain additional data derived from the
configuration such as a price or a textual representation to be used in business
The cross-window messaging mechanism allows the sender of a message to specify that the message should only be delivered if the target window contains a document from a particular origin. Similarly an incoming message is accompanied by the URL of the sending document, which allows the receiver to ignore the message if it is not from the expected document.
Since the embedding application knows the configurator's URL, it can easily make use of these security mechanisms. In contrast to this, on the configurator side we cannot check if a message comes from the "expected" embedding application (unless we hard-wired the embedder URL in the configurator code, which would make the configurator harder to manage). As long as the configurator does not manipulate persistent data and only communicates to its parent window (as recommended in section "Communication Counterpart"), this should not be a security problem from the configurator perspective. If, however, the configurator directly manipulates data on the server, more extensive security mechanisms are needed.
The top-level component created by the
embed function adds a toolbar to the
"close"message with or without return data) and
It turned out that having the "OK" and "Close" buttons on a toolbar inside the configurator iframe (as oppoosed to having these buttons in the embedding API) does not only provide a better user experience but is also easier to implement. Nevertheless it is usually a good idea if the embedding application/component also provides the user with a way to forcefully close the configurator iframe, just for the case that the configurator toolbar does not work due to some problem in the configurator.
The embedder should react to a
"close" message by closing the configurator
iframe and possibly storing any returned data.
In this document we have described the architectural considerations for a "standard" way of embedding openCPQ-based configurators. For more details have a look at the code of the examples mentioned at the beginning of this document.
If for whatever reason some of these decisions are not appropriate for your
case, feel free to deviate.
In particular it is not mandatory to use the
embed function provided by
You can implement your own embedding mechanism and even use bits and pieces
from openCPQ as needed.