/v2/orders/{order_id}/refund
Request to refund an order.
Asynchronous method.
Refund workflow
Restrictions
You can make a full or partial payment refund.
Refunds are available for payments that have one these statuses (paymentStatus):
CAPTURED: The order has been successfully paid and funds have been debited from the payer's account.PARTIALLY_REFUNDED: A partial refund has already been issued for the order.
Once a refund is made, the paymentStatus changes to:
REFUNDEDif the full amount was refunded.PARTIALLY_REFUNDEDif the cart has some items left after the refund.
The total refund amount for the current day is withheld the next business day from the partner payout for the order.
Example: An order for som 1000 is placed at your store and a refund of som 200 is issued. On the next business day, you receive a payout of 800 som (1000 − 200).
You cannot process multiple refunds for the same order simultaneously.
Before sending a repeat request, ensure the current refund operation has been completed: its status must be SUCCESS or FAIL.
Otherwise, you'll get a 409 Conflict response with an error message saying ANOTHER_OPERATION_IN_PROGRESS.
You can track refund status changes via /webhook notifications and using the following requests:
Here's how you can check the refund status
Use the /operations/{external_operation_id}/ method to check the status of the current refund by externalOperationId.
In the example below, the operation has not been completed ("status": "PENDING"). You can't make a repeat refund request.
Response example
{
"code": 200,
"status": "success",
"data": {
"operation": {
"operationId": "52b3c4a8-528b-45eb-a57f-8f808f65d28f",
"operationType": "REFUND",
"orderId": "OrderS-2038",
"amount": "250.00",
"pointsAmount": null,
"status": "PENDING", // refund in progress
"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"
}
}
}
Use the /operations/{external_operation_id}/ method to check all the order details.
In the example below, the refund operation has been completed with "status": "SUCCESS" and the payment status is "paymentStatus": "PARTIALLY_REFUNDED". You can make a repeat refund request.
Response example
{
"code": 200,
"status": "success",
"data": {
"operations": [
{
"operationId": "52b3c4a8-528b-45eb-a57f-8f808f65d28f",
"operationType": "REFUND",
"orderId": "OrderS-2038",
"amount": "250.00",
"status": "SUCCESS", // refund completed successfully
"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": "Yandex Station Mini",
"description": null,
"total": "250",
"subtotal": null,
"discountedUnitPrice": "250",
"unitPrice": null,
"measurements": 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", // payment partially refunded
"reason": null,
"paymentUrl": "https://sandbox.pay.yandex.uz/l/I1RnP9",
"isPrepayment": false,
"splitCode": null
},
"delivery": null
}
}
Refund types
You can make full and partial refunds.
To make a full refund, only pass the refundAmount parameter that is equal to the order amount.
To make a partial refund, pass the refundAmount parameter that is equal to the refund amount and add the cart of items or services provided. You can create a cart in one of the following ways:
-
Method 1: Specify the cart status after the refund.
Use the
targetCartfield to describe the final cart the customer will have after the refund is made. If the field is omitted, it's considered that the entire cart is refunded.The
targetShippingfield is only applicable to Yandex Pay Checkout. In all other cases, leave the field empty. If the field is omitted, it's considered that the delivery cost is refunded in full. -
Method 2: Specify the items to be refunded.
Use the
refundCartfield to specify the number of items to be refunded or the amount to decrease the cost of a specific item by. If the field is empty, the refund is made for the entire cart.
Note
If you use the refundCart field, specify the externalOperationId value. It's used as the idempotency key to prevent the risk of repeat refunds.
Refund examples
Let's take an example of an order with the orderId = Order-123 and the following cart:
{
"items": [
{
"productId": "id-1",
"price": "50",
"title": "Ballpoint pen",
"quantity": {
"count": "10"
}
},
{
"productId": "id-2",
"price": "200",
"title": "Notepad",
"quantity": {
"count": "2"
}
}
]
}
Full refund
http POST https://sandbox.pay.yandex.uz/api/merchant/v2/orders/Order-123/refund \
"Authorization: Api-Key ${API_KEY}" 'refundAmount:="900.00"'
Partial refund
Returning a number of items
Suppose that two ballpoint pens need to be refunded. This is done using the following request:
http POST https://sandbox.pay.yandex.uz/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"'
In this example:
- The number of ballpoint pens decreases by two — from 10 to 8 units.
- The
pricefield is skipped in the request but can be specified if needed. quantityCountof the notepad item remains unchanged and could be omitted.
Refunding part of the amount
Let's say a refund of som 30 is required for each notepad. This is achieved by reducing the item price.
http POST https://sandbox.pay.yandex.uz/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"'
In this example:
- The notepad price decreases by 30 som — from 200 to 170 som.
- As a result, 60 som is refunded because there were two notepads.
- The
quantityCountvalues are not specified but can be included with their original values.
Refund with the number of items to return specified
Suppose that two ballpoint pens need to be refunded. This is done using the following request:
http POST https://sandbox.pay.yandex.uz/api/merchant/v2/orders/Order-123/refund \
"Authorization: Api-Key ${API_KEY}" \
'refundCart[items][0]:={"productId": "id-1", "quantityCount": "2"}' \
'refundAmount:="100.00"'
In this example:
- The number of ballpoint pens decreases by two — from 10 to 8 units.
- The
pricefield is omitted in the request but can be specified if needed.
Refund specifying the portion of the item price to refund
Let's say a refund of som 30 is required for each notepad. This is achieved by reducing the item price.
http POST https://sandbox.pay.yandex.uz/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"'
In this example:
- The notepad price decreases by 30 — from 200 som to 170 som.
- As a result, 60 som is refunded because there were two notepads.
- The
quantityCountvalues are not specified but can be included with their original values.
Request
POST
https://pay.yandex.uz/api/merchant/v2/orders/{order_id}/refund
Production
POST
https://sandbox.pay.yandex.uz/api/merchant/v2/orders/{order_id}/refund
Sandbox
Path parameters
|
Name |
Description |
|
order_id |
Type: string Order ID on the merchant's side that was passed in the Max length: Example: `` |
Body
application/json
{
"branchId": "example",
"externalOperationId": "example",
"managerId": "example",
"motive": "example",
"refundAmount": "123.45",
"refundCart": {
"items": [
{
"price": "123.45",
"productId": "example",
"quantityCount": "123.45"
}
]
},
"targetCart": {
"items": [
{
"price": "123.45",
"productId": "example",
"quantityCount": "123.45"
}
]
},
"targetShipping": {
"amount": "123.45"
}
}
|
Name |
Description |
||||||||
|
refundAmount |
Type: string<double> Refund amount. Example: |
||||||||
|
branchId |
Type: string ID of the point of sale Max length: Example: |
||||||||
|
externalOperationId |
Type: string Refund operation ID in the merchant system. Make sure it's unique. Pass this parameter to track the refund operation status via the operations/{external_operation_id} method. If the operation is not completed (is either in progress or stopped), repeated refund requests with the same arguments and If the refund process is launched successfully, calling the refund method with the same Max length: Example: |
||||||||
|
managerId |
Type: string Manager ID Max length: Example: |
||||||||
|
motive |
Type: string Refund reason Max length: Example: |
||||||||
|
refundCart |
All of 1 type
Specifies the cart items to be refunded.
Can't be specified concurrently with the Example
|
||||||||
|
targetCart |
All of 1 type
Shows the final cart status after the refund.
If the field is omitted, it's considered that the cart is refunded in full. Can't be specified concurrently with the Example
|
||||||||
|
targetShipping |
All of 1 type
Applicable to Yandex Pay Checkout only. In all other cases, leave the field empty. Shows the final delivery status after the refund.
If the field is omitted or is Example
|
Responses
200 OK
Body
application/json
{
"code": 200,
"data": {
"operation": {
"amount": "123.45",
"created": "2025-01-01T00:00:00Z",
"externalOperationId": "example",
"operationId": "123e4567-e89b-12d3-a456-426614174000",
"operationType": "AUTHORIZE",
"orderId": "example",
"params": {},
"pointsAmount": "123.45",
"reason": "example",
"status": "PENDING",
"updated": "2025-01-01T00:00:00Z"
}
},
"status": "success"
}
|
Name |
Description |
||||||||||||||||||||||||
|
code |
Type: unknown Default: |
||||||||||||||||||||||||
|
data |
Type: object
Example
|
||||||||||||||||||||||||
|
status |
Type: string Default: Const: |