Как работают API-платежей у провайдеров
Платёжный API — это контракт между вашим приложением и провайдером, который превращает «создать оплату», «подтвердить 3DS», «вернуть средства», «выплатить клиенту» и «получить статус» в надёжные, повторяемые вызовы. Под капотом — десятки правил: токенизация, idempotency, вебхуки, антифрод, очереди, SLA и аудит. Ниже — практическая карта того, как это устроено у большинства провайдеров.
Базовая модель: какие сущности есть почти всегда
Payment / Charge — попытка списания (authorize+capture или сразу purchase).
Payment Method — карта (PAN/token), банковский счёт/alias, кошелёк, локальный метод.
Customer — сущность клиента/плательщика (иногда необязательна).
Payout / Transfer — исходящий платёж клиенту/мерчанту.
Refund / Reversal — возврат к исходному платежу (closed-loop).
Webhook Event — асинхронное уведомление о статусе.
Dispute / Chargeback — спор по платёжной сети (для карт).
Order / Invoice — бизнес-контекст вокруг платежа.
Аутентификация и безопасность
API-ключи / OAuth 2.0 / mTLS — для сервер-к-серверу.
Клиентские токены — одноразовые токены для фронтенда (чтобы не светить секреты).
Токенизация карт — PAN уходит в провайдера; вы храните только токен.
PCI DSS — если вы видите PAN, вы в зоне PCI; лучше избегать и использовать хостед-поля/SDK.
HMAC подпись вебхуков — проверка, что событие пришло от провайдера.
Двухзонная архитектура — публичный фронт (JS/SDK) и приватный бэкенд (ключи, risk-логика).
Idempotency, очереди и согласованность
Idempotency-Key в заголовке: повтор запроса (при таймауте) не создаёт дубликат.
Outbox/Saga у вас: чтобы «отправил платёж → записал в леджер → дождался вебхука» было согласованно.
Ретраи с backoff — только для временных ошибок. Матрица retryable/non-retryable — обязательна.
Типовые эндпоинты (схемы и флоу)
1) Карты (Visa/Mastercard и др.)
POST /payments — создать платёж (`amount`, `currency`, `payment_method_token`, `capture`=false/true).
POST /payments/{id}/confirm — шаг 3-D Secure 2 (challenge/redirect result).
POST /payments/{id}/capture — захват после авторизации (частичный/полный).
POST /payments/{id}/refund — возврат (частями, до суммы исходного).
GET /payments/{id} — статус (authorized, captured, failed, requires_action).
3-D Secure / SCA: провайдер вернёт `requires_action` + `client_secret`/URL для challenge. После подтверждения клиентом фронт вернёт результат на ваш бэкенд → вы дергаете `/confirm`.
2) A2A / Open Banking (Pay by Bank)
POST /payments → ответ с `redirect_url` в банк клиента.
Клиент авторизуется у банка → webhook `payment.succeeded/failed`.
GET /payments/{id} — финальный статус (часто только асинхронно).
3) Локальные методы (PIX, PayID, FPX, iDEAL и т. п.)
POST /payments → получите `qr_code`/`deeplink`/`copy_code`.
Показываете пользователю, ждёте webhook о зачислении.
Таймауты и TTL на код — часть контракта.
4) Выплаты (payouts)
POST /payouts (`amount`, `currency`, `destination_token` или `card_token`/`bank_alias`).
GET /payouts/{id} — статусы (`queued`, `sent`, `paid`, `failed`).
Вебхуки `payout.paid/failed` — источник правды.
Закрытая петля: предпочтительно выплачивать на источник (reversal) до альтернатив.
Вебхуки: «источник истины»
События: `payment.pending/authorized/captured/failed`, `payment.requires_action`, `refund.succeeded`, `payout.paid`, `dispute.created` и т. д.
Доставка: с ретраями, подписанная HMAC, часто «как минимум один раз» → держите идемпотентность обработчика.
Best practice: обрабатывать вебхук → обновить леджер → ответить 2xx. Любая бизнес-логика после — асинхронно.
Обработка ошибок и статусов
HTTP-коды: `2xx` успех; `4xx` ошибка клиента (валидация, фрод/отказ банка, неверный токен); `5xx` — провайдер.
Причины отказов: `insufficient_funds`, `do_not_honor`, `stolen_card`, `limit_exceeded`, `risk_decline`, `bank_unavailable`.
Окна повторов: для 3DS — нельзя бесконечно ретраить; для A2A — действуют TTL редиректа/кода; для payouts — backoff.
Антифрод и риск
Device-fingerprinting и поведенческие данные — через JS/SDK провайдера или ваш собственный слой.
Списки: BIN-риск, чёрные/белые списки методов/ASN/стран.
Регулируемые гейты: лимиты на новые инструменты, «cool-off», velocity, RG/AML-пороговые проверки.
Политики: `pass / step-up / hold / block` на основе скоринга + правил.
Особенности по рельсам
Карты: авторизация vs клиринг (возможен сдвиг суммы), 3DS2, возвраты по исходной операции, споры/чарджбэки.
A2A/Open Banking: редирект/consent-флоу, высокий апрув, низкая стоимость; всё асинхронно и сильно зависит от банка.
Локальные быстрые: QR/alias, мгновенный вебхук, TTL и строгая свёрка.
OCT/Push-to-Card (выплаты на карту): нужны токены карты, поддержка Fast Funds у эмитента, без 3DS.
Версионирование и совместимость
Версии API: `/v1`, «дата-версии» в заголовке или фичефлаги.
Backwards-compatible изменения: только неразрушающие поля.
Депрекации: график вывода старых версий, миграционные гайды, дубликат вебхуков на время миграции.
Наблюдаемость и SLA
Метрики: p95 времени авторизации/выплаты, approve rate по BIN/банку/методу, доля ретраев, вебхуки-лаг.
Логи: корреляция по `request_id`, `idempotency_key`, `payment_id`.
Алерты: всплеск отказов по конкретному банку/стране, рост таймаутов, дубликаты событий.
Свёрка и финансы
Леджер: двойная запись, неизменяемые журналы, статусы `authorized/captured/refunded`.
Трёхсторонняя свёрка: ваш леджер ↔ вебхуки ↔ отчёты провайдера/банка.
Референсы: храните `provider_reference`, `network_reference`, `payout_reference` — это спасает саппорт.
Sandbox, сертификация и прод
Sandbox: тестовые токены/карты/банки, симуляция 3DS/редиректов, «кнопки» для статусов вебхука.
Тест-кейсы: успех/отказ, 3DS challenge, таймаут провайдера, дубликат вебхука, частичный capture/refund, отмена редиректа, payout fail.
Go-live: ключи прод, домены вебхуков, IP-allowlist, включить антифрод, задать лимиты и алерты.
Мини-примеры (схематично)
Создать платёж (карта)
POST /v1/payments
{
"amount": 9232, "currency": "EUR", "payment_method_token": "pm_tok_123", "capture": true, "metadata": {"order_id": "ORD-1001"}
}
→ 200 { "id": "pay_abc", "status": "requires_action", "next_action": {"type":"redirect", "url":"..."} }
Вебхук об успешном зачислении
POST /webhooks
{
"type": "payment.captured", "data": {"id":"pay_abc","amount":9232,"currency":"EUR","metadata":{"order_id":"ORD-1001"}}
}
Выплата (payout)
POST /v1/payouts
{
"amount": 5000, "currency": "EUR", "destination_token": "dest_tok_456", "metadata": {"user_id":"u_77"}
}
Чек-лист внедрения
1. Архитектура ключей: серверные секреты отдельно, клиентские — одноразовые.
2. Idempotency: в каждом write-вызове + идемпотентные обработчики вебхуков.
3. Вебхуки: подпись HMAC, ретраи, очередь задач, мониторинг лагов.
4. 3DS/SCA и редиректы: обработка отмен/таймаутов, повторная попытка френдли-UX.
5. Антифрод/лимиты: velocity, новые реквизиты, чёрные списки, RG/AML-пороги.
6. Леджер и свёрка: двойная запись, трёхсторонняя сверка, алерты аномалий.
7. Оркестрация: запасной провайдер, правила роутинга по BIN/стране/сумме.
8. Мониторинг: дашборды approve rate/p95/ретраи, алерты по банкам/методам.
9. Юридически/PCI: токенизация, политика возвратов, закрытая петля payouts.
10. План деградации: kill-switch канала, очереди, ручной режим для критичных операций.
Частые ошибки
Хранение PAN на своей стороне без PCI и токенизации.
Отсутствие idempotency → дубли платежей/выплат при таймаутах.
Логика на синхронных ответах без учёта вебхуков.
Один провайдер на рынок, без fallback/каскадов.
Нет обработки отмены 3DS/редиректа → потерянные корзины.
Слабая свёрка → «зависшие» и «потерянные» транзакции.
Отсутствие чётких SLA и алертов → проблему видит клиент, а не вы.
Mini-FAQ
Что надёжнее: синхронный статус или вебхук?
Вебхук — источник истины; синхронный ответ — лишь «принято/нужно действие».
Можно обойтись без 3DS?
Зависит от регуляции/риска. В ЕС/UK — SCA обязательна; для high-risk лучше step-up.
Как повысить approve rate?
Оркестрация по BIN/банку/методу, локальные рельсы, умные ретраи, корректные дескрипторы, антифрод с низким FPR.
Почему payout «не мгновенный»?
Зависит от рельс (OCT/A2A/локальные), банка получателя и лимитов. Давайте честное окно SLA и статус-стрим.
API-платежей — это не только «создать платёж». Это дисциплина: безопасная аутентификация → токенизация → idempotency → асинхронные вебхуки → леджер и свёрка → антифрод/AML → оркестрация и мониторинг. Постройте процесс по этой схеме, держите запасные каналы и прозрачный UX — и ваш платёжный слой будет быстрым, предсказуемым и устойчивым к сбоям банков и провайдеров.