Перейти к основному содержимому

Уведомления

Чтобы отслеживать состояние платежей и возвратов, подпишитесь на уведомления (webhook). Уведомление — POST-запрос от AvantPay на ваш сервер, когда объект API меняется без вашего участия: например, покупатель оплатил платёж. Вместо того чтобы периодически запрашивать статус, дождитесь уведомления.

События​

Событие — изменение статуса объекта. Название события формируется по шаблону <объект>.<статус>: например, payment.succeeded — платёж перешёл в статус succeeded.

СобытиеКогда приходитobject
payment.succeededПлатёж оплачен.Объект платежа
payment.canceledПлатёж отменён: истёк срок оплаты, банк отказал или сработала проверка.Объект платежа
refund.succeededВозврат выполнен — полный или частичный, созданный через API или в личном кабинете.Объект возврата
payment_method.activeСпособ оплаты сохранён для автоплатежей.Объект способа оплаты

Уведомления об отмене возврата нет: отмену видно в ответе на GET /v3/refunds/{refund_id}.

Настройка​

URL и события задаются только в личном кабинете: откройте Ещё → Разработчикам → HTTP-уведомления (открыть сразу), укажите URL для уведомлений и отметьте события.

Требования к URL — протокол HTTPS, доменное имя, TCP-порт 443 или 8443, сертификат от общепризнанного центра сертификации, TLS 1.2 или выше.

URL запоминается в платеже при создании: уведомления о платеже и его возвратах приходят на URL, который был указан, когда платёж создавали.

Использование​

Когда происходит событие, на которое вы подписались, на URL приходит уведомление. Параметры тела и заголовки — в справочнике: Объект уведомления. В object — данные объекта на момент события.

Ответ и повторы​

Подтвердите получение: ответьте кодом HTTP 200 не позже чем через 10 секунд. Тело и заголовки ответа AvantPay не учитывает.

Если ответ другой или его нет, AvantPay повторяет уведомление примерно через 1, 5, 15 и 30 минут, через 1, 2, 4, 8 и 16 часов и в последний раз через 24 часа после первой попытки. Всего 11 попыток.

Проверка подлинности​

Когда получите уведомление, проверьте его подлинность: по статусу объекта, подписи или IP-адресу.

Статус объекта​

Запросите объект с вашими ключами — GET /v3/payments/{payment_id} или GET /v3/refunds/{refund_id} — и убедитесь, что статус из уведомления актуален.

Подпись​

В каждом уведомлении есть заголовки:

  • Signature-Timestamp — время отправки, Unix-время в секундах.
  • Signature — подпись: v1= и HMAC-SHA256 в шестнадцатеричном виде. Подписывается строка <Signature-Timestamp>.<тело запроса>: время, точка и тело запроса как оно пришло (байты, без разбора и повторной сборки JSON). Ключ HMAC — ваш секретный ключ API.

Как проверить:

  1. Склейте значение Signature-Timestamp, точку и тело запроса.
  2. Посчитайте HMAC-SHA256 этой строки секретным ключом и добавьте впереди v1=.
  3. Сравните с Signature функцией сравнения за постоянное время.
  4. Отклоните уведомление, если Signature-Timestamp отличается от текущего времени больше чем на 5 минут (300 секунд). Так чужой не сможет прислать вам старое уведомление повторно.

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

Функция проверки:

verify_signature.py
import hashlib
import hmac
import time
from typing import Optional

TOLERANCE_SECONDS = 300


def verify_signature(raw_body: bytes, signature: Optional[str], timestamp: Optional[str], secret_key: str) -> bool:
if not signature or not timestamp or not (timestamp.isascii() and timestamp.isdigit()):
return False
if abs(time.time() - int(timestamp)) > TOLERANCE_SECONDS:
return False
signed = timestamp.encode() + b"." + raw_body
expected = "v1=" + hmac.new(secret_key.encode(), signed, hashlib.sha256).hexdigest()
return hmac.compare_digest(signature.encode(), expected.encode())

Сравнивайте подпись функцией сравнения за постоянное время, как в примерах: hmac.compare_digest, timingSafeEqual, hash_equals.

Проверьте свою функцию на этом примере. Тело запроса:

{"type":"notification","event":"payment.succeeded","object":{"id":"2f9b6c1e-4d7a-4c3b-9e8f-1a2b3c4d5e6f","status":"succeeded","paid":true,"amount":{"value":"1000.00","currency":"RUB"}}}

Signature-Timestamp равен 1792324800. С ключом test_secret_key подпись равна v1=07181d18b6de6cfe0c882fd02f7e40c8c0e735f19dc67062c39f57c8d75c995b. Время в примере старое, поэтому проверка времени отклонит его: для самопроверки временно подставьте вместо текущего времени 1792324800.

IP-адреса AvantPay​

AvantPay отправляет уведомления только с этих IP-адресов:

  • 79.141.79.167
  • 31.129.44.152