Как пользоваться
- Откройте свой проект в ИИ-редакторе (Cursor, Claude Code, Copilot Chat, Windsurf и т.п.).
- Скопируйте промпт кнопкой ниже и вставьте в чат ассистента.
- Получите ключи
pk_…иsk_…в кабинете и положите их в переменные окружения проекта. - Проверьте предложенный ассистентом план файлов и подтвердите реализацию.
Промпт уже содержит всю спецификацию
Базовый URL, авторизацию, создание платежа, вебхуки с проверкой подлинности, сверку статуса, а также опциональные H2H и выплаты. Ассистент адаптирует код под ваш стек.
Ты — опытный backend-разработчик. Внедри приём платежей Cashera в ЭТОТ проект.
Действуй строго по спецификации ниже. Придерживайся текущего стека, стиля и
структуры проекта, не добавляй лишних зависимостей. Сначала покажи план файлов и
изменений, затем реализуй.
=== КОНТЕКСТ ===
Cashera — платёжный шлюз. Интеграция server-to-server по HTTPS, формат JSON.
Базовый URL: https://api.cashera.cash/api/v1
Все суммы — ЦЕЛЫЕ числа в минорных единицах: RUB/USD/EUR умножать на 100,
USDT — на 1 000 000. Пример: 49900 = 499,00 RUB.
=== СЕКРЕТЫ (только на сервере, через переменные окружения; НИКОГДА в клиентском
коде, в репозитории или в логах) ===
- CASHERA_API_KEY — публичный ключ (pk_...), передаётся в заголовке X-Api-Key
- CASHERA_API_SECRET — секрет (sk_...), для проверки подлинности вебхуков
=== ЗАДАЧА 1. Создание платежа ===
POST {BASE}/integration/transactions
Заголовки: X-Api-Key: <CASHERA_API_KEY>, Content-Type: application/json
Тело:
{
"amount": <int, минорные единицы>,
"currency": "RUB" | "USD" | "EUR",
"payment_method": "<код метода, например sbp>",
"external_id": "<твой уникальный id заказа>",
"description": "<необязательно>",
"callback_url": "https://<твой-домен>/webhooks/cashera",
"success_url": "https://<твой-домен>/pay/ok",
"fail_url": "https://<твой-домен>/pay/fail"
}
Ответ 201 содержит "uuid", "status": "pending" и "payment_url".
Действие: перенаправь покупателя на payment_url.
Идемпотентность: повтор запроса с тем же external_id вернёт ту же транзакцию
(дубль не создаётся) — безопасно повторять при таймаутах.
callback_url ОБЯЗАТЕЛЕН и должен быть HTTPS на публичном хосте.
=== ЗАДАЧА 2. Обработчик вебхуков (как узнать об оплате) ===
Создай HTTP-эндпоинт POST /webhooks/cashera (или по роутингу проекта), который:
1) Читает заголовки X-Api-Key и X-Secret и сравнивает их В ПОСТОЯННОМ ВРЕМЕНИ
(constant-time) с CASHERA_API_KEY и CASHERA_API_SECRET. Если хотя бы один не
совпал — верни 401 и НЕ обрабатывай. X-Secret не логировать.
2) Парсит тело:
{
"event": "transaction.status_updated",
"transaction": {
"uuid": "...", "external_id": "...", "status": "paid",
"amount": 49900, "currency": "RUB", "payment_method": "sbp",
"paid_at": "..."
}
}
3) Идемпотентность по ключу transaction.uuid + transaction.status: уже
обработанное событие — просто верни 200, не повторяя бизнес-логику.
4) Заказ считается ОПЛАЧЕННЫМ только при status == "paid". Перед выдачей товара
сверь amount и currency со своим заказом по external_id.
5) Всегда возвращай HTTP 200 (любой 2xx) после приёма.
Статусы: pending (ждёт оплаты) — нефинальный; paid — успех; failed, expired,
refunded, chargeback — финальные неуспехи.
=== ЗАДАЧА 3. Сверка статуса (резерв, если вебхук не дошёл) ===
GET {BASE}/integration/transactions/{uuid} (заголовок X-Api-Key)
GET {BASE}/integration/transactions/by-external-id/{external_id} (заголовок X-Api-Key)
Возвращает текущий объект транзакции со status. Используй для ручной сверки.
=== ТРЕБОВАНИЯ ===
- НЕ считай возврат клиента на success_url подтверждением оплаты — только вебхук
"paid" или запрос статуса.
- Все вызовы Cashera выполняй ТОЛЬКО с сервера, ключи не попадают в браузер.
- Обрабатывай ошибки по HTTP-коду: 401 (ключ), 403 (мерчант/callback), 422
(валидация — детали в поле errors), 429 (лимит — повтори позже), 502 (провайдер).
- Повторяй сетевые ошибки и 5xx с тем же external_id (экспоненциальная задержка).
- Сохрани в БД: external_id, uuid, status, amount, currency, timestamps.
- Добавь CASHERA_API_KEY и CASHERA_API_SECRET в .env.example без значений.
=== ОПЦИОНАЛЬНО: H2H (свой UI оплаты вместо редиректа) ===
GET {BASE}/integration/transactions/{uuid}/h2h (заголовок X-Api-Key)
Ответ: { "amount": <number>, "qr": "<строка QR СБП или платёжная ссылка>" }
Отрендери qr как QR-код / кнопку оплаты в своём интерфейсе.
=== ОПЦИОНАЛЬНО: выплаты (вывод средств, USDT) — ТРЕБУЮТ ПОДПИСИ ===
POST {BASE}/integration/payouts и GET {BASE}/integration/payouts/{uuid}
Помимо X-Api-Key добавь заголовки:
X-Timestamp: <unix-время в секундах>
X-Signature: hex( HMAC-SHA256( CASHERA_API_SECRET, СТРОКА ) )
где СТРОКА — это склейка через перевод строки:
<timestamp>\n<METHOD>\n<path>\n<sha256_hex(raw_body)>
path включает префикс, например /api/v1/integration/payouts; для GET тело пустое
(sha256 от пустой строки). Допустимое расхождение времени — ±300 секунд.
Тело создания выплаты: { "amount": <int micro-USDT>, "currency": "USDT",
"external_id": "...", "destination": { ... } }. Финальный статус (completed/failed)
приходит вебхуком "payout.status_updated".
Полная документация: https://docs.cashera.cashБезопасность
Никогда не вставляйте реальные pk_… / sk_… в промпт или в клиентский код — храните их только в переменных окружения на сервере. Промпт намеренно использует плейсхолдеры.
Что дальше
- Сверьтесь с разделом «Создание платежа» по полям и кодам ошибок.
- Обязательно настройте проверку подлинности вебхуков до продакшена.
- Для выводов средств изучите подписанные запросы.