Kommo + Checkout.com: платёжный gateway из воронки
При переходе сделки в статус «Выиграно» Kommo автоматически создаёт платёжную ссылку через Checkout.com API и сохраняет её в карточку. Менеджер отправляет ссылку клиенту одним кликом, а статус оплаты возвращается обратно в CRM через webhook - без ручных действий.
В проектах с EU e-commerce и fintech-компаниями на Kommo мы видим один и тот же паттерн: при выигрыше сделки менеджер вручную открывает Checkout.com dashboard, создаёт payment link, копирует его в карточку CRM, а потом ещё вручную отслеживает, прошла ли оплата. При объёме 50-80 сделок в месяц это 2-3 часа рутинной работы еженедельно, плюс постоянный риск ошибки - неверная сумма, не тот контакт, потерянная ссылка. Checkout.com занимает сильные позиции на EU-рынке именно потому, что поддерживает Strong Customer Authentication (SCA) по требованию PSD2 и имеет локальные acquiring-отношения в ключевых странах. Это делает его первым выбором для fintech и e-commerce компаний, которые работают с европейскими покупателями. В этой статье - архитектура интеграции, рабочий Python-код и реальный кейс с цифрами.
Почему нативной интеграции Checkout.com с Kommo нет
Kommo предлагает нативные подключения к Stripe и PayPal через маркетплейс виджетов, но Checkout.com там отсутствует. Причина не в технической сложности, а в рыночной логике: Checkout.com ориентирован на enterprise и mid-market клиентов с кастомными процессами, а не на low-code Zapier-интеграции.
Если пытаться решить задачу через Zapier или Make, вы сразу упираетесь в ограничения: нет готового Checkout.com-модуля с поддержкой Payment Links API v2, нет обработки HMAC-подписи webhook-событий, нет логики идемпотентности при повторных попытках. Всё это нужно строить вручную, и тогда проще сразу написать нормальный Python-сервис.
Payment Links API - это endpoint Checkout.com для генерации платёжных страниц без необходимости встраивать форму на сайт. Ссылка открывается на хостинге Checkout.com, поддерживает 3D Secure и возвращает webhook-события о результате оплаты.
Архитектура интеграции
Интеграция работает в двух направлениях:
-
Kommo -> Checkout.com: при переходе сделки в статус «Выиграно» Kommo отправляет webhook на ваш сервис. Сервис получает данные сделки, создаёт Payment Link через Checkout.com API и записывает URL обратно в кастомное поле карточки.
-
Checkout.com -> Kommo: когда покупатель оплачивает (или отказывается), Checkout.com отправляет webhook-событие на ваш сервис. Сервис обновляет статус сделки и добавляет заметку с деталями транзакции.
Технический стек:
- Python 3.11 + FastAPI для webhook-обработчика
- Checkout.com Secret Key для Bearer-авторизации
- HMAC-SHA256 для верификации подписи входящих webhooks
- Kommo API для обновления полей сделки
Поле reference в Payment Links API используется для хранения Kommo Deal ID - это связующее звено между платежом и сделкой в CRM.
import hmac
import hashlib
import httpx
from fastapi import FastAPI, Request, HTTPException
from pydantic import BaseModel
app = FastAPI()
CKO_SECRET_KEY = "sk_sbox_xxx" # Checkout.com Secret Key
CKO_WEBHOOK_SECRET = "your_webhook_secret" # из Checkout.com dashboard
KOMMO_SUBDOMAIN = "your_company"
KOMMO_TOKEN = "your_kommo_long_lived_token"
def verify_cko_signature(payload: bytes, signature_header: str) -> bool:
"""Верификация HMAC-SHA256 подписи от Checkout.com."""
expected = hmac.new(
CKO_WEBHOOK_SECRET.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature_header)
async def create_payment_link(deal_id: int, amount: int, currency: str, contact_email: str) -> str:
"""Создаёт Payment Link в Checkout.com и возвращает URL."""
async with httpx.AsyncClient() as client:
response = await client.post(
"https://api.checkout.com/payment-links",
headers={
"Authorization": f"Bearer {CKO_SECRET_KEY}",
"Content-Type": "application/json"
},
json={
"amount": amount, # в минимальных единицах (cents)
"currency": currency, # "EUR", "GBP", "USD"
"reference": str(deal_id), # Kommo Deal ID как reference
"description": f"Invoice #{deal_id}",
"customer": {"email": contact_email},
"3ds": {"enabled": True}, # SCA для EU
"expires_in": 86400 # 24 часа
},
timeout=10.0
)
response.raise_for_status()
return response.json()["_links"]["redirect"]["href"]
async def update_kommo_deal(deal_id: int, payment_url: str, field_id: int):
"""Записывает Payment Link URL в кастомное поле сделки Kommo."""
async with httpx.AsyncClient() as client:
await client.patch(
f"https://{KOMMO_SUBDOMAIN}.kommo.com/api/v4/leads/{deal_id}",
headers={"Authorization": f"Bearer {KOMMO_TOKEN}"},
json={"custom_fields_values": [{"field_id": field_id, "values": [{"value": payment_url}]}]},
timeout=10.0
)
@app.post("/kommo/webhook")
async def handle_kommo_webhook(request: Request):
"""Обрабатывает webhook от Kommo при смене статуса сделки."""
data = await request.json()
# Проверяем что это событие выигрыша сделки
leads = data.get("leads", {}).get("status", [])
for lead in leads:
if lead.get("status_id") == 142: # ID статуса Won в вашей воронке
deal_id = lead["id"]
# Здесь получаем amount и email из полей сделки
# (упрощено для примера)
payment_url = await create_payment_link(
deal_id=deal_id,
amount=lead.get("price", 0) * 100, # конвертируем в cents
currency="EUR",
contact_email=lead.get("contact_email", "")
)
await update_kommo_deal(deal_id, payment_url, field_id=12345)
return {"status": "ok"}
@app.post("/checkout/webhook")
async def handle_checkout_webhook(request: Request):
"""Обрабатывает входящие webhook-события от Checkout.com."""
body = await request.body()
signature = request.headers.get("cko-signature", "")
if not verify_cko_signature(body, signature):
raise HTTPException(status_code=401, detail="Invalid signature")
event = await request.json()
event_type = event.get("type")
deal_id = int(event["data"]["reference"]) # наш Kommo Deal ID
if event_type == "payment_captured":
# Оплата прошла - перемещаем сделку или добавляем заметку
await update_kommo_deal_note(deal_id, f"Оплата получена: {event['data']['amount']} {event['data']['currency']}")
elif event_type == "payment_declined":
await update_kommo_deal_note(deal_id, f"Оплата отклонена: {event['data']['response_summary']}")
return {"status": "ok"}
Пошаговая реализация
Шаг 1. Настройка Checkout.com
В Checkout.com Dashboard перейдите в Settings -> Channels. Скопируйте Secret Key (начинается с sk_). В разделе Webhooks создайте endpoint, укажите URL вашего сервиса и включите события: payment_captured, payment_declined, payment_approved. Сохраните Webhook Secret для HMAC-верификации.
Шаг 2. Кастомное поле в Kommo
В Kommo создайте кастомное поле типа «Текст» с названием «Payment Link» (запомните его field_id из API). Это поле будет хранить ссылку для отправки клиенту.
Шаг 3. Webhook из Kommo
В настройках Kommo (Настройки -> Уведомления) добавьте webhook на URL /kommo/webhook вашего сервиса. Настройте триггер на событие «Сделка: изменение этапа» для этапа «Выиграно».
Шаг 4. Маппинг полей сделки
Из webhook Kommo извлекайте price сделки (сумма контракта) и email контакта через API-запрос к /api/v4/leads/{id}?with=contacts. Валюту берите из кастомного поля или задайте по умолчанию.
Шаг 5. 3D Secure и SCA
Для EU-транзакций свыше 30 EUR включайте "3ds": {"enabled": true} в теле запроса к Payment Links API. Checkout.com автоматически применяет Strong Customer Authentication там, где это требует PSD2.
Шаг 6. Exponential backoff
Checkout.com API возвращает 429 при превышении rate limits. Реализуйте retry с задержками 1s, 2s, 4s, 8s (максимум 4 попытки) перед тем как зафиксировать ошибку и уведомить команду.
Реальный кейс: EU e-commerce, 65 сделок в месяц
Клиент - EU e-commerce компания, продаёт B2B через Kommo. До интеграции: менеджер вручную создавал payment link в Checkout.com после каждого звонка с подтверждением, копировал URL в карточку, писал письмо клиенту. Среднее время на операцию - 8-12 минут.
После интеграции: Payment Link создаётся автоматически при переходе в «Выиграно», URL появляется в карточке через 2-3 секунды. Менеджер видит ссылку, копирует в WhatsApp или email одним кликом. Статус оплаты (captured/declined) приходит в CRM автоматически.
Результат за первый месяц:
- Экономия времени: ~7 часов в месяц (65 сделок x 6 минут)
- Ошибки маппинга суммы: снизились с 4-5 в месяц до нуля
- Конверсия из «Выиграно» в «Оплачено» выросла на 11% - за счёт скорости: ссылка уходит клиенту пока он ещё на звонке, а не через 30 минут
Дополнительный эффект: руководитель получил возможность отслеживать pipeline оплат прямо в Kommo без выгрузки из Checkout.com dashboard.
Для кого подходит эта интеграция
Эта схема оптимальна для компаний с несколькими характеристиками:
- Используют Kommo как основной инструмент продаж
- Принимают платежи от EU-покупателей (важна поддержка SCA)
- Объём закрытых сделок от 30 в месяц - при меньшем объёме ручная работа не критична
- Средний чек выше $500 - при небольших суммах административная нагрузка ощутимее
- Нет выделенного billing-отдела, который берёт создание инвойсов на себя
Если вы уже используете Checkout.com и строите кастомные интеграции для Kommo, эта схема встраивается в существующий стек без замены инструментов.
Часто задаваемые вопросы
Можно ли использовать эту интеграцию, если мы принимаем оплату в нескольких валютах?
Да. Payment Links API принимает параметр currency при каждом создании ссылки. В Kommo создайте кастомное поле «Валюта сделки» и передавайте его значение в API-запрос. Checkout.com поддерживает более 150 валют. Курс конвертации на стороне Checkout.com при multicurrency acquiring, если вы используете эту функцию.
Что происходит, если webhook от Checkout.com приходит с задержкой или теряется?
Checkout.com повторяет доставку webhook до 10 раз с экспоненциальной задержкой в течение 24 часов. Дополнительно можно настроить polling через Events API - раз в 15-30 минут запрашивать события по reference (Deal ID) и сверять статусы. Для критичных транзакций рекомендуем комбинировать оба подхода.
Как верифицировать подпись webhook, если мы используем не Python?
Алгоритм одинаков для любого языка: берёте raw body запроса в байтах, считаете HMAC-SHA256 с вашим Webhook Secret, сравниваете с заголовком cko-signature. В Node.js это crypto.createHmac('sha256', secret).update(rawBody).digest('hex'). Важно: работать именно с raw body, а не с распарсенным JSON - иначе порядок полей может измениться.
Checkout.com поддерживает Apple Pay и Google Pay через payment links?
По состоянию на середину 2026 года - да, если у вас настроен Apple Pay / Google Pay в вашем Checkout.com аккаунте. Покупатель, открывший Payment Link на мобильном, увидит доступные кошельки автоматически. Для этого не требуется дополнительная настройка на уровне API.
Нужен ли выделенный сервер для webhook-обработчика?
Нет. Достаточно VPS за $5-10/мес или бессерверной функции (AWS Lambda, Google Cloud Functions). Нагрузка минимальная: даже при 200 сделках в месяц это менее 20 запросов в день. FastAPI-сервис потребляет меньше 128MB RAM.
Если у вас 30+ закрытых сделок в месяц через Checkout.com и команда тратит время на ручное создание payment links - опишите задачу команде Exceltic.dev. Разберём архитектуру под ваш стек и оценим объём работ.