/v1/webhook
Нотификации об изменении статуса.
Запрос отправляется при изменении статуса заказа или операции по заказу.
Поддерживаемые события:
ORDER_STATUS_UPDATED
— обновление статуса заказа;OPERATION_STATUS_UPDATED
— обновление статуса операций списания, возврата или отмены платежа.
Формат запроса
Запрос приходит в формате application/octet-stream
в виде JWT-токена, подписанного по алгоритму ES256. Перед обработкой запроса проверьте его подлинность. Как это сделать, читайте в разделе Аутентификация.
Payload проверенного и декодированного JWT-токена содержит JSON с данными события. Посмотрите примеры событий.
Если в токене нет тела запроса
- Убедитесь, что бэкенд вашего магазина готов принимать сообщение с заголовком
Content-Type: application/octet-stream
. - Проверьте, что брандмауэр не блокирует входящие запросы и не обрезает тело запроса.
Другие ошибки смотрите в разделе Решение проблем c вебхуками.
Идемпотентность операций
При действиях с заказом, например, при возврате средств методом /v2/orders/{order_id}/refund, передавайте уникальный идентификатор операции externalOperationId
.
С помощью него вы сможете:
- понять, по какой операции пришла нотификация;
- проверить состояние операции через метод v1/operations/{external_operation_id};
- защититься от дублирования.
Если отправите запрос повторно с тем же externalOperationId
, то получите:
- информацию о текущей операции, если она в процессе;
- ошибку c
reasonCode: "DUPLICATE_EXTERNAL_OPERATION_ID"
, если операция завершена.
Примеры событий
Оплата заказа
{
"merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx",
"event": "ORDER_STATUS_UPDATED",
"eventTime": "2023-11-26T08:11:09.359370+00:00",
"order": {
"orderId": "700aa3f04df64b3b8712d6b51f752e8b",
"paymentStatus": "CAPTURED"
}
}
Посмотрите пример JWT-токена на jwt.io.
Пример запроса от Яндекс Пэй:
curl -X POST https://test.ru/some/prefix/v1/webhook \
--header 'User-Agent: YandexPay/1.0' \
--header 'Accept: \*/\*' \
--header 'Content-Type: application/octet-stream' \
--header 'X-Request-Id: ff2a54885c4e45309853d2e33af1d63b\\_3a70f3062db640fcb2f3c34de1a27bd5' \
--header 'X-Request-Timeout: 13970' \
--compressed \
-d eyJhbGciOiJFUzI1NiIsImV4cCI6MTcwMDk4NzYwMCwiaWF0IjoxNzAwOTg3MzAwLCJraWQiOiIxLW1lcmNoYW50LWFwaSIsInR5cCI6IkpXVCJ9.eyJtZXJjaGFudElkIjoieHh4eHh4eHh4LXh4eC01eHh4LXh4eHh4LXh4eHh4eHh4IiwiZXZlbnQiOiJPUkRFUl9TVEFUVVNfVVBEQVRFRCIsImV2ZW50VGltZSI6IjIwMjMtMTEtMjZUMDg6MTE6MDkuMzU5MzcwKzAwOjAwIiwib3JkZXIiOnsib3JkZXJJZCI6IjcwMGFhM2YwNGRmNjRiM2I4NzEyZDZiNTFmNzUyZThiIiwicGF5bWVudFN0YXR1cyI6IkNBUFRVUkVEIn19.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
{
"merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx",
"event": "ORDER_STATUS_UPDATED",
"eventTime": "2024-04-25T07:56:29.974810+00:00",
"order": {
"orderId": "253222_1714029088",
"paymentStatus": "FAILED"
}
}
Посмотрите пример JWT-токена на jwt.io.
Возврат
Совет
Сначала изучите, как работают возвраты, в разделе /v2/orders/{order_id}/refund.
Полный возврат
Независимо от того, меняется ли статус заказа, отправляется 2 нотификации: по операции и по заказу.
OPERATION_STATUS_UPDATED
— операция возврата завершилась успешно:
{
"merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx",
"event": "OPERATION_STATUS_UPDATED",
"eventTime": "2024-04-19T10:27:53.323878+00:00",
"operation": {
"operationId": "73dec2cd-db5c-4386-be6d-10c5b5a2ee09",
"orderId": "86283",
"status": "SUCCESS",
"operationType": "REFUND"
}
}
ORDER_STATUS_UPDATED
— заказ в перешел в терминальный статусREFUNDED
. Больше нельзя вызывать возвраты.
{
"merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx",
"event": "ORDER_STATUS_UPDATED",
"eventTime": "2024-04-19T12:16:28.766392+00:00",
"order": {
"orderId": "86283",
"paymentStatus": "REFUNDED"
}
}
Посмотрите пример JWT-токена на jwt.io.
OPERATION_STATUS_UPDATED
— операция возврата завершилась неуспешно:
{
"merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx",
"event": "OPERATION_STATUS_UPDATED",
"eventTime": "2024-06-13T22:27:53.323878+00:00",
"operation": {
"operationId": "73dec2cd-db5c-4386-be6d-10c5b5a2ee08",
"orderId": "9c8aed6d-a8e5-4c6a-acd8-645538173f66",
"status": "FAIL",
"operationType": "REFUND"
}
}
Посмотрите пример JWT-токена на jwt.io.
ORDER_STATUS_UPDATED
— заказ остался в предыдущем статусеCAPTURED
:
{
"merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx",
"event": "ORDER_STATUS_UPDATED",
"eventTime": "2024-06-13T22:27:54.323878+00:00",
"order": {
"orderId": "9c8aed6d-a8e5-4c6a-acd8-645538173f66",
"paymentStatus": "CAPTURED"
}
}
Частичный возврат
Вы можете вернуть всю сумму заказа несколькими частичными возвратами. Когда сумма всех возвратов достигнет полной стоимости, заказ перейдет в терминальный статус REFUNDED
. После этого нельзя вызывать возвраты.
Независимо от того, меняется ли статус заказа, отправляется 2 нотификации: по операции и по заказу.
Рассмотрим на примере заказа с тремя пачками сока.
-
Совершили частичный возврат одного сока. Вам придет 2 нотификации:
-
OPERATION_STATUS_UPDATED
— операция возврата завершилась успешно:{ "merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx", "event": "OPERATION_STATUS_UPDATED", "eventTime": "2024-04-19T10:27:53.323878+00:00", "operation": { "operationId": "73dec3cs-sd5t-4356-ne6d-10c79b5d2ee09", "externalOperationId": "123-partial-refund-1", "orderId": "123", "status": "SUCCESS", "operationType": "REFUND" } }
-
ORDER_STATUS_UPDATED
— заказ в перешел в статусPARTIALLY_REFUNDED
:{ "merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx", "event": "ORDER_STATUS_UPDATED", "eventTime": "2024-04-19T12:16:28.766392+00:00", "order": { "orderId": "123", "paymentStatus": "PARTIALLY_REFUNDED" } }
-
-
Совершили второй частичный возврат одного сока. Вам придет 2 нотификации:
-
OPERATION_STATUS_UPDATED
— операция возврата завершилась успешно:{ "merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx", "event": "OPERATION_STATUS_UPDATED", "eventTime": "2024-04-19T13:27:53.323878+00:00", "operation": { "operationId": "28fba9ds-kl2m-7891-qw3r-45e82c7f1bb12", "externalOperationId": "123-partial-refund-2", "orderId": "123", "status": "SUCCESS", "operationType": "REFUND" } }
-
ORDER_STATUS_UPDATED
— заказ остался в статусеPARTIALLY_REFUNDED
:{ "merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx", "event": "ORDER_STATUS_UPDATED", "eventTime": "2024-04-19T13:27:54.321878+00:00", "order": { "orderId": "123", "paymentStatus": "PARTIALLY_REFUNDED" } }
-
-
Совершили третий частичный возврат. Сумма всех возвратов достигла полной стоимости. Вам придет 2 нотификации:
-
OPERATION_STATUS_UPDATED
— операция возврата завершилась успешно:{ "merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx", "event": "OPERATION_STATUS_UPDATED", "eventTime": "2024-04-19T13:40:51.323878+00:00", "operation": { "operationId": "64abc2ts-rj4y-3187-mf5g-56b71e9a4dd67", "externalOperationId": "123-partial-refund-3", "orderId": "123", "status": "SUCCESS", "operationType": "REFUND" } }
-
ORDER_STATUS_UPDATED
— заказ в перешел в терминальный статусREFUNDED
. Больше нельзя вызывать возвраты.{ "merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx", "event": "ORDER_STATUS_UPDATED", "eventTime": "2024-04-19T14:16:28.766392+00:00", "order": { "orderId": "123", "paymentStatus": "REFUNDED" } }
-
Двухстадийный платеж: списание заблокированных средств
В двухстадийных платежах после подтверждения списания средств методом /v1/orders/{order_id}/capture вам придет 2 нотификации:
-
OPERATION_STATUS_UPDATED
— операция списания средств завершилась успешно:{ "merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx", "event": "OPERATION_STATUS_UPDATED", "eventTime": "2024-07-22T03:19:07.425889+00:00", "operation": { "operationId": "2d23342e-6688-4201-bee2-299330ff7ba6", "orderId": "000540777", "status": "SUCCESS", "operationType": "CAPTURE", "externalOperationId": "000540777-capture" } }
Посмотрите пример JWT-токена на jwt.io.
-
ORDER_STATUS_UPDATED
— заказ в перешел в статусCAPTURED
:{ "merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx", "event": "ORDER_STATUS_UPDATED", "eventTime": "2024-07-22T06:29:07.425889+00:00", "order": { "orderId": "000540777", "paymentStatus": "CAPTURED" } }
Рекуррентный платеж: списание средств по подписке
В рекуррентных платежах после списания средств методом /v1/subscriptions/recur вам придет 2 нотификации.
-
OPERATION_STATUS_UPDATED
— операция списания средств завершилась успешно:{ "event": "OPERATION_STATUS_UPDATED", "eventTime": "2025-05-26T21:00:36.08847+00:00", "merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx", "operation": { "operationId": "15c980db-1d76-4d4b-a28e-b1c18dfff74f", "operationType": "RECURRING", "orderId": "667682505ORG12622TO79659--1748293232", "status": "SUCCESS" } }
Посмотрите пример JWT-токена на jwt.io.
-
ORDER_STATUS_UPDATED
— заказ в перешел в статусCAPTURED
:{ "merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx", "event": "ORDER_STATUS_UPDATED", "eventTime": "2025-05-26T22:00:36.08847+00:00", "order": { "orderId": "667682505ORG12622TO79659--1748293232", "paymentStatus": "CAPTURED" } }
-
OPERATION_STATUS_UPDATED
— операция списания средств завершилась неуспешно:{ "event": "OPERATION_STATUS_UPDATED", "eventTime": "2025-05-26T21:02:03.343994+00:00", "merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx", "operation": { "operationId": "eba91cce-6723-4c7b-ae28-bd2fe39de287", "operationType": "RECURRING", "orderId": "667683695ORG1393TO285518--1748293320", "status": "FAIL" } }
-
ORDER_STATUS_UPDATED
— заказ в перешел в статусFAILED
:{ "merchantId": "xxxxxxxxx-xxx-5xxx-xxxxx-xxxxxxxx", "event": "ORDER_STATUS_UPDATED", "eventTime": "2025-05-26T21:42:03.343994+00:00", "order": { "orderId": "667683695ORG1393TO285518--1748293320", "paymentStatus": "FAILED" } }
Request
POST
https://example.merchant.ru/v1/webhook
Production
POST
https://sandbox.example.merchant.ru/v1/webhook
Sandbox
Body
application/json
{
"event": "TRANSACTION_STATUS_UPDATE",
"eventTime": "2025-05-26T21:00:36.08847+00:00",
"merchantId": "c3073b9d-edd0-49f2-a28d-b7ded8ff9a8b",
"operation": {
"externalOperationId": "string",
"operationId": "5d32f295-8723-457d-81f9-ab13f17b7bd6",
"operationType": "AUTHORIZE",
"orderId": "string",
"status": "PENDING"
},
"order": {
"cartUpdated": false,
"orderId": "string",
"paymentStatus": "PENDING"
},
"subscription": {
"customerSubscriptionId": "c3073b9d-edd0-49f2-a28d-b7ded8ff9a8b",
"nextWriteOff": "2022-12-29T18:02:01Z",
"status": "NEW",
"subscriptionPlanId": "c3073b9d-edd0-49f2-a28d-b7ded8ff9a8b"
}
}
Name |
Description |
event* |
Type: string Тип события:
Enum: |
eventTime* |
Type: string<date-time> Время события в формате Example: |
merchantId* |
Type: string<uuid> ID (идентификатор) продавца. |
operation |
Type: OperationWebhookData Информация по операции. Приходит с событием |
order |
Type: OrderWebhookData Информация по заказу. Приходит с событием |
subscription |
Type: SubscriptionWebhookData Состояние подписки. |
OperationWebhookData
Name |
Description |
operationId* |
Type: string<uuid> Идентификатор операции. Example: |
operationType* |
Type: string Тип операции. Подробнее о типах операций читайте в разделе Статусы операций. Enum: |
orderId* |
Type: string ID заказа, переданный в /v1/orders при создании заказа. |
status* |
Type: string Статус операции. Подробнее о статусах операций читайте в разделе Статусы операций. Enum: |
externalOperationId |
Type: string Идентификатор операции в системе продавца. Должен быть уникальным. Передайте этот параметр, чтобы отслеживать конкретную операцию через метод v1/operations/external_operation_id |
OrderWebhookData
Name |
Description |
orderId* |
Type: string ID заказа, переданный в /v1/orders при создании заказа. |
paymentStatus* |
Type: string Статус заказа. Подробнее читайте в разделе Статусы платежей. Enum: |
cartUpdated |
Type: boolean Была ли обновлена корзина. Возвращается при оплате баллами.Если флаг имеет значение |
SubscriptionWebhookData
Name |
Description |
customerSubscriptionId* |
Type: string<uuid> ID подписки. Возвращается из SDK при успешном создании подписки. Также можно сохранить подписку при получении первой нотификации по ней. Дальнейшие обновления по этой подписке будут приходить с таким же значением этого поля. |
status* |
Type: string Статус подписки. Enum: |
subscriptionPlanId* |
Type: string<uuid> ID плана подписки, созданного в личном кабинете или через API. |
nextWriteOff |
Type: string<date-time> Дата следующей попытки списания денег по подписке. |
Responses
200 OK
Вебхук успешно получен и обработан.
Тело ответа может быть любым, рекомендуем отправить {"status": "success"}
.
При получении 200
Яндекс Пэй прекращает отправку повторных вебхуков.
Body
application/json
{
"status": "success"
}
Name |
Description |
status |
Type: string Default: |
400 Bad Request
Ошибка обработки вебхука.
При отсутствии ответа или любом статусе кроме 200
Яндекс Пэй генерирует новый JWT-токен и повторяет отправку вебхука:
- первые 10 раз через 5 мс;
- далее с экспоненциально возрастающим интервалом до 15 минут;
- затем каждые 15 минут в течение 24 часов. Общее время повторных отправок — 24 часа. После этого вебхук считается недоставленным.
Body
application/json
{
"reason": "string",
"reasonCode": "FORBIDDEN",
"status": "fail"
}
Name |
Description |
reasonCode* |
Type: string Код ошибки:
Enum: |
reason |
Type: string Описание причины ошибки. |
status |
Type: string Default: |
No longer supported, please use an alternative and newer version.