Подготавливаем страницу…
Подготавливаем страницу…
Самый надёжный способ интеграции: ключ sk_ живёт на сервере, защищается через IP whitelist или HMAC. Подходит для любого языка и инфраструктуры.
sk_ (secret — только server-side) forms_scope=[id1, id2, …] — и в каждом запросе передаёте form_id в body.Ключ создаёт менеджер 1ОПД и передаёт вам один раз. Все endpoints → API Reference
Прочитайте один раз — дальше в инструкции эти слова уже не будут пугать.
От этого зависит дальнейшая настройка.
Подходит: bare-metal сервер, VPS со статичным IP, dedicated хостинг.
Минус: при смене сервера нужно обновлять whitelist. Не подходит для AWS Lambda / Cloud Run / kubernetes где IP'ы динамические.
Подходит: контейнеры, serverless, кластеры, динамическая инфраструктура.
Минус: чуть больше кода (подписание каждого запроса). Зато не зависит от IP.
С нужным типом защиты.
Зайдите в ЛК 1ОПД → «Интеграция» . Если sk_ ключа ещё нет — попросите менеджера выпустить.
OPD_SECRET_B64 (base64 секрет, показывается один раз — храните в надёжном месте).Не в код, не в git — только через ENV.
Никогда не записывайте sk_ или OPD_SECRET_B64 прямо в коде. Использовать ENV-переменные:
# В .env / /etc/environment / systemd Unit / docker-compose.yml
OPD_KEY=sk_abc12345678901234567890
# Для HMAC дополнительно:
OPD_SECRET_B64=base64encodedsecretXYZ== env[OPD_KEY]= или getenv() из системного env.Ниже — playground с переключателем. Выбирайте язык + опционально HMAC.
Нажмите на язык (PHP / Node.js / Python) и включите чекбокс «Подписывать HMAC» если используете этот тип защиты.
<?php
$body = json_encode([
"form_id" => 1, // ← form_id из ЛК 1ОПД
"hash_field" => $_POST["email"],
"fields" => [
["field" => "email", "value" => $_POST["email"]],
["field" => "name", "value" => $_POST["name"]],
["field" => "phone", "value" => $_POST["phone"]],
],
]);
$ch = curl_init("https://app.1opd.ru/api/v2/create-agreement");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_HTTPHEADER => [
// sk_ + IP whitelist в ЛК ИЛИ sk_ + HMAC (переключите вкладку)
"API-KEY: sk_xxxxxxxxxxxxxxxxxxxx", // ← ваш sk_ ключ
"Content-Type: application/json",
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
curl_close($ch);
error_log("1ОПД hash: " . ($data["hash"] ?? "(error)")); form_id: 1 на ваш номер формы из ЛК.fields под поля вашей формы.OPD_KEY (и OPD_SECRET_B64 если HMAC) корректно подгружены из ENV.Знать алгоритм пригодится для debug'а и если пишете на другом языке.
Подпись считается над конкатенацией timestamp и тела запроса, разделённых переводом строки. Алгоритм — HMAC-SHA256, результат в base64. Секрет хранится в base64, перед вычислением декодируется в bytes.
API-SIGN = base64( HMAC-SHA256( ts + "\n" + body_bytes, base64_decode(secret) ) ) ts — unix-timestamp в секундах (строка). Например 1731936000.body_bytes — точные байты JSON, которые вы отправляете. Сериализуйте один раз и используйте и для подписи, и для отправки. Иначе любая разница в пробелах = неправильная подпись. API-KEY + API-SIGN + API-TIMESTAMP .data=body вместо json=... — иначе requests пересериализует JSON и подпись не совпадёт. Также использовать json.dumps(..., separators=(",", ":")) — без лишних пробелов.Логи сервера + ЛК 1ОПД.
1ОПД hash: ABC123… (если не ошибка).Самые частые проблемы и что с ними делать. Решает 95% случаев.
1. Сериализуйте JSON один раз: body = json.dumps(...), используйте этот string и для подписи, и для отправки.
2. В Python: data=body вместо json=.... json=... requests пересериализует и подпись поломается.
3. Разделитель между ts и body — именно \n (LF), не CRLF.
4. base64-кодирование результата HMAC, не hex.
Синхронизируйте время через NTP: sudo timedatectl set-ntp true (Ubuntu/Debian).
В Docker контейнере время наследуется от хост-машины — проверьте часы хоста.
На сервере: curl ifconfig.me — узнаете текущий внешний IP. Добавьте в ЛК 1ОПД → ключ → IP-whitelist.
Если у инфраструктуры несколько исходящих IP (load balancer, NAT-пул) — добавьте все.
Альтернатива: переходите на HMAC — не зависит от IP.
1. Перезапустите сервис после изменения .env.
2. Для systemd: добавьте в Unit-файл EnvironmentFile=/path/to/.env или Environment="OPD_KEY=sk_...", затем systemctl daemon-reload и restart.
3. Для Docker: проверьте что переменная передана через docker-compose environment или --env-file.
4. На PaaS (Vercel/Railway/Render): добавьте через UI Environment Variables.
Проверьте: на сервере curl https://app.1opd.ru/healthz — должно вернуть JSON.
Если timeout — свяжитесь с провайдером, попросите открыть исходящие 443 для app.1opd.ru.
Особенно частая проблема у дешёвых shared-хостингов.
Рекомендация: не блокируйте основную бизнес-логику. Обернуть вызов 1ОПД в try/catch (или async fire-and-forget), и если 1ОПД временно недоступен — продолжать обработку формы как обычно.
Альтернатива: писать в локальную очередь (Redis/SQS/RabbitMQ) и асинхронно ретраить запись в 1ОПД. Так согласие не теряется даже если оба сервера временно недоступны.
Если у каждого вашего клиента — отдельный tenant в 1ОПД (свой набор форм), то у каждого свой sk_ ключ. Храните в БД: tenant.opd_api_key, tenant.opd_hmac_secret_b64.
Если все ваши клиенты пишут в одного 1ОПД-tenant'а (вы единый оператор ПД, клиенты — конечные пользователи) — один глобальный sk_ + разные form_id через forms_scope.
Откройте ЛК → «Интеграция»: персональные snippet'ы + готовый HTML-чекбокс с авто-ссылками на согласие и политику + кнопка «IP-whitelist» для каждого ключа.
Открыть ЛК →Запросите тестовый доступ — выдаём ключ под ваш домен и помогаем подключиться.
Связаться →Все endpoints, коды ошибок, форматы HMAC/Origin/IP. Таблица «какую защиту выбрать».
Открыть →