FlipPay API
Принимайте платежи по СБП, картам МИР и в криптовалюте через единый REST API (набор способов зависит от вашей кассы). Плательщик оплачивает на нашей странице оплаты — вам нужно лишь создать платёж и обработать уведомление о статусе.
X-Api-Key + X-Api-SecretВведение
- • Все запросы — JSON по протоколу HTTPS.
- • Суммы — в рублях, строкой с двумя знаками:
"1000.50". Отдаём тоже строкой, чтобы не терять копейку на float. - • Поле
metadata— произвольный JSON (напр.tg_id): вернём его как есть в статусе и в каждом вебхуке.
Промпт для ИИ-ассистента
Скопируйте промпт ниже и вставьте его своему ИИ-ассистенту (Cursor, Claude Code, GitHub Copilot, Windsurf) прямо в проекте — он подключит приём платежей FlipPay по нашей спецификации.
Как пользоваться
- Откройте свой проект в ИИ-редакторе (Cursor, Claude Code, Copilot Chat, Windsurf и т.п.).
- Скопируйте промпт кнопкой ниже и вставьте в чат ассистента.
- Получите ключи
pk_…иsk_…в кабинете и положите их в переменные окружения проекта. - Проверьте предложенный ассистентом план файлов и подтвердите реализацию.
Ты — опытный backend-разработчик. Внедри приём платежей FlipPay в ЭТОТ проект.
Действуй строго по спецификации ниже. Придерживайся текущего стека, стиля и
структуры проекта, не добавляй лишних зависимостей. Сначала покажи план файлов
и изменений, затем реализуй.
══ КОНТЕКСТ ══
FlipPay — платёжный шлюз. Интеграция server-to-server по HTTPS, формат JSON.
Базовый URL: https://flippay.pro/api/v1
Суммы — СТРОКОЙ в рублях с двумя знаками после точки. Пример: "1500.00".
══ СЕКРЕТЫ (только на сервере, через переменные окружения; НИКОГДА в клиентском
коде, в репозитории или в логах) ══
- FLIPPAY_API_KEY — публичный ключ (pk_...), заголовок X-Api-Key
- FLIPPAY_API_SECRET — секретный ключ (sk_...), заголовок X-Api-Secret
- FLIPPAY_WEBHOOK_SECRET — для проверки подписи вебхуков (заголовок X-Signature)
══ ЗАДАЧА 1. Создание платежа ══
POST {BASE}/payments
Заголовки: X-Api-Key: <FLIPPAY_API_KEY>, X-Api-Secret: <FLIPPAY_API_SECRET>,
Content-Type: application/json
Тело:
{
"order_id": "<твой уникальный ID заказа, до 128 символов>",
"amount": "<строка, сумма в рублях, напр. 1500.00>",
"payment_method": <int, код метода — см. ЗАДАЧУ 4>,
"description": "<назначение платежа, обязательно>",
"success_url": "<необязательно, https-адрес возврата после успешной оплаты>",
"fail_url": "<необязательно, https-адрес при отмене/ошибке>",
"metadata": {<необязательно, произвольный JSON до 4 КБ — вернётся как есть
в статусе и в вебхуке>}
}
Возвращает 200 и объект с полями order_id, status, amount, customer_amount,
customer_fee, currency, pay_url, metadata. amount — сумма заказа; customer_amount —
фактический итог клиента. Перенаправь покупателя на pay_url — это готовая ссылка на страницу
оплаты FlipPay, собирать её самому не нужно.
Идемпотентность: повтор запроса с тем же order_id вернёт уже существующий
платёж, дубль не создаётся — для нового платежа генерируй новый order_id.
══ ЗАДАЧА 2. Обработчик вебхуков (как узнать об оплате) ══
Разверни HTTP-эндпоинт (адрес укажешь в кабинете FlipPay: Настройки и API →
Уведомления), который:
1) Читает заголовок X-Signature и сверяет его В ПОСТОЯННОМ ВРЕМЕНИ
(hmac.compare_digest / crypto.timingSafeEqual) с HMAC-SHA256(сырое тело
запроса, ключ FLIPPAY_WEBHOOK_SECRET) в hex. Не совпало — запрос игнорируй.
2) Парсит JSON-тело с полями: event ("payment.updated"), order_id, status
(success | failed | refunded — статус pending вебхуком не отправляется),
amount, customer_amount, customer_fee, merchant_fee_percent, currency, metadata.
3) Обрабатывай ИДЕМПОТЕНТНО — из-за повторов одно и то же уведомление может
прийти несколько раз (например, различай по паре order_id + status).
4) Сверь amount и order_id со своим заказом перед выдачей товара/услуги; заказ
считается оплаченным ТОЛЬКО при status == "success".
5) Отвечай кодом 2xx в течение 30 секунд — иначе попытка
считается неудачной (таймаут, другой код и редирект — тоже неудача) и
повторяется (до 3 попыток, паузы 1 мин → 5 мин).
══ ЗАДАЧА 3. Сверка статуса (резерв, если вебхук не дошёл) ══
GET {BASE}/payments/{order_id} (те же заголовки авторизации)
Возвращает тот же объект, что при создании.
══ ЗАДАЧА 4. Методы оплаты ══
GET {BASE}/payment-methods (те же заголовки) — вернёт актуальный список
[{id, code, name, min_amount}] для этой кассы. Используй id как payment_method
при создании платежа. НЕ зашивай ID методов в код заранее — набор зависит от
кассы и может меняться.
══ ТРЕБОВАНИЯ ══
- НЕ считай возврат покупателя на success_url подтверждением оплаты — только
вебхук со статусом success (или прямой запрос статуса).
- Все вызовы FlipPay — ТОЛЬКО с сервера (backend); ключи не должны попасть в
браузер, мобильное приложение или клиентский код бота.
- Обрабатывай ошибки по HTTP-коду: 400 (метод недоступен / сумма вне лимитов
кассы), 401 (неверные ключи), 403 (касса отключена), 404 (заказ не найден),
422 (ошибка валидации тела), 502 (провайдер временно недоступен — платёж НЕ
создан, тот же order_id безопасно использовать повторно).
- Сохрани по каждому платежу: order_id, текущий status, amount, currency,
метку времени последнего изменения статуса.
- Добавь FLIPPAY_API_KEY, FLIPPAY_API_SECRET, FLIPPAY_WEBHOOK_SECRET в
.env.example без значений.
Полная спецификация — в этой документации (разделы «Создать платёж», «Webhook»,
«Проверка подписи», «Коды ошибок»).
pk_… / sk_… в промпт или в клиентский код — храните их только в переменных окружения на сервере. Промпт намеренно использует плейсхолдеры.Что дальше
- • Сверьтесь с разделом «Создать платёж» по полям и кодам ошибок.
- • Обязательно настройте проверку подлинности вебхуков до продакшена.
Авторизация
В каждый запрос добавьте два заголовка. Ключи доступны в кабинете: Настройки и API → Интеграция и API. Секретный ключ показывается один раз; перевыпуск отключает старый.
| Заголовок | Значение |
|---|---|
X-Api-Key | публичный ключ, pk_… |
X-Api-Secret | секретный ключ, sk_… |
X-Api-Key: pk_2f9c1ab34de5f6a7b8c9d0e1 X-Api-Secret: sk_8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b Content-Type: application/json
X-Api-Secret в браузере, мобильном приложении или коде Telegram-бота на стороне клиента — секрет должен оставаться на сервере.Быстрый старт
- Получите API-ключи в кабинете (Настройки и API → Интеграция и API).
- Создайте платёж запросом
POST /api/v1/payments. - Перенаправьте плательщика на
pay_urlиз ответа. - Получите уведомление о статусе на ваш Callback URL (или опрашивайте статус).
- Проверьте подпись
X-Signatureи выдайте товар/услугу.
Создать платёж
POST https://flippay.pro/api/v1/paymentsСоздаёт платёж и возвращает ссылку на нашу страницу оплаты. Идемпотентность: повторный запрос с тем же order_id вернёт существующий платёж (даже если в запросе другие сумма или метод, и даже если тот платёж уже истёк), дубль не создаётся. Для нового платежа используйте новый order_id.
Параметры
| Поле | Тип | Описание |
|---|---|---|
| order_idобязательное | string | Ваш ID заказа (уникальный). До 128 символов. |
| amountобязательное | string | Сумма в рублях (> 0), максимум 2 знака после точки. Напр. "1500.00". |
| payment_methodобязательное | integer | Метод оплаты (см. Методы): 100, 101, 103. Актуальный список вашей кассы — GET /api/v1/payment-methods. |
| descriptionобязательное | string | Назначение платежа, напр. «Заказ №12345». |
| currency | string | Валюта. Сейчас поддерживается только RUB (по умолчанию); другое значение → 422. |
| success_url | string | Куда вернуть плательщика после успешной оплаты (кнопка + авто-редирект на нашей странице). Только http(s)-адрес до 512 символов, иначе игнорируется. Не указан — берётся адрес из кабинета («Возврат после оплаты»). |
| fail_url | string | Куда вернуть при отмене/ошибке/истечении срока. Только http(s)-адрес до 512 символов. |
| metadata | object | Произвольный JSON (до 4 КБ), напр. {"tg_id": 123}. Вернём как есть в статусе и в вебхуке — удобно вместо похода в свою БД. |
Запрос
# создание платежа на 1500 ₽ по СБП curl -X POST https://flippay.pro/api/v1/payments \ -H "X-Api-Key: pk_2f9c1ab34de5f6a7b8c9d0e1" \ -H "X-Api-Secret: sk_8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b" \ -H "Content-Type: application/json" \ -d '{ "order_id": "ORDER-12345", "amount": "1500.00", "payment_method": 100, "description": "Заказ №12345", "success_url": "https://shop.ru/orders/12345/ok", "fail_url": "https://shop.ru/orders/12345/fail", "metadata": { "tg_id": 123456789 } }'
Ответ 200 OK
{
"order_id": "ORDER-12345",
"status": "pending",
"amount": "1500.00",
"customer_amount": "1500.00",
"customer_fee": "0.00",
"currency": "RUB",
"pay_url": "https://eaglors.com/pay/a1b2c3d4e5f60718293a4b5c6d7e8f90",
"metadata": { "tg_id": 123456789 }
}pay_url — он оплатит на нашей странице (СБП-QR, форма карты МИР, выбор банка, крипто-реквизиты и т.д.). Используйте ссылку как есть: домен в pay_url может отличаться от домена API, ссылку не нужно собирать самим. Ссылка действует ограниченное время — 20 минут для СБП и карт, до часа для криптовалюты (нужен запас на подтверждение сети), оставшееся время видно плательщику на таймере; после истечения создайте платёж заново с новым order_id.Карты МИР
Для оплаты картой создайте обычный платёж с
payment_method: 101, затем перенаправьте покупателя на
pay_url из ответа. Минимальная сумма — 100.00 RUB.
pay_url как обычную страницу в браузере покупателя: ввод карты и 3‑D Secure проходят на странице FlipPay.
Проверьте, что метод подключён
Используйте МИР, только если GET /api/v1/payment-methods
вернул запись с code: "card". Если её нет, метод ещё не включён для вашей кассы.
[
{
"id": 101,
"code": "card",
"name": "Карты МИР",
"min_amount": "100.00"
}
]Пример создания
curl -X POST https://flippay.pro/api/v1/payments \ -H "X-Api-Key: pk_..." \ -H "X-Api-Secret: sk_..." \ -H "Content-Type: application/json" \ -d '{ "order_id": "ORDER-MIR-1001", "amount": "100.00", "payment_method": 101, "description": "Заказ №1001", "success_url": "https://shop.ru/orders/1001/ok", "fail_url": "https://shop.ru/orders/1001/fail" }'
pay_url не выдавайте товар по самому факту возврата на success_url. Подтверждение оплаты — только webhook или GET статуса со значением success.Статус платежа
GET https://flippay.pro/api/v1/payments/{order_id}Резервный способ узнать статус, если не используете webhook (или для сверки).
curl https://flippay.pro/api/v1/payments/ORDER-12345 \ -H "X-Api-Key: pk_…" -H "X-Api-Secret: sk_…"
{
"order_id": "ORDER-12345",
"status": "success",
"amount": "1500.00",
"customer_amount": "1500.00",
"customer_fee": "0.00",
"currency": "RUB",
"pay_url": "https://eaglors.com/pay/a1b2c3d4e5f60718293a4b5c6d7e8f90",
"metadata": { "tg_id": 123456789 }
}Webhook (уведомления)
Укажите Callback URL в кабинете (Настройки и API → Уведомления). При смене статуса платежа мы отправим POST на ваш адрес с JSON-телом и заголовком X-Signature.
- • Отвечайте кодом
2xxв течение 30 секунд. Любой другой ответ, таймаут и редирект (3xxмы не выполняем) считаются неудачей и запускают повтор. - • Первая попытка — сразу после смены статуса (обычно в течение нескольких секунд). Ретраи: всего до 3 попыток с нарастающей паузой (1 мин → 5 мин). После последней неудачной попытки уведомление помечается «не доставлено» — статус всегда можно получить запросом
GET, а в кабинете доступна переотправка. - • Отправляется при переходе платежа в
success,failedилиrefunded(статусpendingвебхуком не шлётся). - • Из-за ретраев одно и то же уведомление может прийти несколько раз — обрабатывайте идемпотентно (например, по паре
order_id+status). - • Всегда сверяйте сумму и статус с вашим заказом; доверяйте только запросам с верной подписью.
Тело запроса
{
"event": "payment.updated",
"order_id": "ORDER-12345",
"status": "success",
"amount": "1500.00",
"customer_amount": "1500.00",
"customer_fee": "0.00",
"merchant_fee_percent": 0.0,
"currency": "RUB",
"metadata": { "tg_id": 123456789 }
}Проверка подписи
Заголовок X-Signature = HMAC-SHA256 от сырого тела запроса (hex), ключ — ваш webhook_secret из кабинета: Настройки и API → Уведомления. Сравнивайте константно (constant-time). Если подпись не совпала — игнорируйте запрос.
import hmac, hashlib def verify(raw_body: bytes, signature: str, secret: str) -> bool: expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, signature) # FastAPI / Flask: берите ИМЕННО сырое тело запроса (request body bytes)
Методы оплаты
Значение поля payment_method при создании платежа. Доступные вам методы настраивает менеджер. Идентификаторы могут меняться при смене платёжной инфраструктуры — актуальный список вашей кассы всегда возвращает GET /api/v1/payment-methods.
| ID | Метод |
|---|---|
100 | СБП |
101 | Карты МИР |
103 | Криптовалюта |
Список методов вашей кассы
curl https://flippay.pro/api/v1/payment-methods \ -H "X-Api-Key: pk_..." -H "X-Api-Secret: sk_..." [ { "id": 100, "code": "sbp", "name": "СБП", "min_amount": "0.01" } ]
Статусы платежа
| Статус | Значение |
|---|---|
| pending | Создан, ожидает оплаты. |
| success | Оплачен и подтверждён. |
| failed | Отклонён или истёк срок. Если плательщик всё же перевёл деньги уже после истечения, статус может перейти из failed в success — считайте success окончательным. |
| refunded | Возврат / чарджбэк. |
Коды ошибок
При ошибке возвращается соответствующий HTTP-код и тело JSON с полем detail:
{ "detail": "invalid credentials" }| Код | Когда |
|---|---|
400 | Метод оплаты не подключён вашей кассе (обратитесь к менеджеру), сумма ниже минимальной для метода (amount below minimum…; минимумы — в GET /api/v1/payment-methods) либо превышен лимит вашей кассы (amount below merchant minimum, amount above merchant maximum, daily limit exceeded). |
401 | Неверные или отсутствующие X-Api-Key / X-Api-Secret. |
403 | Касса отключена. |
404 | Платёж с таким order_id не найден (для GET статуса). |
502 | Платёжный сервис временно недоступен — платёж не создан. Повторите запрос через несколько секунд (тот же order_id безопасно использовать повторно). |
422 | Ошибка валидации тела запроса (отсутствует поле, неверный тип, order_id длиннее 128 символов, amount ≤ 0 или больше 2 знаков после точки, валюта не RUB, metadata > 4096 символов в JSON). |
Тестирование
- • Отдельной песочницы (sandbox) нет — интеграция тестируется на боевых ключах.
- • Проверяйте сценарий на минимальных суммах, затем переходите к реальным.
- • Для приёма вебхуков нужен публичный HTTPS-endpoint; на этапе разработки удобно поднять туннель (ngrok / cloudflared) и указать его как Callback URL.
- • Если вебхук не дошёл — статус всегда можно получить запросом GET статуса.
Чек‑лист МИР
- Убедитесь, что
GET /payment-methodsвозвращаетcode: "card". - Создайте новый заказ на
100.00 RUBсpayment_method: 101. - Откройте полученный
pay_urlи пройдите карточную форму/проверку 3‑D Secure. - Убедитесь, что webhook пришёл с верной подписью и
status: "success", аGETстатуса вернул то же значение.