Документація / Вбудовування віджета та iframe API

Вбудовування віджета та 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: 'uk'},
        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})
}