/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: |
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: |
branchId |
Type: string Идентификатор точки продаж Max length: |
externalOperationId |
Type: string Идентификатор операции возврата в системе продавца. Должен быть уникальным. Передайте этот параметр, чтобы получить возможность отслеживать состояние операции возврата через метод operations/{external_operation_id}. Если операция не завершена (обрабатывается или остановлена), то повторный вызов метода возврата с такими же аргументами и таким же значением Если процесс возврата был успешно запущен, то повторный вызов метода возврата с тем же Max length: |
managerId |
Type: string Идентификатор менеджера Max length: |
motive |
Type: string Причина возврата Max length: |
refundCart |
Type: TargetCart Описывает позиции корзины, которые нужно вернуть.
Не может быть указано одновременно с полем |
targetCart |
Type: TargetCart Описывает итоговое состояние корзины после выполнения возврата.
Если это поле не указано, то считается, что корзина возвращается полностью.Не может быть указано одновременно с полем |
targetShipping |
Type: TargetShipping Применимо только к Yandex Pay Checkout. В остальных случаях следует оставить это поле пустым. Описывает итоговое состояние доставки после выполнения возврата.
Если это поле не указано или равно |
TargetCart
Name |
Description |
items |
Type: TargetCartItem[] |
TargetShipping
Name |
Description |
amount |
Type: string<double> Стоимость доставки после выполнения операции Example: |
TargetCartItem
Name |
Description |
productId* |
Type: string Идентификатор позиции в корзине на момент создания заказа. Если передать идентификатор, которого не было в первоначальной корзине - произойдёт ошибка. Max length: |
price |
Type: string<double> Цена одной единицы товара/услуги после выполнения операции. Необходимо указать, если цена одной единицы уменьшается в результате операции. Это может быть полезным, если необходимо вернуть часть денег за товар или подтверждении заказа. Если не указывать это поле в запросе, то считается, что цена осталась прежней. Example: |
quantityCount |
Type: string<double> Количество единиц товара для операции возврата. Значение зависит от используемой корзины:
Example: |
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: |
data |
Type: OperationResponseData |
status |
Type: string Default: Enum: |
OperationResponseData
Name |
Description |
operation |
Type: Operation |
Operation
Name |
Description |
amount* |
Type: string<double> Сумма операции в фиатной валюте Example: |
operationId* |
Type: string<uuid> Max length: |
operationType* |
Type: string Enum: |
orderId* |
Type: string Max length: |
created |
Type: string<date-time> Дата и время создания операции (ISO 8601) |
externalOperationId |
Type: string Идентификатор операции на стороне продавца Max length: |
params |
Type: object |
pointsAmount |
Type: string<double> Сумма операции в баллах Плюса Example: |
reason |
Type: string Причина ошибки Max length: |
status |
Type: string Default: Enum: |
updated |
Type: string<date-time> Дата и время обновления операции (ISO 8601) |
No longer supported, please use an alternative and newer version.