7. Создание платежа и жизненный цикл
7. Создание платежа и жизненный цикл
7. Создание платежа и жизненный цикл
Запрос
`POST /api/v1/payments` · право `payments:write` · обязателен `Idempotency-Key`.
| Поле | Тип | Описание | | --- | --- | --- | | `amount` | string, обязательно | Положительная десятичная строка: `"100.00"`. Не число с плавающей точкой. | | `currency` | string, обязательно | Валюта заказа: `RUB`, `USD`, `EUR`, `USDT`, `BTC`, `TON` (доступность зависит от магазина и провайдера). | | `merchant_order_id` | string, обязательно | ID заказа в вашей системе, 1–128 символов. | | `method` | string или `null` | Способ оплаты. Не передавайте, если способ выбирает покупатель на общей форме. | | `description` | string | Описание заказа, до 512 символов. | | `customer` | object | Необязательные строковые поля: `external_id`, `email`, `telegram_id`. | | `metadata` | object | До 20 полей: строки, целые числа или boolean. Без вложенных объектов. |
Точность суммы по валютам: RUB, USD, EUR — 2 знака; USDT — 6; BTC — 8; TON — 9.
Значения `method` (если задаёте): `sbp`, `card`, `crypto`, `telegram_crypto`, `direct_crypto`. Доступны только те, что включены для вашего магазина и среды; иначе `422 method_unavailable`. Нюансы:
**Карта (`card`)** оценивается в рублях: валюта платежа `RUB`.
**Криптоплатежи через PayHot (`crypto`)** оцениваются в рублях.
Минимальная комиссия магазина зависит от способа: **не менее 3% для СБП, 4% для карт, 1% для крипто**. Если комиссия магазина ниже минимума для включённых способов, API вернёт `422 fee_below_method_minimum`. Комиссию меняет менеджер.
Комиссию и долю покупателя нельзя переопределить полями запроса: они берутся из условий магазина.
Пример тела:
{
"amount": "100.00",
"currency": "RUB",
"merchant_order_id": "ORDER-1001",
"description": "Оплата заказа 1001",
"customer": { "email": "buyer@example.com" },
"metadata": { "plan": "pro" }
}Ответ `201`
{
"id": "sp_test_01J8Z3K4M5N6P7Q8R9S0T1V2W3",
"project_id": "…",
"status": "awaiting_method",
"amount": "100.00",
"currency": "RUB",
"payer_total": "100.00",
"merchant_amount": "96.00",
"fee": "4.00",
"merchant_order_id": "ORDER-1001",
"description": "Оплата заказа 1001",
"method": null,
"customer": { "email": "buyer@example.com" },
"metadata": { "plan": "pro" },
"checkout_url": "https://pay.shiftpay.cc/p/sp_test_…",
"created_at": "…",
"expires_at": "…",
"livemode": false
}Суммы выше — иллюстрация формата, а не ваши реальные тарифы. Что вернуть покупателю: перенаправьте его на `checkout_url`. Ссылка действует до `expires_at`. Создание ссылки **не** означает оплату.
Сохраните `id` платежа вместе с вашим заказом.
Идемпотентность
Ключ `Idempotency-Key` должен быть **постоянным для одной операции** (например, привязан к вашему заказу). Если ответ потерялся, повторите **тот же запрос с тем же ключом и телом**, но с новыми `timestamp`, `nonce` и подписью. Заголовок ответа `Idempotent-Replayed: true` означает, что вернулся результат прежней команды. Другая команда под тем же ключом → `409`. Не создавайте новый заказ вслепую: сначала прочитайте состояние `GET /payments?…` или `GET /payments/{id}`.
Статусы платежа
| Статус | Значение | Что делать | | --- | --- | --- | | `awaiting_method` | Выбор способа оплаты. | Ждать. | | `pending` | Ожидание оплаты. | Ждать. | | `detected` / `confirming` | Поступление обнаружено, подтверждение или распределение не завершено. | **Не выдавайте заказ**. | | `paid` | Оплата завершена в учёте (`payment.succeeded`). Деньги могут быть в холде/резерве. | Выдавайте заказ (после проверки вебхука). Доступные деньги смотрите в `/balance`. | | `underpaid` / `overpaid` | Недоплата/переплата. | Не приравнивайте к `paid`; нужна ручная обработка. | | `manual_review` / `aml_hold` | Проверка вручную или AML-удержание. | Не приравнивайте к `paid`. | | `expired` / `cancelled` / `failed` | Срок вышел, платёж отменён или ошибка. | Заказ не оплачен. | | `refund_pending` / `refunded` | Возврат ожидает завершения / завершён. | Согласуйте с учётом заказа. |
Отмена доступна только в `awaiting_method` и `pending` (`POST /payments/{id}/cancel`).
---
Страница была полезна?
