# Robokassa API: Повторные платежи по подписке

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

Списывать деньги регулярно без участия покупателя после первой оплаты.

1. Первую (материнскую) оплату проведи как обычно через GET /Merchant/Index.aspx, добавив Recurring=true. Покупатель соглашается на повторные списания.
2. Для каждого следующего списания вызови POST /Merchant/Recurring с MerchantLogin, InvoiceID (новый номер операции), PreviousInvoiceID (номер оплаченной материнской операции), OutSum и подписью MerchantLogin:OutSum:InvoiceID:Пароль#1. PreviousInvoiceID в подпись не входит.
3. Ответ вида OK156 значит, что запрос принят; итог списания придёт уведомлением на ResultURL, как у обычной оплаты.
4. Повторные платежи работают только в боевом режиме.

```bash
SIG=$(printf '%s' 'demo-shop:399.00:2001:<Пароль#1>' | md5sum | cut -d' ' -f1)
curl -X POST https://auth.robokassa.ru/Merchant/Recurring \
  -d MerchantLogin=demo-shop -d InvoiceID=2001 -d PreviousInvoiceID=1042 \
  -d OutSum=399.00 --data-urlencode 'Description=Подписка, ноябрь' -d SignatureValue=$SIG
```

## Базовые URL

- Боевой (оплата, XML-интерфейсы, холдирование, рекурренты): `https://auth.robokassa.ru`
- Боевой (счета, возвраты, фискализация): `https://services.robokassa.ru`

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

Тип: Другое

Стандартной схемы авторизации нет: каждый запрос подписывается контрольной суммой, состав которой зависит от метода. В личном кабинете магазина берутся `MerchantLogin`, Пароль#1, Пароль#2 (и Password3 для API возвратов), там же выбирается алгоритм хэша (в примерах документации — MD5). Пароль#1 используется для подписи запросов на оплату, Пароль#2 — для проверки уведомлений и XML-интерфейсов. Invoice API и Refund API принимают тело в виде JWT, подписанного HMAC.

Подпись запуска оплаты: `MerchantLogin:OutSum:InvId:модификаторы:Пароль#1:Shp_*`. Пример из документации (PHP, MD5):

```
$signature = md5("$merchantLogin:$outSum:$invId:$password1");
```

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

### GET /Merchant/Index.aspx — Открыть платежную страницу

Создаёт операцию оплаты и открывает платёжную страницу. Тот же набор параметров можно отправить POST-формой (`application/x-www-form-urlencoded`). Для теста передайте `IsTest=1`. Ответ — HTML платёжной формы или 302 с адресом платёжной страницы; он не подтверждает оплату.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `MerchantLogin` | query | string | да | Идентификатор магазина |
| `OutSum` | query | string | да | Сумма к оплате, десятичный разделитель — точка |
| `SignatureValue` | query | string | да | Подпись запроса с Паролем#1 |
| `InvId` | query | integer | нет | Уникальный номер счёта; при 0 или отсутствии назначается автоматически |
| `Description` | query | string | нет | Название товара или услуги без спецсимволов |
| `Email` | query | string | нет | Email покупателя для чеков и уведомлений |
| `IncCurrLabel` | query | string | нет | Предлагаемый способ оплаты из GetCurrencies |
| `Culture` | query | string | нет | Язык платёжной страницы: ru, en |
| `Encoding` | query | string | нет | Кодировка данных |
| `IsTest` | query | integer | нет | Тестовый режим: 0, 1 |
| `ExpirationDate` | query | string | нет | Крайний срок оплаты, YYYY-MM-DDThh:mm |
| `Receipt` | query | string | нет | Фискальные данные — минимизированный JSON в URL-кодировке |
| `IsWithoutFreeSale` | query | boolean | нет | Не формировать автоматический чек «Свободная продажа» без Receipt |
| `StepByStep` | query | boolean | нет | Двухстадийная оплата (холдирование) |
| `PaymentMethods` | query | array | нет | Разрешённые способы оплаты, параметр можно повторять |
| `ResultUrl2` | query | string | нет | Дополнительный адрес серверного уведомления |
| `SuccessUrl2` | query | string | нет | Дополнительный адрес возврата после успешной оплаты |
| `FailUrl2` | query | string | нет | Дополнительный адрес возврата после ошибки |
| `Token` | query | string | нет | Токен сохранённой карты |
| `Recurring` | query | boolean | нет | Признак периодического платежа |

### POST /Merchant/Recurring — Повторный платёж

Дочерний платёж после успешной материнской операции с `Recurring=true`; списывает деньги без участия покупателя. `PreviousInvoiceID` в подпись не входит. Только основной режим.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `MerchantLogin` | body | string | да | Идентификатор магазина |
| `InvoiceID` | body | integer | да | Номер новой (дочерней) операции |
| `PreviousInvoiceID` | body | integer | да | Номер оплаченной материнской операции |
| `OutSum` | body | string | да | Сумма |
| `Description` | body | string | нет | Описание |
| `Receipt` | body | string | нет | JSON чека в URL-кодировке |
| `SignatureValue` | body | string | да | Подпись с Паролем#1 |

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

```json
OK156
```

## Нюансы

- После оплаты Robokassa отправляет на ResultURL поля `OutSum`, `InvId`, `Fee`, `EMail`, `SignatureValue`, `PaymentMethod`, `IncCurrLabel` и параметры `Shp_*`. Подпись проверяют по формуле `OutSum:InvId:Пароль#2:Shp_*` и только потом меняют статус заказа.
- Обработчик ResultURL должен ответить строкой `OK` + номер заказа (например `OK12`), иначе уведомление считается недоставленным.
- Пользовательские параметры с префиксом `Shp_` возвращаются в уведомлениях без изменений и включаются в подпись в алфавитном порядке.
- При холдировании (`StepByStep=true`) в строку подписи добавляется модификатор `true`: `MerchantLogin:OutSum:InvId:true:Пароль#1`.
- Сумму передают с точностью до двух знаков после запятой, все данные — в UTF-8.
- Ошибка подписи обычно означает неверный порядок параметров или неверный пароль.
- XML-интерфейсы и Invoice API возвращают HTTP 200 и при прикладных ошибках; результат смотрят в `Result.Code` или `isSuccess`.
- OpStateExt, холдирование, рекурренты и возвраты не работают в тестовом режиме.
- У Robokassa есть публичный MCP-сервер для ИИ-ассистентов: https://mcp.robokassa.ru/

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

- [Принять оплату через платёжную страницу](https://mcp-everything.ru/integrations/robokassa/scenarios/prinyat-oplatu-cherez-platezhnuyu.md)
- [Проверить, оплачен ли заказ](https://mcp-everything.ru/integrations/robokassa/scenarios/proverit-oplachen-li-zakaz.md)
- [Двухстадийная оплата: заблокировать и списать позже](https://mcp-everything.ru/integrations/robokassa/scenarios/dvuhstadiynaya-oplata-zablokirovat.md)
- [Выставить счёт ссылкой и вернуть деньги](https://mcp-everything.ru/integrations/robokassa/scenarios/vystavit-schet-ssylkoy-i-vernut-dengi.md)

---

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