Минимум, чтобы принять первый платёж безопасно
Пять пунктов, без которых нельзя выходить на боевой трафик:- Секрет не лежит в коде. Ключ читается из переменных окружения или секрет‑хранилища, не из репозитория и не с фронтенда. → Безопасность в проде
- Есть HTTPS‑endpoint для вебхуков, доступный из интернета, и он проверяет подпись по сырому телу. → Настройка вебхуков
- Статус заказа меняется только по вебхуку — и перепроверяется запросом
/v1/payment/info, а не по редиректу пользователя. → Приём первого платежа - Обработка вебхука идемпотентна — дедуп по
uuid+status, повтор той же доставки ничего не ломает. → Настройка вебхуков - Суммы хранятся строками (или в minor‑единицах), без float. → Форматы сумм и денег
Полный прод‑харденинг (по мере роста)
Когда базовый чек‑лист пройден и трафик растёт, пройдитесь по областям ниже.Безопасность и ключи
- Секрет ключа хранится только на сервере — в секрет‑хранилище, не в браузере/мобильном приложении, не в репозитории. → Безопасность в проде
- Включён IP‑allowlist для API‑ключа: сначала добавлен IP backend, затем включён контроль. → IP‑allowlist
- Понятно, как ротировать ключ — только в личном кабинете под 2FA; в публичном API ротации нет; заморозки выплат при ротации нет. → Безопасность в проде
- Часы сервера синхронизированы (NTP) — при расхождении больше ±5 минут подпись не проходит и
приходит
merchant.bad_signature(окно времени проверяется внутри сверки подписи). → Как подписать запрос
Подпись и идемпотентность
- Тело сериализуется один раз и используется и для подписи, и для отправки (байт‑в‑байт). → Как подписать запрос
-
Заголовок
Idempotency-Keyна каждом денежном запросе. Значение генерируется до первой отправки и одинаково во всех попытках одного действия. Повтор вернёт тот же ответ и заголовокIdempotent-Replayed: true. → Идемпотентность -
Каждый платёж создаётся с уникальным
order_id, каждая выплата — с уникальнымorder_id/reference(для выплат он обязателен). Это второй, бизнес‑уровень дедупликации: он работает, даже если заголовок забыли. → Идемпотентность -
Ретраи с backoff на
429/503/500. -
409— НЕ всегда финал. Нельзя трактовать любой409как «уже обработано» и бросать операцию: так вы потеряете законную выплату. Разделяйте:409 payout.funds_maturing— повторяемая: средства ещё дозревают, повторите позже с backoff, и выплата пройдёт.409 idempotency.in_progress— повторяемая: запрос с этимIdempotency-Keyещё выполняется, подождите и повторите.- прочие
409(напримерpayout.insufficient_funds) — конфликт состояния: не повторяйте вслепую, сверьтесь через*/info.
Вебхуки
- Приёмник вебхуков настроен и проверен: endpoint зарегистрирован, секрет сохранён. → Настройка вебхуков
- Подпись вебхука проверяется правильным алгоритмом (timestamp +
.+ сырое тело), по сырому телу. → Объект вебхука - Обработка идемпотентна: дедуп по
uuid+status, порядок доставок не подразумевается. → Настройка вебхуков 2xxвозвращается только после успешной обработки.- Пробное событие доходит и возвращает
status_code: 200. → Отладка вебхуков
Платежи
- Обрабатываются все статусы платежа, включая
wrong_amount,paid_over,cancel. → Приём первого платежа - Недоплата/переплата настроены осознанно — допуск
accuracyи автовозвратautorefund. → Недоплата, переплата и автовозврат - Для Bitcoin/UTXO учтён ручной возврат (автовозврат там не работает). → Автовозврат
Выплаты и баланс
- Учтены незрелые (maturing) средства — выводимый остаток может быть меньше показанного;
409 payout.funds_maturingобрабатывается как временная ошибка и повторяется, а не считается отказом. →POST /v1/balance - Адрес получателя валидируется до вызова выплаты (выплаты необратимы и уходят сразу). → Первая выплата
- Большие списки выплат идут через батч
POST /v1/payout/batch(до 5000, асинхронно), а не циклом и не пачками по 100. → Массовые операции - Результат батча разбирается поэлементно (частичный успех — норма), статус опрашивается через
/v1/batch/info. → Массовые операции
Эксплуатация
- Мониторинг баланса и статусов выплат настроен.
- Хранится сопоставление
order_id↔ ваш заказ на вашей стороне. - Суммы хранятся строками/в minor‑единицах, без float. → Форматы сумм и денег
- Поддерживаемые сети/валюты сверяются программно через
*/services, а не только по таблице. →POST /v1/payment/services