/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 нотификации: по операции и по заказу.

  1. 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"
  }
}
  1. 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.

  1. 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.

  1. 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 нотификации: по операции и по заказу.

Рассмотрим на примере заказа с тремя пачками сока.

  1. Совершили частичный возврат одного сока. Вам придет 2 нотификации:

    1. 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"
        }
      }
      
    2. 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. Совершили второй частичный возврат одного сока. Вам придет 2 нотификации:

    1. 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"
        }
      }
      
    2. 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"
        }
      }
      
  3. Совершили третий частичный возврат. Сумма всех возвратов достигла полной стоимости. Вам придет 2 нотификации:

    1. 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"
        }
      }
      
    2. 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 нотификации:

  1. 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.

  2. 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 нотификации.

  1. 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.

  2. 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"
      }
    }
    
  1. 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"
      }
    }
    
  2. 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

Тип события:

  • ORDER_STATUS_UPDATED — обновление статуса заказа;
  • OPERATION_STATUS_UPDATED — обновление статуса операций списания, возврата или отмены платежа.

Enum: TRANSACTION_STATUS_UPDATE, ORDER_STATUS_UPDATED, OPERATION_STATUS_UPDATED, SUBSCRIPTION_STATUS_UPDATED

eventTime*

Type: string<date-time>

Время события в формате RFC 3339: YYYY-MM-DDThh:mm:ssTZD.

Example: 2025-05-26T21:00:36.08847+00:00

merchantId*

Type: string<uuid>

ID (идентификатор) продавца.

operation

Type: OperationWebhookData

Информация по операции. Приходит с событием OPERATION_STATUS_UPDATED

order

Type: OrderWebhookData

Информация по заказу. Приходит с событием ORDER_STATUS_UPDATED

subscription

Type: SubscriptionWebhookData

Состояние подписки.

OperationWebhookData

Name

Description

operationId*

Type: string<uuid>

Идентификатор операции.

Example: 5d32f295-8723-457d-81f9-ab13f17b7bd6

operationType*

Type: string

Тип операции. Подробнее о типах операций читайте в разделе Статусы операций.

Enum: AUTHORIZE, BIND_CARD, REFUND, CAPTURE, VOID, RECURRING, PREPAYMENT, SUBMIT

orderId*

Type: string

ID заказа, переданный в /v1/orders при создании заказа.

status*

Type: string

Статус операции. Подробнее о статусах операций читайте в разделе Статусы операций.

Enum: PENDING, SUCCESS, FAIL

externalOperationId

Type: string

Идентификатор операции в системе продавца. Должен быть уникальным.

Передайте этот параметр, чтобы отслеживать конкретную операцию через метод v1/operations/external_operation_id

OrderWebhookData

Name

Description

orderId*

Type: string

ID заказа, переданный в /v1/orders при создании заказа.

paymentStatus*

Type: string

Статус заказа. Подробнее читайте в разделе Статусы платежей.

Enum: PENDING, AUTHORIZED, CAPTURED, VOIDED, REFUNDED, CONFIRMED, PARTIALLY_REFUNDED, FAILED

cartUpdated

Type: boolean

Была ли обновлена корзина. Возвращается при оплате баллами.Если флаг имеет значение true, получите актуальную корзину.

SubscriptionWebhookData

Name

Description

customerSubscriptionId*

Type: string<uuid>

ID подписки. Возвращается из SDK при успешном создании подписки. Также можно сохранить подписку при получении первой нотификации по ней. Дальнейшие обновления по этой подписке будут приходить с таким же значением этого поля.

status*

Type: string

Статус подписки.

Enum: NEW, ACTIVE, CANCELLED, EXPIRED

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: success

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

Код ошибки:

  • FORBIDDEN — заказ существует, но был оплачен не через Яндекс Пэй;
  • ORDER_NOT_FOUND — заказ не найден в системе продавца;
  • ORDER_AMOUNT_MISMATCH — сумма заказа не совпадает с суммой в системе продавца;
  • ORDER_DETAILS_MISMATCH — детали заказа отличаются от данных в системе продавца;
  • OTHER — общая ошибка;
  • UNAUTHORIZED — не удалось проверить подпись JWT-токена;
  • TOKEN_EXPIRED — срок действия JWT-токена истек;
  • CONFLICT — данные в нотификации расходятся с состоянием заказа в системе продавца. Например, пришла нотификация об оплате для отмененного заказа.

Enum: FORBIDDEN, ITEM_NOT_FOUND, ORDER_NOT_FOUND, ORDER_AMOUNT_MISMATCH, ORDER_DETAILS_MISMATCH, OUT_OF_INVENTORY, PICKUP_POINT_NOT_FOUND, SHIPPING_DETAILS_MISMATCH, OTHER, UNAUTHORIZED, TOKEN_EXPIRED, CONFLICT

reason

Type: string

Описание причины ошибки.

status

Type: string

Default: fail

No longer supported, please use an alternative and newer version.

Предыдущая
Следующая