Kommo + Yousign: электронная подпись документов для EU-команд из воронки продаж
Yousign — EU-ориентированная платформа электронной подписи: eIDAS-совместимая (Регламент ЕС о доверенных электронных сервисах), квалифицированная электронная подпись (QES) для документов с высшим юридическим весом, серверы в Европе, GDPR-compliant. В отличие от DocuSign или Adobe Sign, Yousign создан для EU-рынка — квалифицированная ЭП по французскому и немецкому законодательству, нотариальные документы, банковские соглашения. Нативной интеграции с Kommo нет — разбираем правильную архитектуру через Yousign API v3.
Yousign vs DocuSign vs Adobe Sign для EU-команд
| Параметр | Yousign | DocuSign | Adobe Sign |
|---|---|---|---|
| Юрисдикция | EU-native (eIDAS) | US (eIDAS через партнёра) | US (eIDAS через партнёра) |
| Квалифицированная ЭП | Да (QES) | Через TSP-партнёра | Через TSP-партнёра |
| Серверы | EU (France, GDPR) | US + EU PoP | US + EU PoP |
| Цена | от €25/мес | от $15/user/мес | от $15/user/мес |
| API | REST v3 (современный) | REST (сложный) | REST |
| Подходит для | EU-команды с юридическими требованиями | Глобальные компании | Глобальные компании |
Yousign выбирают EU-компании где электронная подпись должна соответствовать национальному законодательству (Франция, Германия, Нидерланды), а данные не должны покидать ЕС.
Что синхронизируется
Kommo -> Yousign:
— Won (или кастомный этап «Подписание») -> создать Signature Request из шаблона с данными контакта
— Изменение имени или email контакта -> обновить данные подписанта
Yousign -> Kommo:
— request.activated -> Note: «Документ отправлен на подпись»
— request.completed -> Note: «Документ подписан всеми сторонами» + смена этапа на Won
— request.expired -> Note + Task: «Запрос на подпись истёк — повторно отправить»
— request.declined -> Note: «Подписант отклонил документ»
Yousign API v3: создание Signature Request
Base URL: https://api.yousign.app/v3. Аутентификация: Authorization: Bearer {api_key} (из Yousign -> Settings -> API -> Create API Key).
import requests
YS_API_KEY = "your_yousign_api_key"
YS_BASE = "https://api.yousign.app/v3"
YS_HEADERS = {
"Authorization": f"Bearer {YS_API_KEY}",
"Content-Type": "application/json",
}
def upload_document(file_path: str, file_name: str) -> str:
# Загрузить PDF-документ и получить document_id
with open(file_path, "rb") as f:
resp = requests.post(
f"{YS_BASE}/documents",
headers={"Authorization": f"Bearer {YS_API_KEY}"},
files={"file": (file_name, f, "application/pdf")},
data={"nature": "signable_document"},
)
resp.raise_for_status()
return resp.json().get("id")
def create_signature_request(document_id: str, signer_name: str,
signer_email: str, signer_phone: str = "") -> dict:
payload = {
"name": f"Contract - {signer_name}",
"delivery_mode": "email",
"signers": [
{
"info": {
"first_name": signer_name.split()[0] if signer_name else "",
"last_name": " ".join(signer_name.split()[1:]) if len(signer_name.split()) > 1 else "",
"email": signer_email,
"phone_number": signer_phone or None,
"locale": "fr",
},
"signature_level": "electronic_signature",
"signature_authentication_mode": "no_otp",
}
],
"documents": [{"document_id": document_id}],
"timezone": "Europe/Paris",
"expiration_date": None,
}
resp = requests.post(
f"{YS_BASE}/signature_requests",
headers=YS_HEADERS,
json=payload,
)
resp.raise_for_status()
return resp.json()
def activate_signature_request(request_id: str) -> dict:
# Отправить запрос на подпись подписантам
resp = requests.post(
f"{YS_BASE}/signature_requests/{request_id}/activate",
headers=YS_HEADERS,
)
resp.raise_for_status()
return resp.json()
def on_kommo_deal_won(lead: dict, contact: dict):
signer_name = contact.get("name", "")
signer_email = get_contact_email(contact)
signer_phone = get_contact_phone(contact)
# PDF шаблон контракта с предзаполненными данными
pdf_path = generate_contract_pdf(lead, contact)
doc_id = upload_document(pdf_path, f"contract_{lead['id']}.pdf")
sig_req = create_signature_request(doc_id, signer_name, signer_email, signer_phone)
req_id = sig_req.get("id")
activated = activate_signature_request(req_id)
save_to_kommo_deal(lead["id"], {"yousign_request_id": req_id})
create_kommo_note(
lead["id"],
f"Yousign: запрос на подпись отправлен - {signer_email} (request ID: {req_id})",
)
Webhook: Yousign -> Kommo
Yousign Subscriptions (webhooks) настраиваются через API: POST /event_subscriptions.
def create_yousign_webhook(callback_url: str) -> dict:
payload = {
"url": callback_url,
"subscribed_events": [
"signature_request.activated",
"signature_request.completed",
"signature_request.expired",
"signer.declined",
],
}
resp = requests.post(
f"{YS_BASE}/event_subscriptions",
headers=YS_HEADERS,
json=payload,
)
resp.raise_for_status()
return resp.json()
@app.route("/webhooks/yousign", methods=["POST"])
def yousign_webhook():
payload = request.json
event_name = payload.get("event_name", "")
request_id = payload.get("data", {}).get("signature_request", {}).get("id", "")
lead_id = find_kommo_deal_by_custom_field("yousign_request_id", request_id)
if not lead_id:
return "", 200
if event_name == "signature_request.activated":
create_kommo_note(lead_id, "Yousign: документ отправлен на подпись")
elif event_name == "signature_request.completed":
create_kommo_note(lead_id, "Yousign: документ подписан всеми сторонами")
move_kommo_deal_to_stage(lead_id, SIGNED_STAGE_ID)
download_and_attach_signed_doc(lead_id, request_id)
elif event_name == "signature_request.expired":
create_kommo_note(lead_id, "Yousign: срок подписи истёк")
create_kommo_task(lead_id, "Yousign: повторно отправить документ на подпись")
elif event_name == "signer.declined":
signer_email = payload.get("data", {}).get("signer", {}).get("info", {}).get("email", "")
create_kommo_note(lead_id,
f"Yousign: подписант {signer_email} отклонил документ")
return "", 200
def download_and_attach_signed_doc(lead_id: int, request_id: str):
# Скачать подписанный PDF и сохранить URL в Kommo
resp = requests.get(
f"{YS_BASE}/signature_requests/{request_id}/documents/download",
headers=YS_HEADERS,
)
if resp.ok:
# Сохранить в S3 / Google Cloud Storage, получить URL
doc_url = save_signed_pdf_to_storage(resp.content, f"signed_{request_id}.pdf")
create_kommo_note(lead_id, f"Yousign: подписанный документ -> {doc_url}")
Квалифицированная подпись (QES): когда нужна
Yousign поддерживает три уровня подписи согласно eIDAS:
— SES (Simple Electronic Signature) — email-ссылка, достаточно для большинства B2B контрактов
— AES (Advanced Electronic Signature) — OTP через SMS + identity verification
— QES (Qualified Electronic Signature) — максимальный юридический вес, видеоидентификация или eID
Для Kommo-интеграции в signature_level поле: "electronic_signature" (SES), "advanced_electronic_signature" (AES), "qualified_electronic_signature" (QES). Выбор зависит от юрисдикции и типа документа.
Реальный кейс
Юридическая фирма (Франция, 30 человек, Kommo + Yousign):
- До: Won -> секретарь вручную открывала Yousign, загружала PDF, вводила email клиента, отправляла. 10–15 минут. Статус подписания — только в Yousign, в Kommo ничего.
- После: Won -> автоматическое создание Signature Request ->
request.completed-> Note + смена этапа. Параллельно: подписанный PDF сохраняется в облаке, ссылка — в Kommo Note. - Дополнительно: нотариальные соглашения требовали AES (OTP по SMS) — параметр
signature_authentication_mode: "otp_sms"добавлен для этого типа документов.
Для кого актуально
- EU-компании где DocuSign не удовлетворяет требованиям к юрисдикции или хранению данных
- Юридические, финансовые, нотариальные фирмы где нужна QES или AES
- Компании с клиентами во Франции, Германии, Нидерландах — Yousign нативно поддерживает местное законодательство
- Стартапы в EU где данные не должны выходить за пределы EU (GDPR + data residency)
Часто задаваемые вопросы
Yousign поддерживает шаблоны (templates) для автозаполнения?
Да. Yousign -> Templates позволяет создать документ с placeholders ({{first_name}}, {{company}}). При создании Signature Request через API можно использовать template_id вместо загрузки PDF: POST /signature_requests с "template_id": "tmpl_xxx" и "variables": {"first_name": "...", "company": "..."}. Шаблоны создаются один раз в Yousign UI, далее заполняются через API.
Как проверить подлинность Yousign webhook?
Yousign подписывает webhook через HMAC-SHA256: заголовок X-Yousign-Signature-256. Verification ключ (webhook_secret) задаётся при создании Event Subscription. Проверка: hmac.new(secret.encode(), request.data, sha256).hexdigest() должен совпасть с заголовком.
Yousign API v2 vs v3 — есть ли устаревший код?
Yousign v2 (api.yousign.com/v2) — legacy, deprecated в 2024. Yousign v3 (api.yousign.app/v3) — текущий, другой домен и другая структура объектов. Если видите примеры с /v2 — они устарели. Новые интеграции только на v3.
Как подписать документ со стороны вашей компании (двусторонняя подпись)?
В signers массив добавить второго подписанта — сотрудника вашей компании с его email. Yousign отправит запрос обоим. Порядок подписания управляется полем signing_order: "sequential" (клиент подписывает -> затем ваш сотрудник) или "parallel" (одновременно).
Итого
- API: Bearer token, base URL
https://api.yousign.app/v3(v3, не v2) - Поток: загрузить PDF -> создать Signature Request -> activate -> webhook -> Note в Kommo
- Уровни подписи: SES (default), AES (OTP SMS), QES (максимальный вес)
- Webhook верификация:
X-Yousign-Signature-256HMAC-SHA256 request.completed-> скачать подписанный PDF -> сохранить URL в Kommo Note
Если у вас EU-команда с требованиями к eIDAS-совместимой подписи и вы хотите автоматизировать подписание из Kommo — опишите тип документов и нужный уровень подписи. Exceltic.dev настроит интеграцию за 2–3 рабочих дня.