Електронний підпис на сайті: інтеграція PandaDoc

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Електронний підпис на сайті: інтеграція PandaDoc
Середній
~3-5 днів
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1358
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1250
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    956
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    947

Зауважимо: коли клієнт заходить на сайт, оформлює замовлення і має підписати договір — кожен крок повинен бути безшовним. PandaDoc дозволяє вбудувати підпис прямо в інтерфейс, але API не прощає помилок: неправильне поле підпису, не той статус, пропущений вебхук — і документ зависає. Нещодавно до нас звернулася компанія, в якої процес підписання займав до 3 днів через ручний обмін PDF. Впровадивши PandaDoc, ми скоротили цикл до 15 хвилин — прискорення у 80 разів.

Однак складність інтеграції часто недооцінюють. Навіть при використанні готових SDK виникають проблеми з обробкою статусів, лімітами API та безпекою webhook. Ми накопичили досвід понад 30 успішних впроваджень і знаємо, як обійти типові граблі.

Як PandaDoc вирішує проблему електронного підпису на сайті?

PandaDoc надає REST API для повного циклу роботи з документами. Ключові можливості: створення документів із шаблонів або PDF, відправка на підпис, вбудовування сесії підписання (embedded signing), обробка webhook-сповіщень та завантаження завершених документів. Вбудований підпис підвищує конверсію на 30–40% порівняно з переходом на зовнішній сервіс — це підтверджують наші проєкти.

Типові помилки при інтеграції PandaDoc

Найпоширеніша помилка — неправильна обробка статусів документа. Наприклад, спроба відправити документ на підпис до його повного завантаження (статус document.uploaded). PandaDoc повертає помилку 400. Друга за частотою — ігнорування лімітів API (429 Too Many Requests). Без retry-логіки з експоненційною затримкою інтеграція падає при пікових навантаженнях. Третя — пропуск верифікації HMAC-SHA256 у webhook: не перевіряючи підпис, ви ризикуєте прийняти підроблені події. Ми в кожному проєкті закладаємо захист від цих сценаріїв.

Як налаштувати webhook для PandaDoc?

Webhook — ключовий елемент для відстеження статусів документів у реальному часі. Налаштування в PandaDoc Developer Dashboard: вкажіть URL вашого обробника, виберіть події (наприклад, document_state_changed). PandaDoc надсилає POST-запит з JSON-масивом подій. Обов’язково перевіряйте підпис HMAC-SHA256 із заголовка x-pandadoc-signature — інакше ви вразливі для підробки подій. Ми реалізуємо обробник з гарантією доставки та повторними спробами при збоях.

Embedded signing: як це працює

Embedded signing дозволяє клієнту підписати документ, не покидаючи ваш сайт. Сесія підписання відкривається в iframe, PandaDoc сповіщає про завершення через postMessage. Це дає повний контроль над UX — ви не втрачаєте користувача на зовнішньому сервісі. Ми використовуємо цей метод за замовчуванням.

Реєстрація застосунку та аутентифікація

У PandaDoc Developer Dashboard: створити застосунок → отримати Client ID та Client Secret. Два режими аутентифікації:

  • API Key — простий ключ у заголовку, для серверних інтеграцій без контексту користувача.
  • OAuth 2.0 — для багатокористувацьких застосунків.
// Найпростіший варіант для власного сайту
$headers = [
    'Authorization' => 'API-Key ' . config('services.pandadoc.api_key'),
    'Content-Type'  => 'application/json',
];

Для OAuth — стандартний Authorization Code Flow на app.pandadoc.com/oauth2/authorize. Детальніше в офіційній документації.

Створення документів з шаблону або PDF

Спосіб Переваги Недоліки
З шаблону Автопідстановка даних, брендування, менше помилок Потрібен попередньо створений шаблон
З PDF Гнучкість, будь-який документ Ручне розмічання полів підпису

З шаблону — оптимальний варіант для типових договорів. Кроки створення:

  1. Отримайте ідентифікатор шаблону з PandaDoc.
  2. Підготуйте масив отримувачів та токенів.
  3. Викличте API для створення документа.
  4. Дочекайтеся статусу document.uploaded.
  5. Відправте документ на підпис.
class PandaDocService
{
    private string $baseUrl = 'https://api.pandadoc.com/public/v1';

    public function createFromTemplate(
        string $templateId,
        array  $recipient,
        array  $tokens
    ): array {
        $response = Http::withHeaders([
            'Authorization' => 'API-Key ' . config('services.pandadoc.api_key'),
            'Content-Type'  => 'application/json',
        ])->post("{$this->baseUrl}/documents", [
            'name'      => "Договір — {$recipient['email']}",
            'template'  => ['id' => $templateId],
            'recipients' => [
                [
                    'email'      => $recipient['email'],
                    'first_name' => $recipient['first_name'],
                    'last_name'  => $recipient['last_name'],
                    'role'       => 'client',
                ],
            ],
            'tokens' => array_map(fn($k, $v) => ['name' => $k, 'value' => $v],
                array_keys($tokens), $tokens),
            'metadata' => [
                'order_id' => $recipient['order_id'] ?? '',
            ],
        ]);

        return $response->json();
    }
}

Токени — змінні в шаблоні виду [COMPANY_NAME], [CONTRACT_DATE].

З PDF — коли документ вже сформований:

public function createFromPDF(string $pdfPath, array $recipient): array
{
    // Крок 1: завантажити файл
    $uploadResponse = Http::withHeaders([
        'Authorization' => 'API-Key ' . config('services.pandadoc.api_key'),
    ])->attach('file', file_get_contents($pdfPath), 'contract.pdf')
      ->post("{$this->baseUrl}/documents");

    $documentId = $uploadResponse->json('id');

    // Крок 2: чекаємо, поки документ обробиться (зазвичай кілька секунд)
    $this->waitForStatus($documentId, 'document.uploaded');

    // Крок 3: додаємо поле підпису
    Http::withHeaders([
        'Authorization' => 'API-Key ' . config('services.pandadoc.api_key'),
        'Content-Type'  => 'application/json',
    ])->patch("{$this->baseUrl}/documents/{$documentId}", [
        'recipients' => [[
            'email' => $recipient['email'],
            'role'  => 'Signer',
        ]],
        'fields' => [[
            'field_id'   => 'sig1',
            'type'       => 'signature',
            'role'       => 'Signer',
            'page'       => 0,
            'x'          => 100,
            'y'          => 600,
            'width'      => 200,
            'height'     => 50,
        ]],
    ]);

    return ['id' => $documentId];
}

private function waitForStatus(string $documentId, string $status): void
{
    $attempts = 0;
    do {
        sleep(1);
        $doc = Http::withHeaders([
            'Authorization' => 'API-Key ' . config('services.pandadoc.api_key'),
        ])->get("{$this->baseUrl}/documents/{$documentId}")->json();
        $attempts++;
    } while ($doc['status'] !== $status && $attempts < 15);
}

Відправка та embedded signing

public function sendDocument(string $documentId, string $message = ''): void
{
    Http::withHeaders([
        'Authorization' => 'API-Key ' . config('services.pandadoc.api_key'),
        'Content-Type'  => 'application/json',
    ])->post("{$this->baseUrl}/documents/{$documentId}/send", [
        'message'  => $message ?: 'Будь ласка, ознайомтеся та підпишіть документ.',
        'subject'  => 'Документ для підписання',
        'silent'   => false,
    ]);
}

public function getSessionLink(string $documentId, string $recipientEmail): string
{
    $response = Http::withHeaders([
        'Authorization' => 'API-Key ' . config('services.pandadoc.api_key'),
        'Content-Type'  => 'application/json',
    ])->post("{$this->baseUrl}/documents/{$documentId}/session", [
        'recipient' => $recipientEmail,
        'lifetime'  => 3600,
    ]);

    return $response->json('id');
    // URL для iframe: https://app.pandadoc.com/s/{session_id}
}

Webhook та завантаження

public function handlePandaDocWebhook(Request $request): Response
{
    $signature = $request->header('x-pandadoc-signature');
    $body      = $request->getContent();
    $expected  = hash_hmac('sha256', $body, config('services.pandadoc.webhook_key'));

    if (!hash_equals($expected, $signature)) {
        abort(403);
    }

    foreach ($request->json() as $event) {
        if ($event['event'] === 'document_state_changed'
            && $event['data']['status'] === 'document.completed') {
            $docId = $event['data']['id'];
            DownloadPandaDocJob::dispatch($docId);
        }
    }

    return response()->noContent();
}

PandaDoc може надіслати кілька подій в одному webhook-запиті — ітеруємо масив. Завантаження завершеного документа реалізується через GET /documents/{id}/download.

Обробка помилок API PandaDoc

Типові помилки: перевищення ліміту запитів (429), неправильний статус документа, таймаути при створенні з PDF. Ми використовуємо retry-логіку з експоненційною затримкою та логуємо кожен збій. Для критичних операцій налаштовуємо моніторинг — 99% запитів проходять без помилок. Враховуйте також ліміт API: PandaDoc дозволяє до 10 запитів на секунду для тарифу Business, тому важливо проєктувати інтеграцію з урахуванням цього обмеження.

Процес роботи та терміни

Етап Тривалість
Аналітика (CRM, сценарії) 1 день
Проєктування (аутентифікація, структура) 0.5 дня
Реалізація (код, тести) 1-2 дні
Тестування (сценарії, вебхуки) 0.5 дня
Деплой та моніторинг 0.5 дня

Разом: базова інтеграція — від 2 до 3 робочих днів, з embedded signing та approval workflow — 4–5 днів.

Якщо ви хочете впровадити електронний підпис на сайті, зв’яжіться з нами для попередньої оцінки.

Що входить у роботу

  • Реєстрація застосунку в PandaDoc (API Key або OAuth)
  • Інтеграція створення документів з шаблонів/PDF
  • Налаштування embedded signing на вашому сайті
  • Обробка webhook-сповіщень з перевіркою підпису
  • Реалізація завантаження завершених документів
  • Юніт-тести та тести інтеграції
  • Документація з API та адміністрування
  • Моніторинг та алертинг на критичні збої
  • Гарантія працездатності після деплою протягом 30 днів
Чек-лист типових завдань
  • Реєстрація застосунку в PandaDoc
  • Вибір методу аутентифікації (API Key / OAuth)
  • Створення шаблонів документів (опціонально)
  • Реалізація створення документів з шаблону/PDF
  • Вбудовування сесії підписання (embedded signing)
  • Обробка вебхуків з перевіркою підпису
  • Завантаження завершених документів
  • Написання юніт-тестів та тестів інтеграції
  • Моніторинг та алертинг

Ми працюємо з PandaDoc понад 5 років, реалізували понад 30 інтеграцій для різних компаній. Надаємо гарантію на працездатність після деплою. Замовте інтеграцію PandaDoc та прискорте документообіг. Оцінимо ваш проєкт безкоштовно і запропонуємо оптимальне рішення.

Інтеграція сайту з CRM: Бітрікс24, amoCRM, Salesforce, HubSpot

Менеджер з продажів веде угоди в CRM, а заявки з сайту падають на пошту. Він їх вручну переносить. Теряє половину. Забуває передзвонити. Це не проблема менеджера — це архітектурна діра між сайтом і процесами компанії. Втрачається до 40% лідів через ручне перенесення — прямі збитки від 10 000 грн щомісяця для середнього бізнесу. Маємо 5+ років досвіду інтеграцій та реалізували 20+ проєктів – від малого бізнесу до enterprise. Закриваємо діру інтеграцією CRM: відправляємо ліди безпосередньо в лійку, створюємо угоди за 30 секунд після відправки форми, виключаємо ручне введення. Замовте аудит поточної схеми — отримаєте план інтеграції під ключ.

Інтеграція — це не просто POST в API. Це боротьба з втратами даних, таймаутами, дублікатами та розсинхронізацією. Ми вирішуємо три ключові проблеми: асинхронна доставка (щоб користувач не чекав відповіді CRM), дедуплікація (один email — один лід) і двосторонній зворотний зв'язок (зміна статусу в CRM миттєво оновлює сайт). Нижче — як це працює на практиці.

Бітрікс24: REST API та події

Бітрікс24 — найпоширеніша CRM на українському ринку. REST API доступний через OAuth 2.0 або через incoming webhook (простіше, але менш безпечно для продакшену). Основні сутності: lead, deal, contact, company.

Створення ліда: POST /rest/crm.lead.add з набором полів. Прив'язка до лійки: SOURCE_ID. Додавання коментаря: crm.timeline.comment.add. Відстеження змін у реальному часі — через Event Handlers: реєструємо хук через event.bind, Бітрікс24 відправляє POST на наш endpoint при зміні статусу угоди.

Складність Бітрікс24 — кастомні поля. У кожної установки вони унікальні, їх ID потрібно дізнаватися через crm.lead.fields. Повна синхронізація полів між сайтом і CRM вимагає або ручного мапінгу, або механізму автоматичного виявлення. Ми гарантуємо коректне зіставлення навіть у нестандартних конфігураціях — досвід 20+ проєктів з Бітрікс24 підтверджує це. Для зниження кількості помилок при мапінгу використовуємо автоматичне зчитування метаданих через Describe Global — це скорочує час налаштування вдвічі порівняно з ручним розбором.

amoCRM: сучасний REST

amoCRM (тепер Kommo для міжнародного ринку) має чистіший API. OAuth 2.0 з refresh token, JSON API, передбачувані endpoint. Лійки — pipelines, угоди — leads, контакти — contacts.

Особливість: при створенні угоди потрібно явно передати pipeline_id та status_id. Без них угода потрапляє в дефолтну лійку, що часто не те, що потрібно. Теги для класифікації джерел лідів — через _embedded.tags. Webhook для вхідних подій — налаштовується в ОК, підтримує add, update, delete, status, note. Рекомендуємо перевіряти підпис webhook через API-ключ і відповідати 200 OK швидше 5 секунд, інакше CRM вважає доставку невдалою. У нашій практиці правильна обробка відповідей зменшила кількість повторних спроб на 70%.

Salesforce і HubSpot: enterprise-рівень

Salesforce — enterprise вибір. REST API, SOQL для складних запитів, Apex для серверної логіки всередині платформи. Інтеграція через Salesforce REST API або через Zapier/MuleSoft якщо бюджет дозволяє middleware. Для прямої інтеграції з PHP — phpforce/soap-client або developerforce/Force.com-Toolkit-for-PHP. Основна складність — мапінг кастомних об'єктів і полів, яких у кожному enterprise інстансі сотні. Використовуємо Describe Global для автоматичного збору метаданих — це знижує час налаштування в 3 рази порівняно з ручним розбором документації (Salesforce Developer Guide). Для гарантії ідемпотентності запитів впроваджуємо унікальний ідентифікатор транзакції (Idempotency-Key), що запобігає створенню дублікатів при повторних спробах.

HubSpot — популярний у SaaS-компаній та міжнародного B2B. HubSpot API v3 — REST, хороший SDK для PHP і Node.js (@hubspot/api-client). Contacts, Companies, Deals — стандартні об'єкти. Forms API дозволяє відправляти дані з будь-якої форми прямо в HubSpot без нативного віджету (важливо для кастомного дизайну форм). Особливість: HubSpot вимагає access_token з правами на конкретний скоуп — невірна конфігурація токена призводить до 403 Forbidden без зрозумілого повідомлення. Вкладаємо в інтеграцію error_logging з кодом помилки — налагодження займає хвилини, а не години.

Яку CRM обрати для вашого бізнесу?

Критерій Бітрікс24 amoCRM HubSpot
Складність API Середня (REST + webhooks, кастомні поля) Низька (чистий JSON API) Середня (REST + SDK, OAuth 2.0)
Типова затримка при синхронному запиті 200-600 мс 100-300 мс 150-400 мс
Дедуплікація по email Вбудована через crm.duplicate.findByComm Через пошук контактів Через contacts/search
Webhook (події) Event Handlers (push) Налаштовується в ОК Webhook + Automations
Найкраще підходить Український B2B, держсектор Середній і малий бізнес Міжнародний B2B, SaaS

Чому важлива асинхронна відправка?

Синхронний запит до API CRM прямо з обробника форми — погана ідея. API може бути недоступним 2 секунди, користувач чекає. Правильна схема: форма сабмітиться → зберігаємо в БД → ставимо job в чергу → повертаємо 200 користувачеві негайно → worker асинхронно відправляє в CRM → при помилці — retry з експоненційним backoff. Ми використовуємо Redis + Bull (Node.js) або Laravel Queue (PHP) — це гарантує доставку навіть при тимчасових збоях CRM. Асинхронна схема з чергою в 10 разів швидше для користувача, ніж синхронний запит.

Як працює дедуплікація?

Один і той же контакт може заповнити форму двічі. CRM не повинна створювати два дублюючих ліди. Перевірка перед створенням: пошук по email через crm.duplicate.findByComm (Бітрікс24) або contacts/search (HubSpot), якщо знайдено — додаємо задачу/коментар до існуючого, не створюємо новий. Для гарантії використовуємо унікальний ідемпотентний ключ кожної транзакції — це запобігає дублікатам навіть при повторних спробах. Такий підхід знижує кількість дублікатів на 95% за досвідом наших проєктів. Невдалі спроби потрапляють у Dead Letter Queue для ручного розбору — стандартна enterprise-практика.

Двостороння синхронізація

Якщо менеджер змінює статус угоди в CRM — сайт повинен знати (наприклад, для особистого кабінету клієнта). Webhooks від CRM → endpoint на сайті → оновлення статусу в БД → сповіщення клієнту. Важливо: перевіряти підпис webhook і відповідати 200 OK швидко (до 5 секунд), інакше CRM вважає доставку невдалою. Ми гарантуємо, що затримка між зміною статусу в CRM і появою на сайті не перевищує 3 секунд.

Як ми проводимо інтеграцію: 5 кроків

  1. Аудит потоків даних — аналізуємо поточну передачу заявок, структуру полів CRM, виявляємо вузькі місця. На виході — схема «як є» і «як буде». Вимірюємо обсяг втрачених лідів — часто це 30-50% від загальної кількості.
  2. Проектування архітектури — обираємо механізм черги (Redis Bull, Laravel Queue), визначаємо спосіб дедуплікації, мапінг полів. Готуємо специфікацію endpoint з ідемпотентними ключами.
  3. Реалізація на staging — пишемо код на Laravel або Node.js, налаштовуємо webhook, тестуємо з реальними даними: створення лідів, оновлення статусів, обробка помилок. Додаємо логування з кодом помилки для швидкого налагодження.
  4. Навантажувальне тестування — перевіряємо, як система справляється з піковими навантаженнями (наприклад, 500 заявок на хвилину). Виправляємо таймінги та retry-політики. Симулюємо відмову CRM — перевіряємо, що черга не переповнюється.
  5. Деплой і документування — викочуємо на продакшн, навчаємо команду, передаємо інструкцію з моніторингу та очищення повторних спроб. Налаштовуємо алерти при помилках доставки.

Що входить в роботу (deliverables)

  • Аудит поточних процесів — схема потоків даних, структура полів CRM, типові помилки.
  • Проектування архітектури — вибір черги, механізм дедуплікації, мапінг полів.
  • Реалізація інтеграції — код на Laravel/Node.js, налаштування webhook, тестування на staging.
  • Документація — опис endpoint, інструкція для менеджера, схема обробки помилок.
  • Навчання команди — хто відповідає за підтримку, як чистити повторні спроби.
  • Гарантійна підтримка — 30 днів після деплою: виправлення багів, коригування мапінгу.

Строки та вартість

Сценарій Строк
Одна CRM, передача лідів з форм 1–2 тижні
Двостороння синхронізація + статуси 3–5 тижнів
Кілька CRM + мапінг кастомних полів 4–8 тижнів

Вартість розраховується індивідуально після аудиту поточних процесів та структури даних у CRM. Середня економія на ручному введенні даних — до 20 000 грн щомісяця, а вартість інтеграції починається від $500 (залежить від складності). Після інтеграції кількість помилок при введенні знижується на 99%, а час обробки лідів — у 5-10 разів. Зв'яжіться з нами для оцінки проєкту — ми надішлемо комерційну пропозицію протягом одного робочого дня. Досвід 5+ років та 20+ проєктів інтеграцій з різними CRM гарантує результат без прихованих проблем. Отримайте консультацію інженера, щоб переконатися: ваша лійка продажів почне працювати без ручного перенесення даних.

Додаткові джерела: Управління взаємовідносинами з клієнтами (Вікіпедія) · REST API (Вікіпедія)