Smerch — API интеграции для мерчантов
    • Быстрый старт
    • Авторизация и HMAC
    • Платежи
    • Балансы
    • Выводы (выплаты)
    • Возвраты
    • Вебхуки (исходящие колбэки)
    • Песочница, ошибки и go-live
    • Авторизация
      • Проверить, что API отвечает
        GET
    • Платежи
      • Список платежей
        GET
      • Создать платёж
        POST
      • Найти платёж по вашему external_id
        GET
      • Получить платёж по UUID
        GET
    • Рекуррентные платежи
      • Получить список рекуррентных мандатов
        GET
      • Создать рекуррентный СБП-мандат
        POST
      • Получить мандат по external_id
        GET
      • Получить мандат по UUID
        GET
      • Отменить рекуррентный мандат
        POST
    • Балансы
      • Посмотреть балансы
        GET
    • Выводы
      • Создать вывод средств
        POST
      • Посчитать вывод без списания
        GET
      • Получить вывод по UUID
        GET
    • Возвраты
      • Сделать возврат по платежу
        POST
    • Вебхуки
      • Посмотреть настройки webhook
      • Задать URL для колбэков
      • Журнал доставок webhook
      • Сменить secret подписи webhook
      • Отправить тестовый колбэк
      • Событие: изменился статус платежа
      • Событие: изменился статус вывода
      • Событие: изменился статус рекуррентного мандата
      • Событие: изменился статус возврата
    • Песочница
      • Песочница: создать тестовый платёж
      • Песочница: симулировать отказ оплаты
      • Песочница: список тестовых платежей
      • Песочница: отказ, затем запоздавшая оплата
      • Песочница: поиск платежа по external_id
      • Песочница: симулировать успешную оплату
      • Песочница: симулировать истечение платежа
      • Песочница: получить тестовый платёж
    • API v2
      • Авторизация
        • Проверить, что API v2 отвечает
      • Возвраты
        • Сделать возврат по платежу (API v2)
      • Рекуррентные платежи
        • Получить список рекуррентных мандатов
        • Создать рекуррентный СБП-мандат
        • Получить мандат по external_id
        • Получить мандат по UUID
        • Отменить рекуррентный мандат
      • Платежи
        • Список платежей (API v2)
        • Создать платёж (API v2)
    • Schemas
      • CreatePayoutRequest
      • CreatePaymentSubscriptionRequest
      • CreateRefundRequest
      • CreateTransactionRequest
      • CursorMeta
      • CursorPage
      • ErrorResponse
      • HealthResponse
      • ProblemDetails
      • V2CreateTransactionRequest
      • IntegrationBalancesResponse
      • V2HealthResponse
      • MerchantBalance
      • RefundResponse
      • V2RefundResponse
      • TransactionResponse
      • MerchantPaymentSubscriptionCallback
      • V2TransactionResponse
      • MerchantPayoutCallback
      • MerchantRefundCallback
      • MerchantTransactionCallback
      • RatesResponse
      • PaymentSubscriptionPage
      • PaymentSubscriptionResponse
      • PayoutQuoteResponse
      • StructuredError
      • PayoutResponse
      • TransactionCursorPage
      • ValidationErrorResponse
      • SandboxTransactionResponse

    Вебхуки (исходящие колбэки)

    Smerch сам вызывает ваш HTTPS URL, когда меняется статус платежа, выплаты или возврата.
    Это не метод, который вы вызываете: в OpenAPI события лежат в блоке webhooks.

    События#

    OpenAPI webhookПоле event в JSONКогда
    merchant.transaction.statustransaction.status_updatedизменился статус платежа
    merchant.subscription.statussubscription.status_updatedизменился статус рекуррентного мандата
    merchant.payout.statuspayout.status_updatedизменился статус выплаты
    merchant.refund.statusrefund.status_updatedизменился статус возврата

    Настройка#

    МетодЗачем
    GET /integration/webhookтекущий URL / настройки
    PUT /integration/webhookзадать/обновить URL или отключить доставку
    POST /integration/webhook/testтестовая доставка
    GET /integration/webhook/deliveriesжурнал доставок
    POST /integration/webhook/rotate-secretсменить secret подписи
    URL должен быть публичным HTTPS-адресом; redirect не выполняются. После ротации в течение overlap-окна запрос может содержать подписи текущим и предыдущим ключом.

    Проверка подписи webhook#

    Исходящий запрос подписан отдельным webhook secret (не API-ключом).
    Заголовки (типично):
    X-Webhook-Id
    X-Webhook-Timestamp
    X-Webhook-Signature
    X-Webhook-Version
    X-Webhook-Key-Id
    Во время ротации дополнительно могут прийти X-Webhook-Previous-Key-Id и X-Webhook-Previous-Signature. Выберите secret по key id; не перебирайте все сохранённые секреты без ограничения окна.
    Canonical string:
    {version}
    {webhookId}
    {timestamp}
    {sha256(rawBody)}
    signature = HMAC_SHA256(webhookSecret, canonical) → lowercase hex
    Сравнивайте подпись через constant-time compare (hash_equals). Подписывается исходный набор байтов: проверяйте HMAC до JSON-декодирования или переформатирования body.
    X-Webhook-Id стабилен для всех повторных попыток одного события и является ключом дедупликации. Он передаётся в заголовке, а не в JSON-теле.

    Статусы доставки#

    GET /integration/webhook/deliveries возвращает состояние доставки, а не бизнес-статус платежа:
    СтатусСмысл
    pendingДоставка ожидает следующей попытки.
    processingПопытка выполняется.
    success / deliveredEndpoint ответил 2xx; различие историческое, оба значения успешны.
    failedНеретрайбл-ошибка, например большинство 4xx.
    dead_letteredПовторяемая ошибка не исчезла после всех попыток.

    Ваши обязанности#

    1.
    Отвечать быстро кодом 2xx.
    2.
    Обрабатывать повторные доставки идемпотентно по X-Webhook-Id.
    3.
    Не доверять телу без проверки подписи.
    4.
    Сохранять событие и отвечать 2xx до тяжёлой бизнес-обработки.
    5.
    При конфликтующем или запоздавшем событии читать актуальную транзакцию/выплату через GET; для возврата сверяться с журналом доставок или кабинетом.
    Сетевые ошибки, 408, 425, 429 и настроенные 5xx повторяются: по умолчанию всего 10 попыток, первая — сразу. Интервалы после предыдущей неудачной попытки: 1, 5, 10, 15, 30, 60 минут, затем 3, 8 и 12 часов. Заголовок Retry-After имеет приоритет над этими интервалами. После десятой неудачной попытки доставка переходит в dead_lettered. Остальные 4xx и redirect считаются окончательной ошибкой доставки.
    Для рекуррентных платежей subscription.status_updated сообщает только о состоянии мандата. Денежное списание приходит отдельно как transaction.status_updated, а транзакция содержит subscription_uuid. Дедуплицируйте оба потока по X-Webhook-Id.
    Modified at 2026-10-20 12:21:39
    Previous
    Возвраты
    Next
    Песочница, ошибки и go-live
    Built with