Возвраты
Вернуть покупателю деньги за оплаченный платёж можно через API или в личном кабинете. Можно вернуть всю сумму или часть. Деньги вернутся тем же способом, которым покупатель платил.
Все поля и ошибки — в справочнике: Создать возврат, Объект возврата.
Перед первым возвратом
- Попросите поддержку включить ключу право «Возвраты»: напишите на [email protected]. По умолчанию право выключено, и запрос на возврат получит ответ 403
forbidden. Если возвраты нужно разрешить только с IP-адресов ваших серверов, укажите их в письме. - Если хотите получать уведомления о возвратах, включите событие «Возврат выполнен» (
refund.succeeded) в Ещё → Разработчикам → HTTP-уведомления.
Как сделать возврат
-
Запросите платёж:
GET /v3/payments/{payment_id}. Вернуть его можно, еслиrefundableравенtrue. -
Создайте ключ идемпотентности для этого возврата и сохраните его у себя до запроса. Например, номер заказа и номер возврата по нему:
refund-123-1. -
Отправьте запрос
POST /v3/refundsсidплатежа и суммой. Свой номер возврата передайте вmetadata.refund_number: по нему вы найдёте возврат в списке и в уведомлении, если ответ на создание не дошёл.curl https://api.avantpay.io/v3/ \refunds
-X POST \
-u "$AVANTPAY_SHOP_ID:$AVANTPAY_SECRET_KEY" \
-H "Idempotence-Key: refund-123-1" \
-H "Content-Type: application/json" \
-d '{
"payment_id": "2f9b6c1e-4d7a-4c3b-9e8f-1a2b3c4d5e6f",
"amount": {
"value": "300.00",
"currency": "RUB"
},
"description": "Возврат по заказу №123",
"metadata": {
"order_id": "123",
"refund_number": "123-1"
}
}' -
В ответе — объект возврата со статусом
pending. Сохраните егоid. Возврат принят, но ещё не выполнен. Если это был повтор с тем же ключом, статус может быть ужеsucceededилиcanceled: обрабатывайте любой статус из ответа. -
Дождитесь уведомления
refund.succeededили запрашивайте возвратGET /v3/refunds/{refund_id}раз в несколько минут, пока статусpending. Обычно итог — через несколько секунд или минут.
Статус возврата
status | Что значит | Что делать |
|---|---|---|
pending | Возврат выполняется. Покупатель ещё не получил деньги. | Ждать. Новый возврат по этому платежу не создавать. Дольше часа — написать в поддержку. |
succeeded | Деньги вернули покупателю. | Отметить в заказе, что деньги вернули. |
canceled | Возврат не выполнен, сумма осталась на счёте магазина или вернулась на него. | Посмотреть причину — в разделе Если возврат отменён. |
Ответ на запрос, который создал возврат, — всегда pending. Повтор с тем же ключом вернёт тот же возврат в текущем статусе. Статусы succeeded и canceled у возврата больше не меняются. Статус платежа после возврата остаётся succeeded, а сколько уже вернули — в поле refunded_amount платежа.
Если возврат в pending дольше часа, напишите в поддержку: [email protected], укажите id возврата. Не считайте его отменённым и не создавайте новый: API не примет новый возврат по этому платежу, пока этот не завершится.
Частичный возврат
- Передайте в
amount.valueсумму меньше суммы платежа. - По платежу одновременно выполняется только один возврат. Следующий создавайте, когда прежний стал
succeededилиcanceled, — с новым ключом идемпотентности. Пока прежний в статусеpending, API ответит 400. - Всего можно вернуть не больше суммы платежа и не больше чем 10 возвратами. Отменённые возвраты не считаются.
- Минимальная сумма возврата — 1 ₽. Меньше можно вернуть, только если это весь остаток платежа.
Если сумма больше остатка, API ответит 400 и назовёт остаток:
{
"type": "error",
"id": "6b2d9e4f-1c3a-4e5b-8d7f-0a9b8c7d6e5f",
"code": "invalid_request",
"description": "Refund amount exceeds the amount available for refund: 700.00 RUB",
"parameter": "amount.value"
}
Если возврат отменён
Уведомления об отмене возврата нет: отмену видно только в ответе на GET /v3/refunds/{refund_id}. Покупатель денег не получил. Причина — в cancellation_details:
"party": "avantpay"и"reason": "insufficient_funds"— на счёте магазина не хватило денег, сумма осталась на счёте. Дождитесь, когда на счёте будет нужная сумма, и создайте новый возврат с новым ключом идемпотентности. Остаток счёта виден в личном кабинете на странице «Обзор», через API его не узнать."party": "refund_network"— возврат отклонил банк или платёжная система. Сумма вернётся на счёт магазина, но до 3 дней может быть в резерве. Напишите в поддержку: [email protected], укажитеidвозврата.- Другие значения — напишите в поддержку: [email protected], укажите
idвозврата.
Все значения — в разделе Кто отменил возврат.
Деньги
- Со счёта магазина списывается вся сумма возврата. Комиссия AvantPay за платёж не возвращается.
- Если на счёте не хватает денег, API всё равно примет возврат, а потом возврат перейдёт в
canceledс причинойinsufficient_funds.
Ключ идемпотентности
- Один возврат — один ключ. Создайте ключ, когда решили вернуть деньги, и сохраните его до запроса.
- Нет ответа, таймаут, ответ 500 или 429 — повторите запрос с тем же ключом и тем же телом. Придёт тот же возврат, второго не будет.
- Если это повтор после таймаута или ответа 500 и пришла ошибка 400, 401 или 403, возврат мог создаться первым запросом. Ключ не меняйте: исправьте причину и повторите запрос с тем же ключом. Ошибка ключ не занимает: повтор вернёт уже созданный возврат или создаст его сейчас. Или найдите возврат в списке возвратов по платежу по вашему
metadata.refund_number. Новый ключ — только если там этого возврата нет. - Новый ключ — только для нового возврата. Если повторить запрос с новым ключом, покупатель может получить деньги дважды.
- Тот же ключ с другим телом или позже чем через 24 часа — ошибка 400 с
"parameter": "Idempotence-Key". Это значит, что возврат с этим ключом уже создан: найдите его в списке возвратов по платежу и не создавайте новый.
Подробнее — в разделе Идемпотентность.
Частые ошибки
| Ответ | Что не так |
|---|---|
400, "parameter": "payment_id" | Платёж нельзя вернуть сейчас: он не оплачен, уже возвращён полностью, по нему выполняется другой возврат или по нему уже 10 возвратов. В коде не разбирайте description: покажите его сотруднику или запишите в лог. Причину определяйте по платежу — как. |
400, "parameter": "amount.value" | Сумма больше остатка, меньше 1 ₽ или в неверном формате. |
400, "parameter": "Idempotence-Key" | Нет ключа или он длиннее 64 символов. Или возврат с этим ключом уже создан, а тело запроса другое или прошло больше 24 часов: найдите возврат в списке возвратов по платежу и не создавайте новый. |
403 forbidden | У ключа нет права «Возвраты» или запрос пришёл с IP-адреса, которого нет в списке ключа. Напишите в поддержку. |
404, "parameter": "payment_id" | Платежа с таким id нет у вашего магазина. |
Все ошибки — в справочнике: Создать возврат.