Зауважимо: коли клієнт заходить на сайт, оформлює замовлення і має підписати договір — кожен крок повинен бути безшовним. 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 | Гнучкість, будь-який документ | Ручне розмічання полів підпису |
З шаблону — оптимальний варіант для типових договорів. Кроки створення:
- Отримайте ідентифікатор шаблону з PandaDoc.
- Підготуйте масив отримувачів та токенів.
- Викличте API для створення документа.
- Дочекайтеся статусу
document.uploaded. - Відправте документ на підпис.
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 та прискорте документообіг. Оцінимо ваш проєкт безкоштовно і запропонуємо оптимальне рішення.







