Встраивание виджета и iframe API
Встройте виджет Configo во внешнюю систему и управляйте им через postMessage — конфигурация, данные о продукте и обмен правками.
Виджет Configo — это самостоятельная страница калькулятора/конфигуратора (/widget/{configurator}?token=...),
предназначенная для встраивания в виде <iframe> внутрь другой системы — обычно CRM. В таком сценарии заказ и
оформление остаются целиком внутри системы-хоста; используется только сам калькулятор. Эта страница описывает, как
встроить виджет и как общаться с ним со страницы-хоста через postMessage.
Получение ссылки на виджет
Ссылка на виджет привязана к проекту и набору прав, закодированных в подписанный токен. Сгенерируйте её в Проект → Настройки → Виджет: выберите права, которые должны быть у встроенного виджета (показывать ли встроенную корзину, какие цены видны, переопределение/корректировка цены, печать документов), затем нажмите Сгенерировать. Вы получите:
- Прямую ссылку —
https://configo.org/widget?token=<jwt>— открывает список калькуляторов проекта, либоhttps://configo.org/widget/{configurator_uuid}?token=<jwt>для конкретного. - Код встраивания, загружающий
/widget/script.jsи открывающий виджет в модальном<iframe>по клику.
Токен — единственный контроль доступа: любой, у кого есть ссылка, может использовать виджет в рамках прав, с которыми она была сгенерирована. Относитесь к ней как к учётным данным; перевыпустите её, если она утечёт.
Встраивание
Вариант A — скрипт встраивания
<script>
window.configo = {
id: 'configo',
btn: {class: '', style: '', text: 'Open configurator'},
iframe: {width: '800px', height: '600px'},
token: '<jwt>',
// optional — sent as set_config / put_product right after the widget signals ready
config: {mode: 'calculator'},
product: null,
events: {
onReady: () => {},
onConfiguratorLoaded: (data) => {},
onCalculated: (product) => {},
onAddToCart: (product) => {},
onProduct: (product, trigger) => {},
onConfigApplied: (type, payload) => {},
onError: (error) => {},
},
}
</script>
<script id="configo" src="https://configo.org/widget/script.js" referrerpolicy="no-referrer"></script>
Это отрисовывает кнопку, открывающую виджет в модальном <iframe> (или в новой вкладке на мобильных). После загрузки
скрипта доступны window.configo.setConfig(config) и window.configo.putProduct(product) — для отправки сообщений
после того, как виджет уже открыт; window.configo.close() закрывает его.
Вариант B — обычный iframe
Также можно встроить /widget/{configurator}?token=<jwt> в свой собственный <iframe> напрямую, без вспомогательного
скрипта. Протокол сообщений ниже работает так же — он не зависит от script.js, только от самой страницы виджета.
Протокол сообщений
Оба направления используют один и тот же конверт:
{"source": "configo", "type": "...", "payload": {...}}
Виджет принимает только сообщения такой формы; всё остальное игнорируется. Проверки origin нет ни с одной из сторон
— токен, встроенный в URL виджета, является реальной границей доступа, а не канал postMessage.
События от виджета
Отправляются виджетом через window.top.postMessage(...). Если вы используете script.js, они соответствуют
window.configo.events.*.
type |
Когда | payload |
|---|---|---|
ready |
Один раз, когда виджет смонтирован | {project_uuid} |
configurator_loaded |
Каждый раз, когда показывается или меняется конкретный калькулятор | {configurator_uuid, name} |
post_product |
При каждом пересчёте и при клике на кнопку действия | {configurator_uuid, trigger: "change" | "add_to_cart", product} |
config_applied |
После обработки сообщения set_config |
{ok: true} |
product_applied |
После обработки сообщения put_product |
{ok: true} |
error |
Сообщение set_config/put_product было некорректным |
{code, message} |
product имеет одинаковую форму в каждом случае:
{
"name": "Custom Table",
"configuration": {"<control_id>": "<value>", "...": "..."},
"materials": [{"uuid": "...", "name": "Oak board", "unit": "pcs", "quantity": "2.000"}],
"parts": [ /* production sheet, same shape as calculated in the configurator */ ],
"purchase_price": 120.5,
"sale_price": 199
}
trigger в post_product сообщает, почему сработало событие: "change" означает, что клиент отредактировал
параметр (с задержкой, так что вы не получите по сообщению на каждое нажатие клавиши), "add_to_cart" означает, что
клиент нажал кнопку действия — это момент, когда нужно реально сохранить позицию в вашей собственной системе,
поскольку "change" срабатывает непрерывно, пока виджет открыт.
Команды виджету
Отправляйте их в contentWindow iframe (или используйте window.configo.setConfig() / .putProduct(), если вы
используете скрипт встраивания). Дождитесь ready, прежде чем отправлять что-либо — сообщения, отправленные до того,
как виджет смонтировал свой слушатель, теряются.
set_config — настроить виджет. Каждое поле опционально и только переопределяет то, что вы отправляете; всё
опущенное сохраняет предыдущее значение.
{
"mode": "calculator",
"locale": "en",
"labels": {
"add": "Add to order",
"edit": "Update"
},
"styles": {
"dark": true,
"vars": {
"--primary": "#1d4ed8"
}
},
"calculator": "<configurator_uuid>",
"product": {
"configuration": {
"<control_id>": "<value>"
}
}
}
| Поле | Тип | Эффект |
|---|---|---|
mode |
"full" | "calculator" |
"calculator" скрывает иконку корзины, сайдбар и форму оформления, независимо от права show_cart токена — используйте, когда заказы принадлежат вашей системе. "full" восстанавливает поведение по умолчанию (корзина показана, если токен это разрешает). |
locale |
"en" | "ru" | "uk" |
Переключает язык интерфейса виджета немедленно, без перезагрузки. |
labels |
{add?, edit?} |
Переопределяет текст кнопки действия (имеет приоритет над URL-параметром lbl_add). |
styles |
{dark?, vars?} |
dark переключает тёмную тему. vars задаёт произвольные CSS-переменные на корневом элементе виджета — используйте для точечного брендирования (акцентный цвет, радиусы и т. д.), а не для полной смены темы, поскольку виджет пока не предоставляет альтернативных именованных тем. |
calculator |
uuid | Переходит к этому калькулятору. Имеет смысл только когда виджет был открыт на списке калькуляторов (/widget без uuid в пути). |
product |
объект, похожий на продукт | Удобство для предзаполнения калькулятора в том же обмене сообщениями, что и остальная конфигурация — эквивалентно отправке put_product сразу после. Требует как минимум configuration. |
put_product — загрузить продукт в текущий отображаемый калькулятор, например чтобы дать клиенту отредактировать
позицию, ранее сохранённую в вашей системе:
{
"configuration": {
"<control_id>": "<value>",
"...": "..."
}
}
Читается только configuration; всё остальное (цену, материалы, название) виджет пересчитывает сам. Это тот же
механизм, который виджет использует внутренне при редактировании позиции в корзине.
Пример: интеграция только с калькулятором
CRM, которая владеет собственным флоу заказов и хочет использовать только калькулятор:
<script>
window.configo = {
token: '<jwt>',
config: {mode: 'calculator', locale: 'ru'},
events: {
onProduct(product, trigger) {
if (trigger === 'add_to_cart') {
// persist `product` as a line item in the CRM's own order
}
},
},
}
</script>
<script id="configo" src="https://configo.org/widget/script.js"></script>
Чтобы дать клиенту заново открыть и отредактировать ранее сохранённую позицию, откройте виджет на том же калькуляторе
и отправьте put_product, как только он будет готов:
window.configo.events.onReady = () => {
window.configo.putProduct({configuration: savedItem.configuration})
}