---
metadata:
  - name: generator
    content: Diplodoc Platform v5.52.0
alternate:
  - https://pay.yandex.ru/docs/ru/custom/external-amount.md
  - href: ru/custom/external-amount.md
    type: text/markdown
    title: Markdown version
  - href: ../llms.txt
    type: text/markdown
    title: llms.txt
title: "Внешние оплаты в Яндекс\_Пэй | Документация"
description: Как учитывать сертификаты, подарочные карты и другие внешние способы оплаты при создании и возврате заказа.
---
> **Documentation Index:** Fetch the complete configuration index at https://pay.yandex.ru/docs/ru/llms.txt


# Внешние оплаты (сертификаты, подарочные карты, баллы)

Яндекс Пэй позволяет учитывать внешние способы оплаты, которые вы распространяете самостоятельно и которые применяются ко всей корзине, а не к отдельным товарам. Например, сертификаты, подарочные карты, баллы лояльности и купоны.

## Зачем это нужно { #why-needed }

Поддержка параметров для внешних оплат позволит вам:

- отразить честную корзину — показать покупателю реальную стоимость товаров и размер внешней оплаты;
- избежать ошибок валидации — предотвратить ошибку `Cart total amount mismatch` при несоответствии суммы корзины;
- корректно работать с возвратами — правильно распределить возврат между Яндекс Пэй и внешними средствами.

## Как подключить { #connection }

Чтобы получить доступ, интегрируйтесь с Яндекс Пэй через API. Внешние оплаты не работают в [готовых модулях](https://pay.yandex.ru/docs/ru/cms/index.md).

После подключения вам станут доступны параметры `externalAmount` и `refundExternalAmount`, рассмотрим их далее.

## Как это работает { #how-it-works }

{% note warning %}

Внешние оплаты нужны только для корректной валидации корзины. Они не участвуют в процессинге и не фискализируются на стороне Яндекс Пэй.

Вам нужно самостоятельно реализовать логику работы с внешними оплатами. Например, возвращать их покупателю сертификатом, баллами и т. д.

{% endnote %}

Для работы с внешними оплатами используются параметры:

- `externalAmount` — показывает, какая сумма будет оплачена внешними средствами. Указывается в `cart.total` при [создании заказа](#create-order) методом [/orders](https://pay.yandex.ru/docs/ru/custom/backend/yandex-pay-api/order/merchant_v1_orders-post.md) и в двухстадийных платежах при [списании средств](#hold) методом [/capture](https://pay.yandex.ru/docs/ru/custom/backend/yandex-pay-api/order/merchant_v1_capture-post.md).

- `refundExternalAmount` — показывает, какую сумму внешних средств вы вернули покупателю. Указывается при [возврате](#refund) методом [/refund](https://pay.yandex.ru/docs/ru/custom/backend/yandex-pay-api/order/merchant_v2_refund-post.md).

Настройте бэкенд и фронтенд своего магазина по следующим примерам:

- [Создание заказа с внешней оплатой](#create-order)
- [Возврат с внешней оплатой](#refund)
- [Двухстадийные платежи](#hold)

## Создание заказа с внешней оплатой { #create-order }

При создании заказа методом [/orders](https://pay.yandex.ru/docs/ru/custom/backend/yandex-pay-api/order/merchant_v1_orders-post.md) используйте параметр `cart.total.externalAmount`, чтобы указать сумму внешней оплаты.

 #|
||

`externalAmount`

|

**Тип:** `string`

Сумма внешней оплаты (сертификаты, подарочные карты, баллы лояльности).

Может быть не указана, равна 0 или больше 0.

**Ограничения:**

- Сумма `amount` + `externalAmount` должна равняться сумме всех `items` в корзине.
- Нельзя создать заказ с `amount: "0"` (полная оплата внешними средствами). Минимальное значение `amount` — 1 рубль.

**Пример:** `"300.00"`

||
|#

### Пример { #create-order-example }

Рассмотрим на примере заказа из трех товаров на сумму 1000 рублей. Внешняя оплата составляет 300 рублей, оплата через Яндекс Пэй — 700 рублей.

```json
{
  "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.

Корзина собрана корректно.

### Как это выглядит для покупателя { #create-order-ui }

В корзине до и после оплаты сумма внешней оплаты `externalAmount` отображается как **Скидка магазина**:

![Отображение внешней оплаты в корзине](./_assets/external-amount-cart.png){.c-screenshot}

Итоговая сумма к оплате равна `amount` — именно столько покупатель оплатит через Яндекс Пэй. От этой суммы рассчитываются баллы Плюса.

### Возможные ошибки { #create-order-errors }

#### ORDER_AMOUNT_MISMATCH { #order-amount-mismatch }

Ошибка возникает, если сумма `amount` + `externalAmount` не равна сумме всех `items` в корзине.

**Пример невалидной корзины:**

```json
{
  "cart": {
    "total": {
      "amount": "700",
      "externalAmount": "200" // должно быть 300
    },
    "items": [
      {
        "productId": "p1",
        "total": "200"
      },
      {
        "productId": "p2",
        "total": "400"
      },
      {
        "productId": "p3",
        "total": "400"
      }
    ]
  }
}
```

**Пример ошибки:**

```json
{
  "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 { #order-zero-amount }

Ошибка возникает при попытке создать заказ с `amount: "0"` (полная оплата внешними средствами).

**Пример невалидной корзины:**

```json
{
  "cart": {
    "total": {
      "amount": "0",
      "externalAmount": "1000"
    },
    "items": [
      {
        "productId": "p1",
        "total": "1000"
      }
    ]
  }
}
```

**Пример ошибки:**

```json
{
  "status": "fail",
  "reasonCode": "ORDER_ZERO_AMOUNT"
}
```

## Возврат с внешней оплатой { #refund }

При возврате товаров методом [/refund](https://pay.yandex.ru/docs/ru/custom/backend/yandex-pay-api/order/merchant_v2_refund-post.md) используйте параметр `refundExternalAmount`, чтобы указать сумму внешней оплаты, которую вы вернули покупателю.

 #|
||

`refundExternalAmount`

|

**Тип:** `string`

Сумма внешней оплаты, которую вы вернули покупателю (сертификаты, подарочные карты, баллы лояльности).

Может быть не указана, равна 0 или больше 0.

**Ограничение:** Не должна превышать значение `externalAmount`, переданное в [/orders](https://pay.yandex.ru/docs/ru/custom/backend/yandex-pay-api/order/merchant_v1_orders-post.md) при создании заказа.

**Пример:** `"300.00"`

||
|#

{% note warning %}

Если `amount` достигнет `0` в результате возврата, заказ перейдет в статус `REFUNDED` и дальнейшие возвраты станут невозможны.

Поэтому в первую очередь возвращайте внешнюю оплату `refundExternalAmount`, а затем основную сумму `refundAmount`.

{% endnote %}

### Несколько частичных возвратов до полного возврата { #refund-partial }

Рассмотрим на примере заказа из трех товаров на сумму 1000 рублей. Внешняя оплата составляет 300 рублей, оплата через Яндекс Пэй — 700 рублей.

```json
{
  "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 рублей, используйте следующий запрос:

```json
{
  "externalOperationId": "Order-123_refund_1",
  "refundAmount": "500",
  "refundExternalAmount": "300",
  "refundCart": {
    "items": [
      {
        "productId": "p2",
        "quantityCount": "1"
      },
      {
        "productId": "p3",
        "quantityCount": "1"
      }
    ]
  }
}
```

**Результат:**

- Вы возвращаете пользователю 300 рублей сертификатом или другим способом.
- Через Яндекс Пэй возвращено 500 рублей.
- Осталось в заказе: `Товар 1` на сумму 200 рублей.

 #|
|| **До возврата** | **После возврата** ||
||

```json
{
  "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"
      }
    ]
  }
}
```

|

```json
{
  "cart": {
    "total": {
      "amount": "200",
      "externalAmount": null
    },
    "items": [
      {
        "productId": "p1",
        "title": "Товар 1",
        "quantity": { "count": "1" },
        "total": "200"
      }
    ]
  }
}
```

||
|#

Можно вызвать еще один возврат без `refundExternalAmount`:

```json
{
  "externalOperationId": "Order-123_refund_2",
  "refundAmount": "200",
  "refundCart": {
    "items": [
      {
        "productId": "p1",
        "quantityCount": "1"
      }
    ]
  }
}
```

**Результат:** корзина пустая, возвращена вся сумма, заказ перешел в статус `REFUNDED`.

 #|
|| **До возврата** | **После возврата** ||
||

```json
{
  "cart": {
    "total": {
      "amount": "200",
      "externalAmount": null
    },
    "items": [
      {
        "productId": "p1",
        "title": "Товар 1",
        "quantity": { "count": "1" },
        "total": "200"
      }
    ]
  }
}
```

|

```json
{
  "cart": {
    "total": {
      "amount": "0",
      "externalAmount": null
    },
    "items": []
  }
}
```

||
|#

### Частичный возврат без refundExternalAmount  {#refund-partial-no-external }

Рассмотрим на примере заказа из трех товаров на сумму 1000 рублей. Внешняя оплата составляет 300 рублей, оплата через Яндекс Пэй — 700 рублей.

```json
{
  "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` без возврата внешней оплаты, используйте следующий запрос:

```json
{
  "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 рублей внешней оплаты.

 #|
|| **До возврата** | **После возврата** ||
||

```json
{
  "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"
      }
    ]
  }
}
```

|

```json
{
  "cart": {
    "total": {
      "amount": "100",
      "externalAmount": "300"
    },
    "items": [
      {
        "productId": "p3",
        "title": "Товар 3",
        "quantity": { "count": "1" },
        "total": "400"
      }
    ]
  }
}
```

||
|#

### Возможные ошибки {#refund-errors}

#### Заказ рано перешел в статус REFUNDED { #early-refunded-status }

Если `amount` достигнет `0` в результате возврата, заказ перейдет в статус `REFUNDED` и дальнейшие возвраты станут невозможны.

**Пример:** вернули 100 рублей от стоимости `Товара 3`:

```json
{
  "refundAmount": "100",
  "refundExternalAmount": "0",
  "refundCart": {
    "items": [
      {
        "productId": "p3",
        "price": "100"
      }
    ]
  }
}
```

**Результат:** после возврата `amount` стал равен `0`. Заказ перешел в статус `REFUNDED`. Больше нельзя возвращать товары, даже если осталась внешняя оплата.

Чтобы избежать таких ситуаций, в первую очередь возвращайте внешнюю оплату.

 #|
|| **До возврата** | **После возврата** ||
||

```json
{
  "cart": {
    "total": {
      "amount": "100",
      "externalAmount": "300"
    },
    "items": [
      {
        "productId": "p3",
        "title": "Товар 3",
        "quantity": { "count": "1" },
        "total": "400"
      }
    ]
  }
}
```

|

```json
{
  "cart": {
    "total": {
      "amount": "0",
      "externalAmount": "300"
    },
    "items": [
      {
        "productId": "p3",
        "title": "Товар 3",
        "total": "400",
        "quantity": { "count": "1" },
        "finalPrice": "300"
      }
    ]
  }
}
```
||
|#

#### REFUND_AMOUNT_TOO_LARGE { #refund-amount-too-large }

Ошибка возникает, если `refundAmount` больше, чем было оплачено через Яндекс Пэй.

Рассмотрим на корзине:

```json
{
  "cart": {
    "total": {
      "amount": "700",
      "externalAmount": "300"
    },
    "items": [
      {
        "productId": "p1",
        "title": "Товар 1",
        "quantity": { "count": "1" },
        "total": "1000"
      }
    ]
  }
}
```

**Пример невалидного запроса:**

```json
{
  "externalOperationId": "Order-123_refund_full",
  "refundAmount": "1000.00"
}
```

**Пример ошибки:**

```json
{
  "status": "fail",
  "reasonCode": "REFUND_AMOUNT_TOO_LARGE",
  "details": {
    "requested_amount": "1000.00",
    "max_amount": "700.00"
  }
}
```

**Пример валидного запроса:**

Укажите оба параметра так, чтобы сумма `refundAmount` + `refundExternalAmount` была равна `orderAmount` из ответа [/orders/{order_id}](merchant_v1_order-get). Корзину можно не указывать.

```json
{
  "externalOperationId": "Order-123_refund_full",
  "refundAmount": "700.00",
  "refundExternalAmount": "300"
}
```

**Результат:** возвращена вся сумма заказа (1000 рублей), корзина пустая, заказ перешел в статус `REFUNDED`.

## Двухстадийные платежи с внешней оплатой { #hold }

Если вы используете [двухстадийные платежи](https://pay.yandex.ru/docs/ru/hold/index.md) укажите `cart.total.externalAmount` дважды:

1. При создании заказа методом [/orders](https://pay.yandex.ru/docs/ru/custom/backend/yandex-pay-api/order/merchant_v1_orders-post.md) — чтобы захолдировать внешнюю оплату.
2. При списании методом [/capture](https://pay.yandex.ru/docs/ru/custom/backend/yandex-pay-api/order/merchant_v1_capture-post.md) — чтобы списать нужную сумму внешней оплаты.

 #|
||

`externalAmount`

|

**Тип:** `string`

Сумма внешней оплаты (сертификаты, подарочные карты, баллы лояльности).

Может быть не указана, равна 0 или больше 0.

**Ограничения:**

- Нельзя создать заказ с `amount: "0"` (полная оплата внешними средствами). Минимальная сумма для оплаты через Яндекс Пэй — 1 рубль.
- Сумма `amount` + `externalAmount` должна равняться сумме всех `items` в корзине.
- При списании методом [/capture](https://pay.yandex.ru/docs/ru/custom/backend/yandex-pay-api/order/merchant_v1_capture-post.md) не должна превышать значение `externalAmount`, переданное в [/orders](https://pay.yandex.ru/docs/ru/custom/backend/yandex-pay-api/order/merchant_v1_orders-post.md) при создании заказа.

**Пример:** `"300.00"`

||
|#

{% note info %}

При частичном списании средств вы должны самостоятельно вернуть покупателю остаток `externalAmount`.

{% endnote %}

### Пример частичного списания (клира) { #hold-example }

Рассмотрим на примере заказа из трех товаров на сумму 1000 рублей. Внешняя оплата составляет 300 рублей, оплата через Яндекс Пэй — 700 рублей.

#### Шаг 1. Создание заказа

При создании заказа укажите `cart.total.externalAmount`, чтобы захолдировать внешнюю оплату:

```json
{
  "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`, чтобы списать нужную сумму внешней оплаты:

```json
{
  "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 рублей.
