ru

Вебхуки криптоплатежей: как безопасно обрабатывать подтверждения

Опубликовано
01.08.2026
Обновлено
17.10.2026
Лавандово-персиковая 3D-сцена: защищённое событие платежа проходит от блоков блокчейна к подтверждённой системе заказов.
Лавандово-персиковая 3D-сцена: защищённое событие платежа проходит от блоков блокчейна к подтверждённой системе заказов.
Contents

    Платёж может уже появиться в кошельке клиента, а заказ всё ещё нельзя безоговорочно считать оплаченным. Сайт мог показать успешный экран, платёжный сервис мог найти транзакцию, а внутренней системе всё равно нужно понять: уведомление настоящее ли, не приходило ли оно раньше и достаточно ли оснований, чтобы выдать доступ, товар или баланс.

    Эту связку обычно решает вебхук. Вебхук — это HTTP-уведомление: когда у платёжного сервиса происходит событие, он отправляет запрос на указанный адрес вашего приложения. Для криптоплатежей он помогает не опрашивать API каждую минуту, но сам по себе не должен становиться командой «сразу выдать заказ».

    Рабочая цель проще, чем кажется: быстро принять доставку, проверить её, сохранить след и изменить бизнес-статус ровно один раз.

    У уведомления и у расчёта разные роли

    В API-сценарии приложение создаёт счёт или платёжное намерение, показывает клиенту реквизиты и ожидает изменение статуса. Затем платёжный провайдер может прислать вебхук. Так заказ быстрее выходит из состояния ожидания, а серверу не приходится постоянно запрашивать обновления.

    Но название события не заменяет бизнес-логику. У одного провайдера уведомление приходит, когда перевод замечен в сети, у другого — после собственного набора проверок, у третьего — после смены статуса счёта. Единый формат, единая подпись и единое число повторных доставок для всех сервисов не существуют.

    Полезно заранее разделить четыре вещи:

    • вебхук сообщает, что провайдер доставил уведомление о событии;
    • карточка платежа связывает это событие со счётом, суммой, активом, сетью и текущим статусом;
    • запись в блокчейне показывает сам перевод и его подтверждения, если эта проверка нужна сценарию;
    • заказ в вашем продукте хранит уже принятое решение: ждать, проверить вручную, выдать доступ, завершить исполнение или оформить возврат.

    Такое разделение особенно помогает поддержке. Проверка криптоплатежа по TXID объясняет, что произошло в сети, но она не должна автоматически подменять решение о выдаче заказа.

    Сначала опишите состояния заказа

    Не стоит копировать в базу все статусы провайдера как есть. Лучше описать собственный небольшой жизненный цикл. Например, заказ сначала ждёт оплаты; после обнаружения перевода переходит в проверку; после выполнения вашего правила становится готов к выдаче; при нестандартной ситуации попадает в отдельную очередь.

    Правило выдачи зависит от риска. Цифровой доступ на небольшую сумму и дорогостоящая услуга могут требовать разной осторожности. У сетей различаются механика подтверждений и финальности, а у провайдера могут быть дополнительные проверки. Поэтому универсального числа подтверждений, подходящего любой операции, нет.

    Для начала достаточно зафиксировать несколько состояний:

    • счёт создан;
    • платёж обнаружен;
    • платёж соответствует текущему правилу подтверждения;
    • заказ исполнен или баланс зачислен;
    • ситуация требует разбора: не та сумма, сеть, просроченный счёт или ручная проверка.

    Ценность этого подхода в том, что только один управляемый переход даёт клиенту доступ к ценному результату. Ни уведомление, ни видимый перевод не должны перескочить через него сами по себе.

    Проверяйте подпись до бизнес-обработки

    Открытый URL, который принимает любой JSON, не является защищённой платёжной интеграцией. Если провайдер подписывает вебхуки, проверяйте подпись ровно так, как описано в его актуальной документации. В правилах могут участвовать исходное, не изменённое тело запроса, заголовок подписи, метка времени и секрет вебхука. Нельзя подменять исходное тело распарсенным JSON или переносить алгоритм из документации другого сервиса.

    Проверка подписи отвечает на конкретный вопрос: запрос пришёл от настроенного провайдера и не был изменён по дороге? Она не доказывает, что заказ уже можно выдавать. Корректное уведомление может оказаться дублем, старым статусом, событием из тестовой среды или уведомлением, которое ваша система ещё не готова обработать.

    У обработчика должны быть базовые защитные свойства:

    • секреты не лежат в коде и меняются по процедуре провайдера;
    • запрос идёт по HTTPS, а неверная подпись и повреждённый формат отклоняются до основной логики;
    • проверяются тип события, среда, время и идентификатор доставки, если провайдер их документирует;
    • подключены только те виды событий, которые действительно нужны продукту;
    • результат проверки и метаданные доставки остаются в журнале для разбора инцидента.

    Одной только проверки IP-адреса недостаточно считать источник доказанным. У сервисов различаются методы аутентификации и правила инфраструктуры; ориентироваться нужно на действующую документацию конкретного провайдера.

    Быстро отвечайте, но не делайте всю работу в запросе

    Если обработчик долго молчит или возвращает неуспешный HTTP-ответ, платёжный сервис обычно считает доставку неудачной и пытается отправить её снова. Поэтому разумный путь такой: проверить подпись, сохранить идентификатор и минимальные данные, поставить задачу в очередь и быстро вернуть успешный ответ. Сверка, отправка писем, выдача лицензии, изменение нескольких записей и вызовы внутренних сервисов выполняются отдельно, в управляемом процессе.

    Это не означает «подтвердить всё без проверки». Быстрый ответ отделяет надёжность доставки от бизнес-обработки. Неверную подпись нужно отклонить. Если подпись верна, но задача дальше не выполнилась, событие должно остаться в наблюдаемом статусе, а не исчезнуть между повторными запросами.

    До старта API-интеграции стоит пройти чеклист по выбору криптовалютного платёжного API. В нём важны не только создание счёта и ключи доступа, но и статусы, журналы, обязанности команды и обработка сбоев.

    Идемпотентность защищает от двойной выдачи

    Повторная доставка — нормальная часть распределённой системы. Провайдер мог не увидеть ответ из-за таймаута, очередь могла повторить задачу, а инженер — заново отправить событие при расследовании. Если каждый такой случай создаёт новый доступ, баланс, отгрузку или выплату, проблема уже в логике приложения, а не в блокчейне.

    Идемпотентный обработчик при повторе одного и того же события оставляет тот же бизнес-результат, что и при первом выполнении. Если провайдер присылает устойчивый идентификатор события, сохраните его вместе с ID платежа и заказа. Внутри транзакции базы данных или другой атомарной операции отметьте событие обработанным, а выдачу результата сделайте условной: она возможна, только если заказ ещё не дошёл до финального состояния.

    Не ищите дубли только по сумме или адресу. Два разных клиента могут заплатить одинаковую сумму, а один клиент — оплатить несколько счетов. Надёжнее опираться на документированный ID события или платежа в связке с собственным ID счёта, заказа и окружения.

    Такой учёт делает полезнее и метрики криптоплатежей. В отчётности должны отдельно видеть уникальные оплаты, попытки доставки, неверные подписи, дубли, ручные повторы и действительно исполненные заказы. Иначе серия ретраев легко выглядит как рост оборота или конверсии.

    Не рассчитывайте на идеальный порядок событий

    Поток вебхуков не похож на аккуратно отсортированный журнал. Поздний статус может прийти раньше раннего, а повторная доставка — после того, как заказ уже обработан. Воспринимайте уведомление как повод загрузить актуальный контекст платежа, а не как приказ безусловно переписать локальный статус.

    Сравните событие с тем, что уже знает ваша система. Устаревший статус можно сохранить для истории, но не следует откатывать им заказ назад. Если не хватает нужного шага, запросите актуальные данные через документированный API провайдера или оставьте заказ в ожидании проверки. При противоречии лучше сохранить доказательства и передать кейс в разбор, чем угадывать правильную версию.

    Сценарии с ошибками стоит делать отдельной веткой. Клиент может отправить не ту сумму, выбрать неподдерживаемую сеть, оплатить после истечения счёта или перечислить часть суммы. Хороший процесс не превращает это уведомление в угадайку, а открывает контролируемый статус. Многие такие ситуации проще предотвратить ещё в интерфейсе оплаты: для этого полезны правила из материала о том, как сократить число неуспешных криптоплатежей.

    Сопоставляйте событие со счётом и заказом

    Перед выдачей доступа или зачислением баланса система должна убедиться, что уведомление относится к ожидаемому платежу. Точный набор полей зависит от провайдера, но в решении обычно сопоставляют ID платежа, свой ID счёта или заказа, ожидаемые актив и сеть, сумму, текущий статус и уже выполненные действия.

    В одном сценарии основным операционным основанием будет статус провайдера. В другом — для более рискованного действия потребуется ещё запрос актуальной карточки платежа или проверка в сети. Цель не в том, чтобы намеренно замедлить каждый платёж. Цель — заранее определить, какое доказательство открывает выдачу ценности в конкретном случае.

    Если сумма или сеть не совпали, не пытайтесь «подогнать» заказ на глаз. Сохраните исходные реквизиты и идентификаторы, покажите их поддержке и примените согласованный процесс решения проблемы. Тогда возвраты криптоплатежей не превращаются в спешный перевод на случайный адрес.

    Проверьте сбои до запуска

    Успешная демо-оплата проверяет только самый лёгкий путь. До запуска стоит воспроизвести те случаи, которые проявятся в реальной эксплуатации: дубли, задержки, неверная подпись, повтор после завершения заказа и временно недоступные внутренние сервисы.

    Минимальный тестовый набор включает:

    • корректное новое событие для подходящего платежа;
    • несколько повторов одной доставки;
    • старый статус, пришедший после нового;
    • неверную подпись или неожиданный тип события;
    • таймаут после сохранения события, но до завершения фоновой задачи;
    • неверную сумму или сеть, которые должны уйти в проверку, а не в выдачу.

    Проверьте не только базу данных, но и опыт клиента с поддержкой: что увидит покупатель, какие идентификаторы найдёт оператор, и изменит ли повтор запуска конечный статус заказа. Если индивидуальная серверная интеграция пока избыточна, HTML-виджет для криптоплатежей уменьшает объём собственной разработки. Но правила статусов и выдачи всё равно должны быть понятны команде.

    Как учитывать CryptumPay в этом процессе

    У платёжных сервисов вебхуки устроены похоже: сервис присылает уведомление на каждую смену статуса платежа, а ваш обработчик решает, что с этим статусом делать. Различаются детали, и именно их стоит выписать из документации своего провайдера до того, как писать код:

    • Какие события приходят. У одних сервисов это одно уведомление «платёж прошёл», у других — отдельное событие на каждый шаг платежа, а иногда ещё и на создание счёта.
    • Через какие статусы проходит платёж. От выданного адреса до денег на балансе обычно три-четыре шага, и выдавать заказ стоит только на последнем.
    • В каком событии приходит итоговая сумма. Сумма, которую отправил клиент, и сумма, которая дошла после комиссий, — это разные числа, и сверять заказ нужно со вторым.

    Какие вебхуки присылает CryptumPay

    У CryptumPay уведомления об оплате приходят сразу, через callback и вебхуки, и вебхуков два типа:

    • merchantOrder. Сообщает, что создан заказ мерчанта.
    • customerOrder. Приходит на каждую смену статуса клиентского заказа. Обработчик из этой статьи слушает именно его.

    Клиентский заказ у CryptumPay проходит четыре статуса, и на каждый приходит свой вебхук customerOrder:

    • created. Клиент выбрал валюту, сервис выдал адрес и ждёт оплату. Для вашей системы это ещё «счёт создан».
    • pending. Входящая транзакция замечена в сети, сервис ждёт подтверждений. Это «платёж обнаружен»: заказ переходит в проверку, но не в выдачу.
    • crediting. Подтверждений достаточно, средства зачисляются на баланс мерчанта. Выдавать заказ по-прежнему рано.
    • finished. Платёж завершён. Только в этом вебхуке есть поле income — сумма, зачисленная после всех комиссий, — и только на нём заказ стоит переводить в «исполнен, баланс зачислен».

    Отсюда и правила для обработчика, те же, что в разделах выше, только с именами конкретных статусов. Если вебхук finished по тому же заказу придёт ещё раз, второй раз зачислять баланс нельзя. Если pending придёт после finished, откатывать заказ назад тоже нельзя.

    Что происходит при недоплате

    Отдельная ветка — клиент отправил не ту сумму. Обычно это биржа удержала комиссию за вывод, и вместо 100 USDT дошло 99. Сервисы решают это по-разному: одни закрывают такой счёт как неоплаченный, другие держат допуск на небольшую разницу и считают платёж состоявшимся.

    У CryptumPay это решается в окне оплаты. Если разница укладывается в допуск, платёж подтверждается автоматически. Если нет, окно оплаты просит клиента доплатить остаток, и на доплату у него есть до двух попыток. Переплату клиент может запросить к возврату прямо в том же окне. Для обработчика правило остаётся тем же, что в списке выше: заказ переводится в «исполнен» только по вебхуку finished, а не по факту доплаты.

    Частые вопросы

    Можно ли сразу выдать заказ после вебхука?

    Не всегда. Сначала нужно проверить подлинность доставки, сопоставить её со счётом и применить заранее определённое правило статуса или подтверждения.

    Почему один вебхук пришёл несколько раз?

    Обычно это повторная доставка после таймаута или неуспешного ответа, а иногда — ручной повтор во время восстановления. Обработчик должен быть идемпотентным и не выдавать ценность повторно.

    Нужно ли после вебхука всегда ходить в блокчейн?

    Нет. Это зависит от вашего процесса и смысла статуса у провайдера. Статус платежа, данные API и подтверждения в сети решают разные задачи.

    Можно ли для всех криптоплатежей поставить одно число подтверждений?

    Нет. У сетей различаются подтверждения и финальность, а у бизнеса — ценность заказа и приемлемый риск.

    Что делать при неверной сумме или сети?

    Не выдавать другой заказ автоматически. Сохраните идентификаторы, переведите случай в контролируемую проверку и используйте понятный процесс доплаты, возврата или ручного решения.

    Начните приём криптовалют сейчас

    Создайте аккаунт и подключите оплату самостоятельно, или свяжитесь с нами и мы поможем всё настроить