Реалізація електронного підпису документів на сайті

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

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

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

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

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація електронного підпису документів на сайті
Складна
~1-2 тижні
Часті питання

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

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

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

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

Впровадження електронного підписання документів

Електронна підпис у веб-програмі вирішує юридично значущі завдання: підписання договорів, прийняття пропозиції, підтвердження транзакцій. Типи: проста ЕП (ПЕП — логін/пароль/SMS-код), посилена некваліфікована (НЕП — крипто), кваліфікована (КЕП — тільки через УЦ).

Проста ЕП: SMS-підписання договору

Найпоширеніший підхід для B2C: користувач отримує код по SMS, вводить його, PDF-договір фіксується з отміткою часу, IP, fingerprint. Юридично значима як проста ЕП при наявності угоди про використання ЕП.

class DocumentSigningService
{
    public function initiateSignin(Document $document, User $user): void
    {
        $code = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
        Cache::put("signing_code:{$document->id}:{$user->id}", bcrypt($code), now()->addMinutes(15));
        $user->notify(new DocumentSigningCodeNotification($code, $document));
    }

    public function confirmSigning(Document $document, User $user, string $code, Request $request): void
    {
        $cached = Cache::get("signing_code:{$document->id}:{$user->id}");

        if (!$cached || !Hash::check($code, $cached)) {
            throw new InvalidSigningCodeException('Невірний код');
        }

        $documentHash = hash('sha256', Storage::disk('s3')->get($document->path));

        $document->update([
            'status'           => 'signed',
            'signed_at'        => now(),
            'signed_by'        => $user->id,
            'document_hash'    => $documentHash,
            'signing_metadata' => [
                'ip'            => $request->ip(),
                'user_agent'    => $request->userAgent(),
                'method'        => 'sms_code',
                'phone_last4'   => substr($user->phone, -4),
                'signed_at_iso' => now()->toIso8601String(),
            ],
        ]);

        AuditLog::create([
            'action'      => 'document.signed',
            'user_id'     => $user->id,
            'document_id' => $document->id,
        ]);

        $user->notify(new DocumentSignedNotification($document));
    }
}

Візуальна підпис: canvas + API

import SignatureCanvas from 'react-signature-canvas';

function DocumentSigner({ documentId }: { documentId: number }) {
  const sigCanvas = useRef<SignatureCanvas>(null);
  const [step, setStep] = useState<'draw' | 'confirm' | 'sms'>('draw');

  const handleDrawComplete = async () => {
    if (sigCanvas.current?.isEmpty()) return;

    const signatureData = sigCanvas.current!.toDataURL('image/png');
    await api.post(`/documents/${documentId}/initiate`, { signature_image: signatureData });
    setStep('sms');
  };

  return (
    <div>
      {step === 'draw' && (
        <>
          <p>Намалюйте вашу підпис:</p>
          <SignatureCanvas ref={sigCanvas} penColor="#1a1a1a" canvasProps={{ width: 500, height: 200 }} />
          <button onClick={handleDrawComplete}>Далі</button>
        </>
      )}
    </div>
  );
}

Вбудовування підпису в PDF

use setasign\Fpdi\Fpdi;

class SignedPdfService
{
    public function addSignatureStamp(string $pdfPath, array $signing): string
    {
        $pdf = new Fpdi();
        $pageCount = $pdf->setSourceFile($pdfPath);

        for ($i = 1; $i <= $pageCount; $i++) {
            $templateId = $pdf->importPage($i);
            $pdf->AddPage();
            $pdf->useTemplate($templateId);

            if ($i === $pageCount) {
                $pdf->SetFont('DejaVu', '', 8);
                $stamp = implode("\n", [
                    "Електронно підписано",
                    "Підписувачем: {$signing['user_name']}",
                    "Дата: {$signing['signed_at']}",
                    "SHA-256: " . substr($signing['document_hash'], 0, 16),
                    "IP: {$signing['ip']}",
                ]);
                $pdf->MultiCell(0, 4, $stamp, 'D', 'L');
            }
        }

        $signedPath = str_replace('.pdf', '_signed.pdf', $pdfPath);
        $pdf->Output('F', $signedPath);
        return $signedPath;
    }
}

Перевірка підпису

public function verify(Document $document): bool
{
    $currentHash = hash('sha256', Storage::disk('s3')->get($document->path));
    return hash_equals($document->document_hash, $currentHash);
}

Підписані документи зберігаються з незмінними правами (S3 Object Lock) для запобігання фальсифікації.

Тривалість реалізації

Завдання Тривалість
Проста ЕП (SMS + аудит) 3–4 дні
Canvas підпис + вбудовування в PDF +2–3 дні
Інтеграція СБИС або КриптоПро КЕП 5–7 днів
Повна система з сховищем та перевіркою 7–10 днів