# CloudPayments API: Двухстадийная оплата: заблокировать и списать позже

Сценарий из mcp-everything. Актуально на 2026-10-24.

Деньги замораживаются при заказе и списываются после сборки — или возвращаются на карту, если товара нет.

1. Проведи авторизацию вместо списания: POST /payments/cards/auth с теми же параметрами, что и одностадийная оплата. Деньги заблокируются на карте.
2. Когда заказ собран, подтверди списание: POST /payments/confirm с TransactionId и Amount. Сумма может быть меньше заблокированной — например, если часть товара закончилась.
3. Если заказ отменён, сними блокировку: POST /payments/void с TransactionId.
4. Для оплат по сохранённой карте в двухстадийной схеме — /payments/tokens/auth, подтверждение тем же /payments/confirm.

```bash
# Подтвердить списание (сумма — не больше заблокированной)
curl -X POST https://api.cloudpayments.ru/payments/confirm \
  -u '<Public ID>:<API Secret>' \
  -H 'Content-Type: application/json' \
  -d '{"TransactionId": 455, "Amount": 65.98}'

# Или отменить блокировку
curl -X POST https://api.cloudpayments.ru/payments/void \
  -u '<Public ID>:<API Secret>' \
  -H 'Content-Type: application/json' \
  -d '{"TransactionId": 455}'
```

## Базовые URL

- Боевой: `https://api.cloudpayments.ru`

## Авторизация

Тип: Basic Auth

HTTP Basic Auth: логин — Public ID, пароль — API Secret. Оба значения есть в личном кабинете. Без заголовка авторизации или с неверными данными API возвращает HTTP 401 Unauthorized. API Secret нужно хранить в защищённом месте.

Параметры передаются методом POST в теле запроса: `application/x-www-form-urlencoded` («ключ=значение») или `application/json`. Ответ всегда JSON и содержит как минимум `Success` и `Message`.

```
{ "Success": false, "Message": "Invalid Amount value" }
```

## Методы сценария

### POST /payments/cards/auth — Оплата по криптограмме (двухстадийная)

Те же параметры и ответы, что у `/payments/cards/charge`. Деньги блокируются и списываются только после вызова `/payments/confirm`.

### POST /payments/tokens/auth — Оплата по токену (двухстадийная)

Те же параметры, что у `/payments/tokens/charge`; требует последующего подтверждения через `/payments/confirm`.

### POST /payments/confirm — Подтверждение оплаты

Подтверждение платежа, проведённого по двухстадийной схеме.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `TransactionId` | body | Long | да | Номер транзакции в системе |
| `Amount` | body | Number | да | Сумма подтверждения в валюте транзакции |
| `JsonData` | body | Json | нет | Данные транзакции, в том числе для онлайн-чека |

Пример запроса:

```
{"TransactionId":455,"Amount":65.98}
```

Пример ответа:

```json
{"Success":true,"Message":null}
```

### POST /payments/void — Отмена оплаты

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `TransactionId` | body | Long | да | Номер транзакции в системе |

Пример запроса:

```
{"TransactionId":455}
```

Пример ответа:

```json
{"Success":true,"Message":null}
```

## Нюансы

- `Success` в ответе показывает только успешность запроса, а не статус транзакции. Статус транзакции смотрят в поле `Model.Status` или в уведомлениях.
- Идемпотентность включается заголовком `X-Request-ID` с уникальным значением; результат хранится 1 час, новый запрос требует нового значения.
- Если в целочисленное поле передать дробное число, ошибки не будет: значение математически округлится.
- Токен работает только на том терминале (publicId), где был получен.
- Финальный статус оплаты по токену СБП приходит только в Pay- и Fail-уведомлениях, а не в ответе на запрос.
- Для ТСП с MCC 4814 обязателен телефон плательщика в `Payer.Phone` (только цифры, например `+71234567890`), иначе банки отклоняют операции.
- Pay, Fail, Recurrent, Cancel, Confirm, Refund-уведомления повторяются до 100 раз (интервалы 1, 2, 5, 10, 30 минут), если сервер магазина недоступен или ответил кодом, отличным от нуля; таймаут ответа — 30 секунд.
- Подлинность уведомлений проверяют по заголовкам `X-Content-HMAC` и `Content-HMAC`: HMAC-SHA256 от тела запроса (для GET — от строки параметров) в UTF-8, ключ — API Secret, результат в base64.
- Уведомления приходят с адресов 185.98.81.0/28, 87.251.91.160/27, 46.46.175.96/27, 46.46.168.160/27, 162.55.174.97/32, 91.216.178.243/32.
- Ответ на Check-уведомление: `{"code":0}` — принять платёж; коды 10, 11, 12, 13, 20 отклоняют его (неверный InvoiceId, AccountId, сумма, платёж не принят, просрочен).

## Другие сценарии

- [Принять оплату картой на сайте](https://mcp-everything.ru/integrations/cloudpayments/scenarios/prinyat-oplatu-kartoy-na-sayte.md)
- [Подписка и списания по сохранённой карте](https://mcp-everything.ru/integrations/cloudpayments/scenarios/podpiska-i-spisaniya-po-sohranennoy.md)
- [Вернуть деньги покупателю](https://mcp-everything.ru/integrations/cloudpayments/scenarios/vernut-dengi-pokupatelyu.md)
- [Выставить счёт ссылкой на оплату](https://mcp-everything.ru/integrations/cloudpayments/scenarios/vystavit-schet-ssylkoy-na-oplatu.md)
- [Принимать уведомления об оплате и сверять платежи](https://mcp-everything.ru/integrations/cloudpayments/scenarios/prinimat-uvedomleniya-ob-oplate.md)

---

Если этого недостаточно — официальная документация: https://developers.cloudpayments.ru/#api
Вся интеграция одним документом: https://mcp-everything.ru/integrations/cloudpayments.md
