Інтеграція електронного підпису DocuSign на сайт
DocuSign — лідер ринку електронних підписів в США та Європі. Підтримує юридично обов'язуючі підписи за стандартами eIDAS (Європа), UETA/ESIGN (США) та низкою національних стандартів. Для російського ринку важливо: DocuSign надає просту електронну підпис (ПЕП), яка визнається в суді при наявності угоди сторін — для більшості комерційних договорів цього достатньо.
Архітектура інтеграції
Типовий флоу:
- На сайті користувач заповнює дані → натискає «Підписати договір»
- Backend створює Envelope (конверт) у DocuSign з документом і одержувачами
- Користувач перенаправляється на DocuSign для підписання (або отримує email)
- Після підписання DocuSign сповіщає сайт через webhook
- Backend скачує підписаний документ і зберігає його
Налаштування додатка
У DocuSign Developer Portal: створити Integration Key → додати redirect URI → запросити Secret Key. Для тестування — безплатне Demo середовище (account-d.docusign.com).
composer require docusign/esign-client
// config/docusign.php
return [
'integrator_key' => env('DOCUSIGN_INTEGRATOR_KEY'),
'client_secret' => env('DOCUSIGN_CLIENT_SECRET'),
'account_id' => env('DOCUSIGN_ACCOUNT_ID'),
'base_url' => env('DOCUSIGN_BASE_URL', 'https://demo.docusign.net/restapi'),
'redirect_uri' => env('DOCUSIGN_REDIRECT_URI'),
];
OAuth: отримання токена
DocuSign використовує OAuth 2.0 Authorization Code Grant:
class DocuSignAuthService
{
public function getAuthUrl(): string
{
$params = http_build_query([
'response_type' => 'code',
'scope' => 'signature',
'client_id' => config('docusign.integrator_key'),
'redirect_uri' => config('docusign.redirect_uri'),
]);
// Demo: account-d.docusign.com, Prod: account.docusign.com
return 'https://account-d.docusign.com/oauth/auth?' . $params;
}
public function handleCallback(string $code): string
{
$response = Http::withBasicAuth(
config('docusign.integrator_key'),
config('docusign.client_secret')
)->asForm()->post('https://account-d.docusign.com/oauth/token', [
'grant_type' => 'authorization_code',
'code' => $code,
'redirect_uri' => config('docusign.redirect_uri'),
]);
return $response->json('access_token');
}
}
Для серверних сценаріїв без участі користувача — JWT Grant (сервіс-аккаунт).
Створення конверта та відправка на підпис
class DocuSignEnvelopeService
{
public function createEnvelope(
string $accessToken,
string $pdfPath,
array $signers
): string {
$config = new \DocuSign\eSign\Configuration();
$config->setHost(config('docusign.base_url'));
$config->addDefaultHeader('Authorization', "Bearer {$accessToken}");
$apiClient = new \DocuSign\eSign\client\ApiClient($config);
$envelopesApi = new \DocuSign\eSign\Api\EnvelopesApi($apiClient);
// Документ з файлу
$document = new \DocuSign\eSign\Model\Document([
'document_base64' => base64_encode(file_get_contents($pdfPath)),
'name' => 'Договір',
'file_extension' => 'pdf',
'document_id' => '1',
]);
// Місце для підпису
$signHere = new \DocuSign\eSign\Model\SignHere([
'anchor_string' => '/sig1/', // або фіксовані координати
'anchor_x_offset' => '20',
'anchor_y_offset' => '-10',
'anchor_units' => 'pixels',
]);
$recipientList = [];
foreach ($signers as $i => $signer) {
$tabs = new \DocuSign\eSign\Model\Tabs(['sign_here_tabs' => [$signHere]]);
$recipientList[] = new \DocuSign\eSign\Model\Signer([
'email' => $signer['email'],
'name' => $signer['name'],
'recipient_id' => (string)($i + 1),
'routing_order'=> (string)($i + 1),
'tabs' => $tabs,
]);
}
$envelopeDefinition = new \DocuSign\eSign\Model\EnvelopeDefinition([
'email_subject' => 'Будь ласка, підпишіть документ',
'documents' => [$document],
'recipients' => new \DocuSign\eSign\Model\Recipients([
'signers' => $recipientList,
]),
'status' => 'sent', // 'created' для чорновика
]);
$result = $envelopesApi->createEnvelope(
config('docusign.account_id'),
$envelopeDefinition
);
return $result->getEnvelopeId();
}
}
Embedded Signing: підпис прямо на сайті
Замість переходу на DocuSign — вбудований iframe або редирект назад на сайт:
public function getSigningUrl(string $accessToken, string $envelopeId, array $signer): string
{
$config = new \DocuSign\eSign\Configuration();
$config->setHost(config('docusign.base_url'));
$config->addDefaultHeader('Authorization', "Bearer {$accessToken}");
$apiClient = new \DocuSign\eSign\client\ApiClient($config);
$envelopesApi = new \DocuSign\eSign\Api\EnvelopesApi($apiClient);
$viewRequest = new \DocuSign\eSign\Model\RecipientViewRequest([
'authentication_method' => 'none',
'client_user_id' => $signer['id'], // внутрішній ID користувача
'recipient_id' => '1',
'return_url' => route('contracts.signed'),
'user_name' => $signer['name'],
'email' => $signer['email'],
]);
$result = $envelopesApi->createRecipientView(
config('docusign.account_id'),
$envelopeId,
$viewRequest
);
return $result->getUrl(); // редирект сюди або відкрити в iframe
}
Webhook: сповіщення про підпис
public function handleDocuSignWebhook(Request $request): Response
{
// DocuSign відправляє XML
$xml = simplexml_load_string($request->getContent());
$status = (string)$xml->EnvelopeStatus->Status;
$envelopeId = (string)$xml->EnvelopeStatus->EnvelopeID;
if ($status === 'Completed') {
DownloadSignedDocumentJob::dispatch($envelopeId);
}
return response('OK', 200);
}
Терміни
Базова інтеграція (створення конверта + відправка email підписанту + webhook): 2–3 робочих дні. Embedded signing з повним флоу всередині сайту та автоматичним скачуванням документа: 4–5 робочих днів. Оцінка включає реєстрацію додатка DocuSign, тестування в Demo-середовищі та переключення на Production.







