/v2/orders/{order_id}/refund

Запрос на возврат средств за заказ.

Метод является асинхронным.

Схема процесса возврата

Ограничения

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

Нельзя оформить возврат, если:

  • сумма возврата меньше 1 рубля;
  • после возврата в заказе останется меньше 1 рубля.

Возвраты доступны для платежей в одном из статусов paymentStatus:

  • CAPTURED — заказ успешно оплачен, средства списаны со счета плательщика;
  • PARTIALLY_REFUNDED — совершен частичный возврат средств за заказ.

После успешного выполнения возврата статус платежа paymentStatus изменится:

  • на REFUNDED, если был произведен полный возврат;
  • на PARTIALLY_REFUNDED, если после совершения возврата в заказе остались товары.

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

Пример: в вашем магазине совершен заказ на 1000 рублей и сделан возврат на 200 рублей. На следующий рабочий день вы получите выплату 800 рублей (1000 − 200).

Нельзя одновременно проводить несколько возвратов по одному заказу.

Перед отправкой повторного запроса проверьте, что текущая операция возврата завершена: status должен быть SUCCESS или FAIL.

Иначе вы получите ответ 409 Conflict c ошибкой ANOTHER_OPERATION_IN_PROGRESS.

Отслеживать изменения статуса возврата можно через нотификации /webhook, а также с помощью запросов:

Примеры проверки статуса возврата

С помощью метода /operations/{external_operation_id}/ по externalOperationId можно проверить состояние текущего возврата.

В примере ниже операция не завершена — "status": "PENDING". Нельзя отправить повторный запрос на возврат.

Пример ответа
{
  "code": 200,
  "status": "success",
  "data": {
    "operation": {
      "operationId": "52b3c4a8-528b-45eb-a57f-8f808f65d28f",
      "operationType": "REFUND",
      "orderId": "OrderS-2038",
      "amount": "250.00",
      "pointsAmount": null,
      "status": "PENDING", // возврат в процессе
      "reason": null,
      "params": { "motive": null, "branch_id": null, "manager_id": null },
      "externalOperationId": "OrderS-2038",
      "created": "2025-03-14T14:58:45.850206+03:00",
      "updated": "2025-03-14T14:58:45.850206+03:00"
    }
  }
}

С помощью метода /operations/{external_operation_id}/ можно проверить все детали заказа.

В примере ниже операция возврата завершена успешно — "status": "SUCCESS", а платеж в статусе "paymentStatus": "PARTIALLY_REFUNDED". Можно отправить повторный запрос на возврат.

Пример ответа
{
  "code": 200,
  "status": "success",
  "data": {
    "operations": [
      {
        "operationId": "52b3c4a8-528b-45eb-a57f-8f808f65d28f",
        "operationType": "REFUND",
        "orderId": "OrderS-2038",
        "amount": "250.00",
        "status": "SUCCESS", // возврат успешно завершен
        "reason": null,
        "params": { "motive": null, "branch_id": null, "manager_id": null },
        "externalOperationId": "OrderS-2038",
        "created": "2025-03-14T14:58:45.850206+03:00",
        "updated": "2025-03-14T14:58:46.084886+03:00",
        "approvalCode": null
      },
      {
        "operationId": "9c763cfb-dcf6-4056-be8f-ca9e2e61d772",
        "operationType": "AUTHORIZE",
        "orderId": "OrderS-2038",
        "amount": "500.00",
        "status": "SUCCESS",
        "reason": null,
        "params": {},
        "externalOperationId": null,
        "created": "2025-03-14T14:58:07.161667+03:00",
        "updated": "2025-03-14T14:58:07.414886+03:00",
        "approvalCode": null
      }
    ],
    "order": {
      "currencyCode": "RUB",
      "cart": {
        "items": [
          {
            "productId": "p2",
            "quantity": { "count": "1", "available": null, "label": null },
            "type": "UNSPECIFIED",
            "title": "Яндекс.Станция Мини",
            "description": null,
            "total": "250",
            "subtotal": null,
            "discountedUnitPrice": "250",
            "unitPrice": null,
            "measurements": null,
            "receipt": null,
            "finalPrice": "250",
            "pointsAmount": null,
            "features": null
          }
        ],
        "total": { "amount": "250", "pointsAmount": null, "label": null },
        "cartId": "1eed9a9827e68ba8981d9961c1237624fabc19cda05044b574e06302e83c7549",
        "externalId": null,
        "coupons": null,
        "discounts": null,
        "measurements": null
      },
      "merchantId": "76cc0f5c-91c4-40f2-9794-64a64c3c6011",
      "orderAmount": "250.00",
      "orderId": "OrderS-2038",
      "paymentMethod": { "methodType": "CARD", "cardLast4": "0412", "cardNetwork": "MASTERCARD" },
      "shippingMethod": null,
      "metadata": null,
      "created": "2025-03-14T14:58:03.699930+03:00",
      "updated": "2025-03-14T14:58:46.084886+03:00",
      "paymentStatus": "PARTIALLY_REFUNDED", // платеж частично возвращен
      "reason": null,
      "paymentUrl": "https://`[`sandbox.pay.ya.ru`](http://sandbox.pay.ya.ru)`/l/I1RnP9",
      "isPrepayment": false,
      "splitCode": null
    },
    "delivery": null
  }
}

Виды возвратов

Доступен полный или частичный возврат платежа.

Для выполнения полного возврата передайте только refundAmount, равный сумме заказа.

Для выполнения частичного передайте refundAmount, равный сумме возврата, и добавьте корзину предоставляемых товаров и услуг. Сформировать корзину можно одним из способов:

  • Способ 1: Указать состояние корзины после возврата.

    Используйте поле targetCart — целевая корзина, которая должна остаться у покупателя после выполнения возврата. Если это поле не указано, то считается, что корзина возвращается полностью.

    Поле targetShipping применимо только к Yandex Pay Checkout. В остальных случаях следует оставить это поле пустым. Если это поле не указано, то считается, что стоимость доставки возвращается полностью.

  • Способ 2: Указать возвращаемые товары.

    Используйте поле refundCart — данные о возвращаемых позициях: количество единиц товара для возврата или сумма, на которую нужно уменьшить стоимость конкретного товара. Если поле не указано, возврат осуществляется на всю корзину.

Примечание

При использовании refundCart указывайте идентификатор операции externalOperationId. Он служит токеном идемпотентности и позволяет избежать риска повторных возвратов.

Примеры возвратов

Рассмотрим на примере заказа с orderId = Order-123 и следующей корзиной:

{
  "items": [
    {
      "productId": "id-1",
      "price": "50",
      "title": "Шариковая ручка",
      "quantity": {
        "count": "10"
      }
    },
    {
      "productId": "id-2",
      "price": "200",
      "title": "Блокнот",
      "quantity": {
        "count": "2"
      }
    }
  ]
}

Полный возврат

http POST https://sandbox.pay.yandex.ru/api/merchant/v2/orders/Order-123/refund \
  "Authorization: Api-Key ${API_KEY}" 'refundAmount:="900.00"'

Частичный возврат

Возврат единиц товара

Допустим, необходимо вернуть две шариковые ручки. Это делается следующим запросом:

http POST https://sandbox.pay.yandex.ru/api/merchant/v2/orders/Order-123/refund \
  "Authorization: Api-Key ${API_KEY}" \
  'targetCart[items][0]:={"productId": "id-1", "quantityCount": "8"}' \
  'targetCart[items][1]:={"productId": "id-2", "quantityCount": "2"}' \
  'refundAmount:="100.00"'

В этом примере:

  • Количество шариковых ручек уменьшилось на 2, с 10 до 8 единиц.
  • Поле price в запросе пропущено, но его вполне допустимо указать.
  • quantityCount у позиции с блокнотом не изменилось, его можно было не указывать.

Возврат части денег

Допустим, необходимо вернуть 30 рублей за каждый из блокнотов. Это достигается путем уменьшения цены позиции.

http POST https://sandbox.pay.yandex.ru/api/merchant/v2/orders/Order-123/refund \
  "Authorization: Api-Key ${API_KEY}" \
  'targetCart[items]:=[{"productId": "id-1"}, {"productId": "id-2", "price": "170"}]' \
  'refundAmount:="60.00"'

В этом примере:

  • Цена блокнота уменьшилась на 30 рублей, с 200 до 170 рублей;
  • Таким образом, производится возврат 60 рублей, поскольку блокнотов было два.
  • quantityCount не указаны, но вполне допустимо указать их прежние значения.

Возврат c указанием количества возвращаемого товара

Допустим, необходимо вернуть две шариковые ручки. Это делается следующим запросом:

http POST https://sandbox.pay.yandex.ru/api/merchant/v2/orders/Order-123/refund \
  "Authorization: Api-Key ${API_KEY}" \
  'refundCart[items][0]:={"productId": "id-1", "quantityCount": "2"}' \
  'refundAmount:="100.00"'

В этом примере:

  • Количество шариковых ручек уменьшилось на 2, с 10 до 8 единиц.
  • Поле price в запросе пропущено, но его вполне допустимо было указать.

Возврат с указанием, какую часть от стоимости товара необходимо вернуть

Допустим, необходимо вернуть 30 рублей за каждый из блокнотов. Это достигается путем уменьшения цены позиции.

http POST https://sandbox.pay.yandex.ru/api/merchant/v2/orders/Order-123/refund \
  "Authorization: Api-Key ${API_KEY}" \
  'refundCart[items]:=[{"productId": "id-1"}, {"productId": "id-2", "price": "30"}]' \
  'refundAmount:="60.00"'

В этом примере:

  • Цена блокнота уменьшилась на 30, с 200 рублей до 170 рублей.
  • Таким образом, производится возврат 60 рублей, поскольку блокнотов было два.
  • quantityCount не указаны, но вполне допустимо указать их прежние значения.

Request

POST

https://pay.yandex.ru/api/merchant/v2/orders/{order_id}/refund

Production

POST

https://sandbox.pay.yandex.ru/api/merchant/v2/orders/{order_id}/refund

Sandbox

Path parameters

Name

Description

order_id*

Type: string

ID заказа на стороне продавца, который был передан в ответе на /orders.

Max length: 2048

Body

application/json
{
    "branchId": "string",
    "externalOperationId": "string",
    "managerId": "string",
    "motive": "string",
    "refundAmount": "123.45",
    "refundCart": {
        "items": [
            {
                "price": "123.45",
                "productId": "string",
                "quantityCount": "123.45"
            }
        ]
    },
    "targetCart": {
        "items": [
            {
                "price": "123.45",
                "productId": "string",
                "quantityCount": "123.45"
            }
        ]
    },
    "targetShipping": {
        "amount": "123.45"
    }
}

Name

Description

refundAmount*

Type: string<double>

Сумма к возврату. Минимальная сумма возврата — 1 рубль.

Example: 123.45

branchId

Type: string

Идентификатор точки продаж

Max length: 2048

externalOperationId

Type: string

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

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

Если операция не завершена (обрабатывается или остановлена), то повторный вызов метода возврата с такими же аргументами и таким же значением externalOperationId будет идемпотентным: в ответе вернется та же операция. Иначе вернется ошибка.

Если процесс возврата был успешно запущен, то повторный вызов метода возврата с тем же externalOperationId вернет ошибку с "reasonCode": "DUPLICATE_EXTERNAL_OPERATION_ID".

Max length: 2048

managerId

Type: string

Идентификатор менеджера

Max length: 2048

motive

Type: string

Причина возврата

Max length: 2048

refundCart

Type: TargetCart

Описывает позиции корзины, которые нужно вернуть. Не может быть указано одновременно с полем targetCart. Вместе с этим параметром желательно передавать идентификатор операции externalOperationId, так как он является токеном идемпотентности.

targetCart

Type: TargetCart

Описывает итоговое состояние корзины после выполнения возврата. Если это поле не указано, то считается, что корзина возвращается полностью.Не может быть указано одновременно с полем refundCart.

targetShipping

Type: TargetShipping

Применимо только к Yandex Pay Checkout. В остальных случаях следует оставить это поле пустым.

Описывает итоговое состояние доставки после выполнения возврата. Если это поле не указано или равно null, то считается, что стоимость доставки возвращается полностью.

TargetCart

Name

Description

items

Type: TargetCartItem[]

TargetShipping

Name

Description

amount

Type: string<double>

Стоимость доставки после выполнения операции

Example: 123.45

TargetCartItem

Name

Description

productId*

Type: string

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

Max length: 2048

price

Type: string<double>

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

Example: 123.45

quantityCount

Type: string<double>

Количество единиц товара для операции возврата.

Значение зависит от используемой корзины:

  • если targetCart, то quantityCount — остаток товара после возврата (было 5 единиц товара, указали 3 → вернется 2);
  • если refundCart, то quantityCount — количество возвращаемых товаров (было 5 единиц товара, указали 3 → вернется 3). Если поле не указано, количество товара не меняется.

Example: 123.45

Responses

200 OK

Body

application/json
{
    "code": 200,
    "data": {
        "operation": {
            "amount": "123.45",
            "created": "2022-12-29T18:02:01Z",
            "externalOperationId": "string",
            "operationId": "c3073b9d-edd0-49f2-a28d-b7ded8ff9a8b",
            "operationType": "AUTHORIZE",
            "orderId": "string",
            "params": {},
            "pointsAmount": "123.45",
            "reason": "string",
            "status": "PENDING",
            "updated": "2022-12-29T18:02:01Z"
        }
    },
    "status": "success"
}

Name

Description

code

Type: number

Default: 200

data

Type: OperationResponseData

status

Type: string

Default: success

Enum: success

OperationResponseData

Name

Description

operation

Type: Operation

Operation

Name

Description

amount*

Type: string<double>

Сумма операции в фиатной валюте

Example: 123.45

operationId*

Type: string<uuid>

Max length: 2048

operationType*

Type: string

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

orderId*

Type: string

Max length: 2048

created

Type: string<date-time>

Дата и время создания операции (ISO 8601)

externalOperationId

Type: string

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

Max length: 2048

params

Type: object

pointsAmount

Type: string<double>

Сумма операции в баллах Плюса

Example: 123.45

reason

Type: string

Причина ошибки

Max length: 2048

status

Type: string

Default: PENDING

Enum: PENDING, SUCCESS, FAIL

updated

Type: string<date-time>

Дата и время обновления операции (ISO 8601)

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

Предыдущая