API для мерчантов
Кабинет
Для разработчиков

FlipPay API

Принимайте платежи по СБП, картам МИР и в криптовалюте через единый REST API (набор способов зависит от вашей кассы). Плательщик оплачивает на нашей странице оплаты — вам нужно лишь создать платёж и обработать уведомление о статусе.

Базовый адрес
https://flippay.pro/api/v1
Авторизация
заголовки X-Api-Key + X-Api-Secret
Формат
JSON, суммы — строкой в рублях

Введение

  • • Все запросы — JSON по протоколу HTTPS.
  • • Суммы — в рублях, строкой с двумя знаками: "1000.50". Отдаём тоже строкой, чтобы не терять копейку на float.
  • • Поле metadata — произвольный JSON (напр. tg_id): вернём его как есть в статусе и в каждом вебхуке.

Промпт для ИИ-ассистента

Скопируйте промпт ниже и вставьте его своему ИИ-ассистенту (Cursor, Claude Code, GitHub Copilot, Windsurf) прямо в проекте — он подключит приём платежей FlipPay по нашей спецификации.

Как пользоваться

  1. Откройте свой проект в ИИ-редакторе (Cursor, Claude Code, Copilot Chat, Windsurf и т.п.).
  2. Скопируйте промпт кнопкой ниже и вставьте в чат ассистента.
  3. Получите ключи pk_… и sk_… в кабинете и положите их в переменные окружения проекта.
  4. Проверьте предложенный ассистентом план файлов и подтвердите реализацию.
Промпт уже содержит всю спецификацию: базовый URL, авторизацию, создание платежа, обработку вебхука с проверкой подписи, сверку статуса и список методов. Ассистент адаптирует код под ваш стек.
Промпт для ИИ-ассистента
Ты — опытный 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
Вызывайте API только с вашего сервера (backend). Никогда не размещайте X-Api-Secret в браузере, мобильном приложении или коде Telegram-бота на стороне клиента — секрет должен оставаться на сервере.

Быстрый старт

  1. Получите API-ключи в кабинете (Настройки и API → Интеграция и API).
  2. Создайте платёж запросом POST /api/v1/payments.
  3. Перенаправьте плательщика на pay_url из ответа.
  4. Получите уведомление о статусе на ваш Callback URL (или опрашивайте статус).
  5. Проверьте подпись X-Signature и выдайте товар/услугу.
POST

Создать платёж

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».
currencystringВалюта. Сейчас поддерживается только RUB (по умолчанию); другое значение → 422.
success_urlstringКуда вернуть плательщика после успешной оплаты (кнопка + авто-редирект на нашей странице). Только http(s)-адрес до 512 символов, иначе игнорируется. Не указан — берётся адрес из кабинета («Возврат после оплаты»).
fail_urlstringКуда вернуть при отмене/ошибке/истечении срока. Только http(s)-адрес до 512 символов.
metadataobjectПроизвольный 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.

Мерчант не принимает и не обрабатывает PAN, срок действия карты и CVV. Не создавайте свою форму ввода карты и не передавайте карточные реквизиты через свой backend. Откройте 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

Статус платежа

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.

Callback URL — только HTTPS и публичный домен (не IP-адрес и не внутренний адрес), с валидным SSL-сертификатом. Иной адрес не будет принят при сохранении в кабинете.
  • • Отвечайте кодом 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 статуса.

Чек‑лист МИР

  1. Убедитесь, что GET /payment-methods возвращает code: "card".
  2. Создайте новый заказ на 100.00 RUB с payment_method: 101.
  3. Откройте полученный pay_url и пройдите карточную форму/проверку 3‑D Secure.
  4. Убедитесь, что webhook пришёл с верной подписью и status: "success", а GET статуса вернул то же значение.
Нужна помощь с интеграцией? Напишите в поддержку.
Скопировано