Зауважимо: коли клієнт заходить на сайт, оформлює замовлення і має підписати договір — кожен крок повинен бути безшовним. 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 та прискорте документообіг. Оцінимо ваш проєкт безкоштовно і запропонуємо оптимальне рішення.







