# PayKeeper: Выставить счёт и получить ссылку на оплату

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

Ссылка на оплату для клиента — в письмо, мессенджер или на страницу заказа.

1. Все запросы — к адресу твоего сервера PayKeeper с заголовком Authorization: Basic (логин и пароль от личного кабинета в base64). Чтение — GET, изменения — POST в формате application/x-www-form-urlencoded.
2. Получи токен безопасности: GET /info/settings/token/. Он нужен в каждом POST-запросе и меняется раз в сутки.
3. Создай счёт: POST /change/invoice/preview/ с pay_amount, orderid, clientid, client_email, service_name и token. Срок действия счёта задаёт expiry.
4. В ответе invoice_id и invoice_url — ссылка для оплаты. Добавь к ней ?pstype=sbp_default, чтобы сразу показать QR-код СБП.
5. Чтобы PayKeeper сам отправил письмо со счётом, вызови POST /change/invoice/send/ с id счёта.

```bash
PK=https://<твой-сервер>.server.paykeeper.ru
AUTH='<логин>:<пароль>'
TOKEN=$(curl -s -u "$AUTH" "$PK/info/settings/token/" | jq -r .token)

curl -X POST "$PK/change/invoice/preview/" -u "$AUTH" \
  -d pay_amount=1500.00 -d orderid=1042 \
  --data-urlencode 'clientid=Иван Петров' -d client_email=ivan@example.ru \
  --data-urlencode 'service_name=Заказ №1042' \
  -d token=$TOKEN
```

## Базовые URL

- Боевой: `https://<адрес вашего сервера PayKeeper>`

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

Тип: Basic Auth

Каждый запрос отправляется с заголовком `Authorization: Basic` — логин и пароль от личного кабинета PayKeeper в base64. Запросы на чтение выполняются GET, изменения — POST с заголовком `Content-Type: application/x-www-form-urlencoded`. Каждый POST-запрос дополнительно должен содержать параметр `token` — токен безопасности, полученный методом `/info/settings/token/`.

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

### GET /info/settings/token/ — Получить токен безопасности

Токен нужен для всех POST-запросов (защита от CSRF). Меняется раз в 24 часа.

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

```json
{
    "token" : "fd50e47596cff6c63c7ea0a633c0d2a8"
}
```

### POST /change/invoice/preview/ — Подготовка счёта

Создаёт счёт по параметрам оплаты и возвращает его номер, полный URL для оплаты и HTML-предпросмотр письма. Созданный счёт получает служебный статус `created` и не попадает в историю счетов.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `pay_amount` | body | string | да | Сумма заказа к оплате |
| `clientid` | body | string | нет | Идентификатор клиента |
| `orderid` | body | string | нет | Номер заказа |
| `service_name` | body | string | нет | Наименование услуги; можно передать JSON-объект с корзиной cart и доп. атрибутами |
| `client_email` | body | string | нет | E-mail клиента |
| `client_phone` | body | string | нет | Телефон клиента |
| `expiry` | body | string | нет | Срок действия счёта: YYYY-MM-DD или YYYY-MM-DD H:i:s (не включительно) |
| `token` | body | string | да | Токен безопасности |

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

```json
{
  "invoice_id" : "20120229133742255",
  "invoice_url" : "https://pay.example.com/bill/20120229133742255",
  "invoice"    : "&lt;HTML&gt;&lt;HEAD&gt;&lt;META http-equiv=Content-Type ..."
}
```

### POST /change/invoice/send/ — Отправить счёт клиенту

Отправляет клиенту письмо, созданное методом preview.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `id` | body | string | да | Идентификатор созданного счёта |
| `token` | body | string | да | Токен безопасности |

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

```json
{
  "result" : "success"
}
```

## Нюансы

- Параметр `token` обязателен в каждом POST-запросе, хотя в описании методов его часто не упоминают; токен меняется раз в 24 часа.
- В `partial` передавайте именно `true`/`false` — значения 1/0 система не воспринимает.
- Возврат выполняется асинхронно: успешный ответ означает только постановку в очередь. Результат проверяют через `/info/refunds/bypaymentid/` или реестр платежей со статусом `refunding`, обычно через несколько минут.
- При ответе `status = queued` на capture (Промсвязьбанк) запрос лишь принят банком; итог проверяют через несколько минут.
- POST-оповещение о платеже содержит `id`, `sum`, `clientid`, `orderid`, `key` и доп. поля. `key` — md5 от конкатенации id, sum (2 знака после точки), clientid, orderid и секретного слова из личного кабинета.
- На оповещение нужно ответить строкой `OK <md5(id + секретное слово)>`. Без корректного ответа PayKeeper повторяет запрос каждую минуту, по умолчанию до 50 раз, после чего платёж получает статус «Совершён без оповещения».
- Оповещение может прийти несколько раз — обработчик должен защищаться от повторного зачисления по `id` платежа.
- К ссылке счёта можно добавить `?pstype=sbp_default`, чтобы показать QR-код СБП, и `&returnFormat=json`, чтобы получить содержимое QR-кода.

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

- [Принять оповещение об оплате](https://mcp-everything.ru/integrations/paykeeper/scenarios/prinyat-opoveschenie-ob-oplate.md)
- [Вернуть деньги покупателю](https://mcp-everything.ru/integrations/paykeeper/scenarios/vernut-dengi-pokupatelyu.md)
- [Списать заблокированные деньги](https://mcp-everything.ru/integrations/paykeeper/scenarios/spisat-zablokirovannye-dengi.md)
- [Сверить платежи за период](https://mcp-everything.ru/integrations/paykeeper/scenarios/sverit-platezhi-za-period.md)

---

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