Подготавливаем страницу…
Подготавливаем страницу…
Самый простой случай: обычный HTML, статический сайт (Jekyll/Hugo), одностраничник, лендинг. Готовая форма + сниппет — копируете и вставляете.
pk_ (publishable — можно публиковать в браузере) forms_scope=[id1, id2, …] — и в каждом запросе передаёте form_id в body.Ключ создаёт менеджер 1ОПД и передаёт вам один раз. Все endpoints → API Reference
Прочитайте один раз — дальше в инструкции эти слова уже не будут пугать.
Без ключа форма не сможет писать в 1ОПД.
Зайдите на lk.v2.1opd.ru/lk/integrations → найдите карточку вашего сайта → скопируйте pk_ ключ.
form_id формы, под которую интегрируетесь.sk_ — попросите менеджера выпустить именно publishable. sk_ в HTML = ключ сразу скомпрометирован (видно через F12).1ОПД должен знать «этому ключу разрешено работать с этого домена».
В ЛК 1OPD → ваш pk_ ключ → раздел Origin-whitelist. Добавьте все хосты, с которых сайт будет открываться.
https://example.com https://www.example.com https://staging.example.com *.example.com разрешает любые поддомены, но НЕ сам example.com. Если нужны оба — внесите явно оба.*» (звёздочку без домена) — это снимет защиту и ключом сможет пользоваться кто угодно. Если действительно нужна публичная форма — лучше специальный ключ-flood с ограничением на N запросов/час.Нужно вставить туда форму и сниппет.
Где находится HTML — зависит от вашего хостинга:
index.html или contact.html в корне._includes/ или layouts/. После правки нужен `npm run build` (или `hugo`).git push, через 1-2 минуты появится.Замените 3 места: pk_ ключ, form_id, ссылки на ваши документы.
Это полная рабочая форма — HTML и JS уже в одном куске. Замените только выделенные значения.
<!-- Готовая форма + JS-сниппет для статичного HTML-сайта -->
<form id="lead-form"> <input name="email" type="email" required placeholder="Email" /> <input name="name" type="text" required placeholder="Имя" /> <input name="phone" type="tel" placeholder="Телефон" /> <!-- ОСНОВНОЙ чекбокс — согласие на обработку ПДн (ОБЯЗАТЕЛЬНЫЙ). --> <label style="display:flex;gap:8px;align-items:flex-start;font-size:13px"> <input type="checkbox" name="opd_consent" required style="margin-top:3px"> <span> Даю согласие на обработку персональных данных в соответствии с
<a href="https://app.1opd.ru/public/d/<slug>/<client-id>/privacy_policy" target="_blank">Политикой обработки персональных данных</a>.
</span> </label> <!-- ОПЦИОНАЛЬНО: второй чекбокс — маркетинговая рассылка. БЕЗ required. --> <label style="display:flex;gap:8px;align-items:flex-start;font-size:13px;margin-top:8px"> <input type="checkbox" name="opd_consent_marketing" style="margin-top:3px"> <span>Даю согласие на получение информационной и рекламной рассылки.</span> </label> <button type="submit">Отправить</button>
</form> <script>
// Один pk_ ключ обслуживает N форм согласия (multi-form) — для каждой
// поставленной галочки шлём отдельный POST со своим form_id из ЛК 1ОПД.
const OPD_KEY = 'pk_xxxxxxxxxxxxxxxxxxxx'; // ← ваш pk_ ключ
const OPD_API = 'https://app.1opd.ru/api/v2/create-agreement';
const FORM_IDS = {
opd_consent: 1, // основное «Согласие на обработку ПДн»
opd_consent_marketing: 2, // маркетинговая рассылка (опц.)
};
document.getElementById('lead-form').addEventListener('submit', async function (e) {
e.preventDefault();
const fd = new FormData(e.target);
const email = fd.get('email');
// Поля, которые шлём в 1ОПД — без самих чекбоксов (они служебные).
const fields = Array.from(fd.entries())
.filter(function (p) { return p[0] !== 'opd_consent' && p[0] !== 'opd_consent_marketing'; })
.map(function (p) { return { field: p[0], value: String(p[1]) }; });
async function sendConsent(formId) {
try {
const res = await fetch(OPD_API, {
method: 'POST',
headers: { 'API-KEY': OPD_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ form_id: formId, hash_field: email, fields: fields })
});
const data = await res.json();
console.log('1ОПД form_id=' + formId + ' hash:', data.hash);
} catch (err) {
console.warn('1ОПД error (form_id=' + formId + '):', err);
}
}
// На каждую ПОСТАВЛЕННУЮ галочку — свой запрос со своим form_id.
if (fd.get('opd_consent')) await sendConsent(FORM_IDS.opd_consent);
if (fd.get('opd_consent_marketing')) await sendConsent(FORM_IDS.opd_consent_marketing);
// Здесь — ваша основная отправка (Formspree, ваш backend, и т.д.)
// e.target.submit();
});
</script> pk_xxxxxxxx → ваш ключ (3 раза проверьте: всё ли скопировано).form_id: 1 → ваш номер формы из ЛК.preventDefault() — форма не уйдёт штатным образом. Если у вас уже есть AJAX-отправка формы (например на свой backend) — раскомментируйте e.target.submit() в конце JS-кода.DevTools Network + ЛК 1ОПД.
Откройте свою опубликованную страницу с формой. Нажмите F12 → вкладка Network. Заполните и отправьте форму с тестовым email-ом.
POST /api/v2/create-agreement → 200 OK.1ОПД hash: ABC123….Самые частые проблемы и что с ними делать. Решает 95% случаев.
В ЛК 1ОПД → ваш pk_ ключ → Origin-whitelist → добавьте текущий домен (включая и www-вариант, если есть). Подтвердите паролем.
В Console обычно написано какой Origin был отклонён — берите оттуда и копируйте в whitelist.
Уберите e.target.submit() из конца JS-сниппета (или используйте await для fetch'а, чтобы сначала записать в 1ОПД, потом продолжить отправку).
Альтернатива: используйте fetch().then() без await — запрос уйдёт асинхронно ещё до перезагрузки.
Console (F12 → Console) — должны быть красные ошибки JavaScript. Самые частые: неправильный getElementById (ID формы не совпадает с id="lead-form").
Проверьте что атрибут id у вашей формы совпадает с тем что в JS.
Эти placeholder'ы должны быть заменены на реальные значения. Готовые URL'ы доступны в ЛК 1ОПД → «Интеграция» → блок «HTML-чекбокс для формы». Скопируйте оттуда полный URL.
Если хочется чтобы после отправки была своя «спасибо за заявку»-страница: уберите e.preventDefault() в JS и оставьте action="/thanks.html" в форме.
JS-сниппет всё равно успеет отправить запрос в 1ОПД до редиректа (fetch без await асинхронный).
_includes/footer.html или прямо в _layouts/default.html перед </body>.layouts/partials/footer.html.</body>.Сниппет должен загрузиться после формы — иначе document.getElementById вернёт null.
Откройте ЛК → «Интеграция»: персональные snippet'ы + готовый HTML-чекбокс с авто-ссылками на согласие и политику + кнопка «IP-whitelist» для каждого ключа.
Открыть ЛК →Запросите тестовый доступ — выдаём ключ под ваш домен и помогаем подключиться.
Связаться →Все endpoints, коды ошибок, форматы HMAC/Origin/IP. Таблица «какую защиту выбрать».
Открыть →