Оповещения виджета

В этом разделе описаны HTTP-оповещения (колбеки), которые HighHelp отправляет при изменении статуса заявок, созданных через платежный виджет (H2C). Обзор работы виджета приведен в разделе Обзор виджета.

Определения статусов и подстатусов приведены в разделе Коды статусов. Механизм аутентификации и подписи запросов и оповещений описан в разделе Аутентификация и подпись.

Назначение оповещений

Оповещения виджета используются для передачи результата обработки заявки с платформы HighHelp на бэкенд мерчанта.

Оповещения нужны для:

  • отслеживания прогресса обработки заявки;

  • фиксации финального результата (успех или отказ);

  • получения дополнительных данных (сумма, валюта, метод, замаскированные реквизиты и др.).

Базовая структура оповещения (поля project_id, general, status) одинакова для H2H и виджета, но состав дополнительных блоков зависит от продукта и сценария интеграции. Полный перечень статусов и подстатусов приведен в разделе Коды статусов.

Типы оповещений

Для заявок, созданных через виджет, используются три типа оповещений:

  • Информативные оповещения — отправляются при изменении промежуточных статусов заявки. URL для информативных оповещений указывается в поле merchant_callback_url при создании заявки.

  • Успешные оповещения — отправляются при переводе заявки в финальный статус success. URL указывается в поле merchant_success_callback_url.

  • Неуспешные оповещения — отправляются при переводе заявки в финальный статус decline. URL указывается в поле merchant_decline_callback_url.

Статусы, подстатусы и их значения описаны в разделе Коды статусов.

Транспорт и формат

HighHelp отправляет оповещения:

  • методом POST;

  • в формате JSON;

  • с кодировкой UTF-8;

  • с заголовком Content-Type: application/json.

Каждое оповещение содержит:

  • данные о кассе и платеже;

  • текущий статус и подстатус;

  • информацию о сумме, валюте и методе;

  • дополнительные блоки, специфичные для продукта, например, информация о карте или клиенте.

Примеры структур JSON приведены ниже.

Информативные оповещения

Для статуса processing информативные оповещения для заявок, созданных через виджет, отправляются только для подстатусов awaiting_confirm и paid (т.е. для статусов processing:awaiting_confirm и processing:paid). Оповещения со статусами error и dispute:* также отправляются на merchant_callback_url.

Пример информативного оповещения для P2P-платежа через виджет:

{
  "project_id": "57aff4db-b45d-42bf-bc5f-b7a499a01782",
  "general": {
    "request_id": "16a10539-fcb3-4ff5-a3e2-86625a2dc3d3",
    "payment_id": "P2P-WIDGET-0001"
  },
  "status": {
    "status": "processing",
    "sub_status": "awaiting_confirm",
    "status_description": null
  },
  "payment_info": {
    "amount": 7000,
    "old_amount": 7000,
    "initial_amount": 7000,
    "currency": "RUB",
    "lifetime": 300,
    "expiration_date": 1721647251,
    "updated_date": 1721647251,
    "created_date": 1721647251,
    "method": "card-p2p",
    "widget_method": "payin-p2p-card",
    "type": "payin"
  },
  "recipient_requisites": {
    "pan_hidden": "2202****6980",
    "card_holder_hidden": "Ко****ов",
    "bank_name": "t-bank",
    "bank_country": "RU",
    "currency": "RUB"
  },
  "integration": {
    "form_url": "https://pay.****host.com/****6789",
    "redirect_url": "https://your-domain.com/order/page"
  }
}

Замаскированные реквизиты в блоке recipient_requisites передаются только для статусов processing:awaiting_confirm и processing:paid. Для остальных подстатусов processing:* информативное оповещение не отправляется. В оповещениях со статусами success, decline, error и dispute:* блок recipient_requisites не передается.

Мерчант может использовать информативные оповещения для обновления состояния заказа на своей стороне.

Успешные оповещения

Успешные оповещения отправляются, когда заявка переходит в финальный статус success. URL для успешных оповещений задается в параметре merchant_success_callback_url.

{
  "project_id": "57aff4db-b45d-42bf-bc5f-b7a499a01782",
  "general": {
    "request_id": "16a10539-fcb3-4ff5-a3e2-86625a2dc3d3",
    "payment_id": "ECOM-WIDGET-0001"
  },
  "status": {
    "status": "success",
    "sub_status": null,
    "status_description": null
  },
  "payment_info": {
    "amount": 10000,
    "old_amount": 10000,
    "initial_amount": 10000,
    "currency": "RUB",
    "lifetime": 300,
    "expiration_date": 1721647251,
    "updated_date": 1721647251,
    "created_date": 1721647251,
    "method": "card-ecom",
    "widget_method": "payin-ecom-card",
    "type": "payin"
  }
}

Такие оповещения используются для:

  • фиксации успешного списания или выплаты;

  • выполнения бизнес-логики мерчанта (изменение статуса заказа, выдача услуги, зачисление бонусов и т.п.).

При получении такого оповещения рекомендуется:

  • зафиксировать успешное завершение операции в системе мерчанта;

  • обновить состояние заказа;

  • не выполнять повторное списание или повторную обработку по уже обработанной заявке.

Неуспешные оповещения

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

{
  "project_id": "57aff4db-b45d-42bf-bc5f-b7a499a01782",
  "general": {
    "request_id": "16a10539-fcb3-4ff5-a3e2-86625a2dc3d3",
    "payment_id": "ECOM-WIDGET-0001"
  },
  "status": {
    "status": "decline",
    "sub_status": null,
    "status_description": "Declined by anti-fraud"
  },
  "payment_info": {
    "amount": 10000,
    "old_amount": 10000,
    "initial_amount": 10000,
    "currency": "RUB",
    "lifetime": 300,
    "expiration_date": 1721647251,
    "updated_date": 1721647251,
    "created_date": 1721647251,
    "method": "card-ecom",
    "widget_method": "payin-ecom-card",
    "type": "payin"
  }
}

Причины отказа описываются в полях status и status_description. Коды и значения статусов приведены в разделе Коды статусов.

Формат оповещения

оповещение представляет собой HTTP POST-запрос в формате JSON.

Общие параметры:

  • Метод: POST.

  • Заголовки:

  • Тело: JSON-объект с полями заявки и статуса.

Общая структура оповещения:

{
  "project_id": "57aff4db-b45d-42bf-bc5f-b7a499a01782",
  "general": {
    "request_id": "16a10539-fcb3-4ff5-a3e2-86625a2dc3d3",
    "payment_id": "WIDGET-PAYIN-0001"
  },
  "status": {
    "status": "processing",
    "sub_status": "awaiting_confirm",
    "status_description": null
  },
  "payment_info": {
    "amount": 10000,
    "old_amount": 10000,
    "initial_amount": 10000,
    "currency": "USD",
    "lifetime": 300,
    "expiration_date": 1721647251,
    "updated_date": 1721647251,
    "created_date": 1721647251,
    "method": "card-p2p",
    "widget_method": "payin-p2p-card",
    "type": "payin"
  },
  "recipient_requisites": {
    "pan_hidden": "4850****1726",
    "card_holder_hidden": "Al****on",
    "bank_name": null,
    "bank_country": null,
    "currency": "USD"
  },
  "integration": {
    "form_url": "https://pay.****host.com/****6789",
    "redirect_url": "https://your-domain.com/order/page"
  }
}

Основные поля:

  • project_id — идентификатор кассы в системе HighHelp.

  • general — общая информация о заявке.

    • request_id — идентификатор заявки в системе HighHelp.

    • payment_id — идентификатор платежа в системе мерчанта.

  • status — статус обработки заявки.

    • status — основной статус заявки. Значения описаны в Коды статусов.

    • sub_status — подстатус заявки. Значения описаны в Коды статусов.

    • status_description — текстовое описание статуса, используется в случае ошибок или отказов.

  • payment_info — параметры платежа.

    • amount — сумма в дробных единицах валюты.

    • old_amount — предыдущая сумма в дробных единицах валюты.

    • initial_amount — первоначальная сумма в дробных единицах валюты.

    • currency — код валюты в формате ISO 4217 alpha-3. Варианты описаны в Коды валют.

    • lifetime — срок жизни заявки в секундах.

    • expiration_date — дата истечения срока жизни заявки.

    • created_date — дата создания заявки (timestamp).

    • updated_date — дата обновления заявки (timestamp).

    • method — базовый метод обработки платежа (например, card-ecom). Значения описаны в Методы оплаты (H2H).

    • widget_method — (если присутствует) метод платежной страницы. Значения описаны в Методы виджета.

    • type — тип платежа (payin или payout). Значения описаны в Типы платежей.

  • recipient_requisites — замаскированные реквизиты получателя (если доступны).

  • integration — ссылки для интеграции (например, form_url, redirect_url).

Конкретный состав полей может отличаться в зависимости от продукта и метода (P2P, ECOM, выплата).

Полный перечень возможных статусов и подстатусов приведен в Коды статусов.

Данные для аутентификации (3-D Secure)

Для заявок, созданных через платежный виджет данные для прохождения 3-D Secure и других видов аутентификации обрабатываются внутри виджета HighHelp. В HTTP-оповещениях на бэкенд мерчанта не передаются блоки acs_info и redirect_info, описанные для H2H-интеграции. Соответственно, оповещения по статусам ожидания аутентификации (например, processing:awaiting_3ds_result и processing:awaiting_redirect_result) не отправляются.

Бэкенд мерчанта получает только статус операции (status, sub_status, status_description) и платежные атрибуты. Подробный пример работы 3-D Secure в H2H-сценарии приведен в разделе Одностадийная оплата.

Проверка подписи оповещений

Каждое оповещение подписывается цифровой подписью по тому же алгоритму, что и входящие запросы к API HighHelp.

Чтобы подписать оповещения:

  • Получите актуальный публичный ключ в кабинете мерчанта (публичный ключ привязан к конкретной кассе).

  • Используйте алгоритм проверки, описанный в разделе Аутентификация и подпись.

Общие рекомендации:

  • проверять подпись всех входящих оповещений перед обработкой;

  • при ошибке проверки подписи фиксировать инцидент и не выполнять бизнес-логику по такому оповещению;

  • не использовать неподтвержденные данные (без проверки подписи) для проведения операций на стороне мерчанта.

Идемпотентность и обработка дубликатов

Оповещения могут быть отправлены повторно, если:

  • предыдущий запрос завершился с ошибкой;

  • HighHelp не получил успешный HTTP-ответ от сервера мерчанта;

  • сервер мерчанта ответил с кодом, отличным от диапазона 2xx;

  • произошла повторная попытка доставки.

Рекомендуется:

  • реализовать проверку на дубликаты;

  • использовать ключ идемпотентности вида {project_id}:{payment_id}:{status}:{sub_status};

  • игнорировать повторные оповещения с уже обработанным сочетанием status и sub_status.

Это позволяет избежать повторной обработки одной и той же операции при повторной доставке оповещений.

Если оповещение невозможно доставить (ошибка сети или неуспешный ответ сервера мерчанта), система повторяет попытки отправки до тех пор, пока не истечет срок жизни заявки. Поэтому важно, чтобы обработка оповещения была идемпотентной и не требовала длительного времени выполнения.

Ответ мерчанта на оповещение

Рекомендуемый формат ответа на оповещение:

  • HTTP-статус: 200 OK при успешной обработке.

  • Тело ответа: пустое или короткое подтверждение (например, {"status":"ok"}).

На стороне бэкенда мерчанта рекомендуется реализовать следующий алгоритм обработки:

  1. Принять HTTP-запрос POST с телом JSON.

  2. Проверить цифровую подпись оповещения.

  3. Считать ключ идемпотентности {project_id}:{payment_id}:{status}:{sub_status}.

  4. Проверить, обрабатывался ли уже данный ключ.

    • если обрабатывался, вернуть успешный HTTP-ответ и завершить обработку;

    • если не обрабатывался, выполнить бизнес-логику.

  5. В зависимости от значения status:

    • для success зафиксировать успешное завершение;

    • для decline зафиксировать отказ;

    • для dispute:* (если используется) зафиксировать спорную ситуацию и обработать по бизнес-логике;

    • для processing:* при необходимости обновить промежуточное состояние.

  6. Записать результат обработки в журнал.

  7. Вернуть HTTP-ответ с кодом 2xx в случае успешной обработки.

Это поведение одинаково для заявок, созданных через виджет и через H2H.

Практические рекомендации

Рекомендуется:

  • логировать все полученные оповещения с ключевыми полями:

    • project_id, payment_id, request_id;

    • status, sub_status, status_description;

    • значения сумм и валют;

  • проверять подпись перед выполнением бизнес-логики;

  • реализовать идемпотентность по ключу {project_id}:{payment_id}:{status}:{sub_status};

  • обрабатывать как финальные (success, decline), так и промежуточные (processing:*, dispute:*) статусы;

  • при необходимости получать актуальный статус заявки через методы …​/info для соответствующего продукта (например, метод widget/payin/info для ECOM через виджет или другие инфо-методы, описанные в продуктовых разделах).

Следующие шаги

Для настройки и отладки работы виджета: