Разделы справки

Разделы справки

Для разработчиков

Внешний API, identity контакта, витрина, покупки и платежи, вебхуки и проверка подписи, повторы.

Этот раздел для того, кто подключает сайт, бот или другую систему к Истоку. Здесь главное, чтобы начать; полный список полей смотрите в ответах API.

Подключение сайта

Интеграция в Истоке создаётся владельцем или администратором проекта в «Настройках» на вкладке «Интеграции». Вам передадут API-ключ вида istk_… и, если вы принимаете события, секрет вебхука whsec_….

Все запросы идут на https://<адрес Истока>/api/v1/… с заголовком:

Authorization: Bearer istk_…

Проект в запросах не указывается: он определяется ключом. Проверить ключ проще всего так:

GET /api/v1/me

В ответе интеграция с её подписками и проект. Выключенная или удалённая интеграция, как и перевыпущенный ключ, получает 401.

Ключ и секрет

Ключ даёт доступ к данным проекта, секрет нужен только для проверки подписи вебхуков. Ключ и секрет меняются независимо: «Перевыпустить» в карточке интеграции сразу отзывает старый ключ, «Перегенерировать» меняет секрет. Храните оба на сервере; в браузерный код они попадать не должны.

Identity контакта

Внешняя система не знает внутренних номеров контактов. Вместо этого контакт определяется значениями полей идентификации, заданных в проекте: обычно это почта или телефон. Ключи полей видны в «Настройках» на вкладке «Поля контактов» в столбце «Ключ».

Создать или обновить контакт:

PUT /api/v1/contacts
{"values": {"pochta": "anna.sokolova@example.com", "imya": "Анна Соколова", "status": "Новый"}}

Если контакт с такой почтой уже есть, значения дописываются к нему, и в ответе created: false. Все поля идентификации в values обязательны, остальные по желанию. Значения должны соответствовать типам полей: число для числового поля, true/false для булева, дата в формате YYYY-MM-DD, значения списков ровно как в настройках.

В остальных запросах контакт передаётся полем identity с теми же ключами:

{"identity": {"pochta": "anna.sokolova@example.com"}}

Каталог и витрина

Запрос Что возвращает
POST /api/v1/products/search Активные продукты с поиском, фильтрами по характеристикам и сортировкой; в каждом количество предложений и минимальная цена
GET /api/v1/products/{id} Продукт с активными предложениями
POST /api/v1/showcase с identity Витрина конкретного контакта: только то, что ему доступно по условиям продукта и предложения

Цены везде в копейках: 24000_00 это 24 000 ₽. Картинки приходят в пяти размерах: thumb, small, medium, large и original, это готовые адреса.

Покупки и платежи

Покупка без оплаты через Исток:

POST /api/v1/purchases
Idempotency-Key: order-1287
{"identity": {"pochta": "…"}, "offer_id": 8, "price": 350000}

Покупка создаётся в статусе «Ожидает оплаты»; price необязателен, по умолчанию берётся цена предложения. Дальше POST /api/v1/purchases/{id}/confirm отмечает её оплаченной, POST /api/v1/purchases/{id}/cancel отменяет. Есть также GET /api/v1/purchases/{id} и POST /api/v1/purchases/search по identity.

Покупка с оплатой через Робокассу:

POST /api/v1/payments
Idempotency-Key: order-1288
{"identity": {"pochta": "…"}, "offer_id": 9, "customer_email": "…"}

В ответе payment_url для покупателя и expires_at: ссылка действует 24 часа. customer_email попадёт в чек. Предложение должно быть доступно этому контакту, иначе 409. Состояние платежа можно проверить через GET /api/v1/payments/{id}, но надёжнее подписаться на события «Оплата прошла» и «Оплата не прошла».

Заголовок Idempotency-Key защищает от дублей при повторе запроса: с тем же ключом вернётся уже созданная покупка или платёж.

Вебхуки и проверка подписи

Событие приходит на Webhook URL интеграции POST-запросом с JSON:

Событие, каким его получает сайт
Событие, каким его получает сайт

Конверт события:

{
  "id": 39,
  "type": "purchase.status_changed",
  "occurred_at": "2026-09-17T16:15:14.945001+00:00",
  "origin": {"kind": "integration", "integration_id": 1},
  "data": {…}
}

origin говорит, кто вызвал событие: сотрудник в админке (user) или интеграция. Так вы отличите свои же действия от чужих. Состав data зависит от типа: у событий контакта это values, у покупки — purchase_id, offer_id, product_id, price, status, old_status, new_status и contact, у платежа — данные платежа вместе с покупкой и контактом.

Подпись в заголовке X-Istok-Signature: t=<unix time>,v1=<hex>. Это HMAC-SHA256 от строки "<t>." + тело запроса с секретом вебхука. Проверка на Python:

import hmac, hashlib

def verify(secret: str, header: str, body: bytes) -> bool:
    parts = dict(p.split("=", 1) for p in header.split(","))
    signed = f"{parts['t']}.".encode() + body
    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts["v1"])

Считайте подпись от байтов тела как они пришли, до разбора JSON. Отвечайте 2xx в течение 10 секунд; редиректы Исток не выполняет и считает ошибкой.

Типы событий:

Группа Код Когда
Контакты contact.created, contact.updated, contact.deleted Контакт создан, изменены поля, удалён
Покупки purchase.created, purchase.status_changed Покупка создана; сменился статус
Оплата payment.succeeded, payment.failed Платёж прошёл; платёж отклонён, просрочен или отменён
Каталог product.created, product.updated, product.deleted, offer.created, offer.updated, offer.deleted Изменения продуктов и предложений

Повторы и лог

Если ваш сервер не ответил 2xx, Исток повторяет доставку: паузы 1, 3, 9, 27 и 81 минута, затем около 4 часов и дважды по 12 часов, всего 8 попыток. После восьмой событие получает статус «Не доставлено» и больше не отправляется. Порядок доставки при повторах не гарантируется: ориентируйтесь на occurred_at.

Пока интеграция выключена, события копятся и уйдут после включения. Записи о доставках хранятся 30 дней и видны в карточке интеграции на вкладке «Лог доставок»: там же код ответа вашего сервера и текст ошибки.