Внешние оплаты (сертификаты, подарочные карты, баллы)
Яндекс Пэй позволяет учитывать внешние способы оплаты, которые вы распространяете самостоятельно и которые применяются ко всей корзине, а не к отдельным товарам. Например, сертификаты, подарочные карты, баллы лояльности и купоны.
Зачем это нужно
Поддержка параметров для внешних оплат позволит вам:
- отразить честную корзину — показать покупателю реальную стоимость товаров и размер внешней оплаты;
- избежать ошибок валидации — предотвратить ошибку
Cart total amount mismatchпри несоответствии суммы корзины; - корректно работать с возвратами — правильно распределить возврат между Яндекс Пэй и внешними средствами.
Как подключить
Чтобы получить доступ, интегрируйтесь с Яндекс Пэй через API. Внешние оплаты не работают в готовых модулях.
После подключения вам станут доступны параметры externalAmount и refundExternalAmount, рассмотрим их далее.
Как это работает
Важно
Внешние оплаты нужны только для корректной валидации корзины. Они не участвуют в процессинге и не фискализируются на стороне Яндекс Пэй.
Вам нужно самостоятельно реализовать логику работы с внешними оплатами. Например, возвращать их покупателю сертификатом, баллами и т. д.
Для работы с внешними оплатами используются параметры:
-
externalAmount— показывает, какая сумма будет оплачена внешними средствами. Указывается вcart.totalпри создании заказа методом /orders и в двухстадийных платежах при списании средств методом /capture. -
refundExternalAmount— показывает, какую сумму внешних средств вы вернули покупателю. Указывается при возврате методом /refund.
Настройте бэкенд и фронтенд своего магазина по следующим примерам:
Создание заказа с внешней оплатой
При создании заказа методом /orders используйте параметр cart.total.externalAmount, чтобы указать сумму внешней оплаты.
|
|
Тип: Сумма внешней оплаты (сертификаты, подарочные карты, баллы лояльности). Может быть не указана, равна 0 или больше 0. Ограничения:
Пример: |
Пример
Рассмотрим на примере заказа из трех товаров на сумму 1000 рублей. Внешняя оплата составляет 300 рублей, оплата через Яндекс Пэй — 700 рублей.
{
"orderId": "order-123",
"currencyCode": "RUB",
"availablePaymentMethods": ["CARD", "SPLIT"],
"cart": {
"total": {
"amount": "700",
"externalAmount": "300"
},
"items": [
{
"productId": "p1",
"title": "Товар 1",
"quantity": { "count": "1" },
"total": "200"
},
{
"productId": "p2",
"title": "Товар 2",
"quantity": { "count": "1" },
"total": "400"
},
{
"productId": "p3",
"title": "Товар 3",
"quantity": { "count": "1" },
"total": "400"
}
]
}
}
Логика валидации:
- Сумма всех
itemsв корзине: 200 + 400 + 400 = 1000. - Сумма
amount+externalAmount: 700 + 300 = 1000.
Корзина собрана корректно.
Как это выглядит для покупателя
В корзине до и после оплаты сумма внешней оплаты externalAmount отображается как Скидка магазина:

Итоговая сумма к оплате равна amount — именно столько покупатель оплатит через Яндекс Пэй. От этой суммы рассчитываются баллы Плюса.
Возможные ошибки
ORDER_AMOUNT_MISMATCH
Ошибка возникает, если сумма amount + externalAmount не равна сумме всех items в корзине.
Пример невалидной корзины:
{
"cart": {
"total": {
"amount": "700",
"externalAmount": "200" // должно быть 300
},
"items": [
{
"productId": "p1",
"total": "200"
},
{
"productId": "p2",
"total": "400"
},
{
"productId": "p3",
"total": "400"
}
]
}
}
Пример ошибки:
{
"status": "fail",
"reasonCode": "ORDER_AMOUNT_MISMATCH",
"reason": "Cart total amount mismatch: expected `cart_total` = `items_sum` - `discounts_sum`, but found 900 != 1000 - 0.00",
"details": {
"cart_total": "900",
"items_sum": "1000",
"discounts_sum": "0.00"
}
}
ORDER_ZERO_AMOUNT
Ошибка возникает при попытке создать заказ с amount: "0" (полная оплата внешними средствами).
Пример невалидной корзины:
{
"cart": {
"total": {
"amount": "0",
"externalAmount": "1000"
},
"items": [
{
"productId": "p1",
"total": "1000"
}
]
}
}
Пример ошибки:
{
"status": "fail",
"reasonCode": "ORDER_ZERO_AMOUNT"
}
Возврат с внешней оплатой
При возврате товаров методом /refund используйте параметр refundExternalAmount, чтобы указать сумму внешней оплаты, которую вы вернули покупателю.
|
|
Тип: Сумма внешней оплаты, которую вы вернули покупателю (сертификаты, подарочные карты, баллы лояльности). Может быть не указана, равна 0 или больше 0. Ограничение: Не должна превышать значение Пример: |
Важно
Если amount достигнет 0 в результате возврата, заказ перейдет в статус REFUNDED и дальнейшие возвраты станут невозможны.
Поэтому в первую очередь возвращайте внешнюю оплату refundExternalAmount, а затем основную сумму refundAmount.
Несколько частичных возвратов до полного возврата
Рассмотрим на примере заказа из трех товаров на сумму 1000 рублей. Внешняя оплата составляет 300 рублей, оплата через Яндекс Пэй — 700 рублей.
{
"cart": {
"total": {
"amount": "700",
"externalAmount": "300"
},
"items": [
{
"productId": "p1",
"title": "Товар 1",
"quantity": { "count": "1" },
"total": "200"
},
{
"productId": "p2",
"title": "Товар 2",
"quantity": { "count": "1" },
"total": "400"
},
{
"productId": "p3",
"title": "Товар 3",
"quantity": { "count": "1" },
"total": "400"
}
]
}
}
Чтобы вернуть Товар 2 и Товар 3 на сумму 800 рублей, используйте следующий запрос:
{
"externalOperationId": "Order-123_refund_1",
"refundAmount": "500",
"refundExternalAmount": "300",
"refundCart": {
"items": [
{
"productId": "p2",
"quantityCount": "1"
},
{
"productId": "p3",
"quantityCount": "1"
}
]
}
}
Результат:
- Вы возвращаете пользователю 300 рублей сертификатом или другим способом.
- Через Яндекс Пэй возвращено 500 рублей.
- Осталось в заказе:
Товар 1на сумму 200 рублей.
|
До возврата |
После возврата |
|
|
Можно вызвать еще один возврат без refundExternalAmount:
{
"externalOperationId": "Order-123_refund_2",
"refundAmount": "200",
"refundCart": {
"items": [
{
"productId": "p1",
"quantityCount": "1"
}
]
}
}
Результат: корзина пустая, возвращена вся сумма, заказ перешел в статус REFUNDED.
|
До возврата |
После возврата |
|
|
Частичный возврат без refundExternalAmount
Рассмотрим на примере заказа из трех товаров на сумму 1000 рублей. Внешняя оплата составляет 300 рублей, оплата через Яндекс Пэй — 700 рублей.
{
"cart": {
"total": {
"amount": "700",
"externalAmount": "300"
},
"items": [
{
"productId": "p1",
"title": "Товар 1",
"quantity": { "count": "1" },
"total": "200"
},
{
"productId": "p2",
"title": "Товар 2",
"quantity": { "count": "1" },
"total": "400"
},
{
"productId": "p3",
"title": "Товар 3",
"quantity": { "count": "1" },
"total": "400"
}
]
}
}
Чтобы вернуть Товар 1 и Товар 2 без возврата внешней оплаты, используйте следующий запрос:
{
"externalOperationId": "Order-123_refund_no_external",
"refundAmount": "600",
"refundExternalAmount": "0",
"refundCart": {
"items": [
{
"productId": "p1",
"quantityCount": "1"
},
{
"productId": "p2",
"quantityCount": "1"
}
]
}
}
Результат:
- Через Яндекс Пэй возвращено 600 рублей.
- Осталось в заказе:
Товар 3на сумму 400 рублей, из них 100 рублей через Яндекс Пэй и 300 рублей внешней оплаты.
|
До возврата |
После возврата |
|
|
Возможные ошибки
Заказ рано перешел в статус REFUNDED
Если amount достигнет 0 в результате возврата, заказ перейдет в статус REFUNDED и дальнейшие возвраты станут невозможны.
Пример: вернули 100 рублей от стоимости Товара 3:
{
"refundAmount": "100",
"refundExternalAmount": "0",
"refundCart": {
"items": [
{
"productId": "p3",
"price": "100"
}
]
}
}
Результат: после возврата amount стал равен 0. Заказ перешел в статус REFUNDED. Больше нельзя возвращать товары, даже если осталась внешняя оплата.
Чтобы избежать таких ситуаций, в первую очередь возвращайте внешнюю оплату.
|
До возврата |
После возврата |
|
|
REFUND_AMOUNT_TOO_LARGE
Ошибка возникает, если refundAmount больше, чем было оплачено через Яндекс Пэй.
Рассмотрим на корзине:
{
"cart": {
"total": {
"amount": "700",
"externalAmount": "300"
},
"items": [
{
"productId": "p1",
"title": "Товар 1",
"quantity": { "count": "1" },
"total": "1000"
}
]
}
}
Пример невалидного запроса:
{
"externalOperationId": "Order-123_refund_full",
"refundAmount": "1000.00"
}
Пример ошибки:
{
"status": "fail",
"reasonCode": "REFUND_AMOUNT_TOO_LARGE",
"details": {
"requested_amount": "1000.00",
"max_amount": "700.00"
}
}
Пример валидного запроса:
Укажите оба параметра так, чтобы сумма refundAmount + refundExternalAmount была равна orderAmount из ответа /orders/{order_id}. Корзину можно не указывать.
{
"externalOperationId": "Order-123_refund_full",
"refundAmount": "700.00",
"refundExternalAmount": "300"
}
Результат: возвращена вся сумма заказа (1000 рублей), корзина пустая, заказ перешел в статус REFUNDED.
Двухстадийные платежи с внешней оплатой
Если вы используете двухстадийные платежи укажите cart.total.externalAmount дважды:
- При создании заказа методом /orders — чтобы захолдировать внешнюю оплату.
- При списании методом /capture — чтобы списать нужную сумму внешней оплаты.
|
|
Тип: Сумма внешней оплаты (сертификаты, подарочные карты, баллы лояльности). Может быть не указана, равна 0 или больше 0. Ограничения:
Пример: |
Примечание
При частичном списании средств вы должны самостоятельно вернуть покупателю остаток externalAmount.
Пример частичного списания (клира)
Рассмотрим на примере заказа из трех товаров на сумму 1000 рублей. Внешняя оплата составляет 300 рублей, оплата через Яндекс Пэй — 700 рублей.
Шаг 1. Создание заказа
При создании заказа укажите cart.total.externalAmount, чтобы захолдировать внешнюю оплату:
{
"orderId": "order-123",
"currencyCode": "RUB",
"availablePaymentMethods": ["CARD"],
"cart": {
"total": {
"amount": "700",
"externalAmount": "300"
},
"items": [
{
"productId": "p1",
"title": "Товар 1",
"quantity": { "count": "1" },
"total": "200"
},
{
"productId": "p2",
"title": "Товар 2",
"quantity": { "count": "1" },
"total": "400"
},
{
"productId": "p3",
"title": "Товар 3",
"quantity": { "count": "1" },
"total": "400"
}
]
}
}
Шаг 2. Списание средств (клир)
Рассмотрим частичное списание средств с уменьшением корзины.
Когда заказ перешел в статус AUTHORIZED, выполните частичное списание для Товара 1 и Товара 2 на сумму 600 рублей. Укажите cart.total.externalAmount, чтобы списать нужную сумму внешней оплаты:
{
"externalOperationId": "Order-123_capture_1",
"cart": {
"total": {
"amount": "400",
"externalAmount": "200"
},
"items": [
{
"productId": "p1",
"title": "Товар 1",
"quantity": { "count": "1" },
"total": "200"
},
{
"productId": "p2",
"title": "Товар 2",
"quantity": { "count": "1" },
"total": "400"
}
]
}
}
Результат:
- Захолдировано через Яндекс Пэй: 700 рублей. Списано: 400 рублей.
- Захолдировано внешней оплаты: 300 рублей. Списано: 200 рублей.
- Вы должны самостоятельно вернуть покупателю остаток внешней оплаты: 100 рублей.