Перейти к содержимому

Жизненный цикл платежа

TL;DR: платёж живёт дольше, чем HTTP-запрос покупателя: от попытки через статусы и уведомления до сверки с банком. Единственное подтверждение оплаты — server-to-server уведомление от провайдера, а не успешный ответ страницы, и вся логика магазина строится вокруг этого факта.

Страница описывает механику платежа во времени: какие статусы существуют, кто их источник, как магазин узнаёт об изменениях и как закрывает период сверкой. Состав способов — в способах и провайдерах, кассовые события — в фискализации, общая рамка — в обзоре.

  • Hosted-форма — платёжные данные вводит провайдер на своей странице; магазину не нужны сертификаты PCI DSS в минимальном объёме ответственности, кастомизация checkout ограничена.
  • API — магазин управляет сценарием, но принимает на себя требования безопасности платёжных данных; подход для команд с собственной разработкой.
  • SDK/виджет — компромисс: форма провайдера внутри checkout магазина, единый бренд, меньше ответственности за данные.

Выбор канала не меняет жизненный цикл: статусы, уведомления и возвраты устроены одинаково. Меняется только то, кто держит ввод платёжных данных и какую часть безопасности принимает магазин.

Для карт подтверждение покупателя проходит эмитентом (3-D Secure). Практические следствия:

  • Часть попыток падает на аутентификации — это не «сбой оплаты», а отказ эмитента или покупателя подтвердить.
  • Отчёты о конверсии checkout стоит отделять от отчётов о конверсии банка-эмитента: причины падений разного происхождения.
  • Часть способов вне карт (СБП, Pay-кнопки) проходит собственное подтверждение в приложении банка — по смыслу это тот же этап аутентификации.

Двухстадийные платежи: на первой стадии средства блокируются (hold/authorisation), на второй — списываются (capture). Нужны, когда между подтверждением и фактом списания есть шаг бизнеса:

  • проверка наличия товара до списания;
  • комплектация и сборка;
  • вручение суммы только после подтверждения доставки;
  • дозаказ несущих позиций, которых нет в наличии.

Одностадийные платежи списывают сразу и подходят для мгновенной отгрузки цифровых товаров. Освобождение hold (void) — отмена блокировки без списания; у части провайдеров сроки жизни hold ограничены — проверяется на момент проекта.

СтатусСмыслИсточник истиныТипичное следствие в магазине
pendingПопытка создана, исход не определёнПровайдерЗаказ «ждёт оплаты», товар не резервируется железно
succeededСредства получены/capturedПровайдер; магазин фиксирует локальноЗаказ «оплачен», чек по кассовому событию
failedПопытка неуспешнаПровайдерЗаказ остаётся, попытку можно повторить другим способом
expiredВремя на оплату истеклоПровайдер (по правилам схемы)Заказ, hold, если был, — освобождается

Источник истины по статусу — у провайдера. Локальная копия статуса в заказе — кэш для интерфейса и логики, который обновляется уведомлениями и сверяется периодически. Покупательский UI не должен считать платёж успешным по ответу браузера.

  • Server-to-server уведомления — единственное подтверждение платежа: провайдер сам вызывает сервер магазина. HTTP-ответ успешной попытки НЕ подтверждает платёж: пользователь мог закрыть страницу, сеть могла оборваться, а «успешная» страница могла отрисоваться до фактического завершения операции.
  • Идемпотентность — уведомления приходят повторно и в любом порядке; обработчик должен быть идемпотентным: повторное succeeded по тому же платежу не создаёт второй заказ, второй чек и вторую отгрузку. Ключ идемпотентности — идентификатор платежа и уведомления провайдера.
  • Достоверность — проверка подписи/IP-источника уведомления на стороне сервера; неподписанные вызовы не меняют статус заказа.
  • Порядок — уведомления могут приходить не в хронологическом порядке бизнес-событий (например, дубликат succeeded после первого); состояние склада доверяют сверке, а не последнему пришедшему сообщению.
  • Разрыв цепочки — «платёж удался, уведомление не дошло»: магазин узнаёт по сверке и по выгрузкам провайдера, поэтому не строит финальные решения только на вебхуках.

Сумма платежа может измениться в процессе: недовоз, замена позиции, удержание части стоимости. Провайдеры поддерживают частичный capture (в пределах hold) и частичные возвраты (в пределах списанного). Каждое денежное движение порождает кассовое событие, и возврат прихода идёт на возвращаемую часть, а не на весь чек (см. фискализацию).

Спор инициируется эмитентом покупателя, проходит по правилам платёжной схемы с дедлайнами на предоставление документов. Что готовит магазин:

  • доказательства вручения/отгрузки — из статусов отгрузки (логистика);
  • историю заказа и согласий — из системы заказов (интеграции);
  • переписку и правила возврата — из процессов магазина (процессы).

Деньги по chargeback могут уйти из счёта продавца независимо от решения магазина — резервирование и учёт таких рисков требуют проверки бухгалтером/юристом.

Сверка — периодическое сопоставление трёх потоков: платежи (уведомления), деньги (выписка/реестры провайдера), документы (чеки). По каждому партнёру — свой реестр.

BNPL-партнёр выплачивает сумму целиком, а заёмщик платит частями. Реестр связывает платежи заёмщика, выплаты продавцу, комиссии и возвраты. Без реестра невозможно закрыть период: продажа есть, денег «нет». Возврат товара по BNPL-заказу идёт своим возвратом в реестр партнёра, а не «возвратом платежа» провайдера.

Платежи по QR идут по правилам схемы СБП; реестры позволяют сопоставить входящие платежи с заказами и выявить, по какой схеме (СБП/УПК/эквайринг) фактически пришёл платёж (см. способы и провайдеры). Сверка СБП — не подмена QR-платежа на «единственный способ», а отдельный поток с собственными реестрами.

При split-платежах сверка ведётся по каждому продавцу: его доля, комиссия платформы, выплаты, возвраты. Реестр — основа расчётных документов с продавцом (см. модель маркетплейса). Один платёж покупателя порождает несколько расчётных позиций и, соответственно, несколько строк сверки.

  • Уведомление не дошло — статус заказа «завис»; лечится выгрузкой реестров и повторной синхронизацией, а не ручным вводом без записи.
  • Двойной платёж — два succeeded по одному заказу с разными идентификаторами; требует процедуры ручного возврата и записи причины.
  • Расхождение сумм (частичный capture, комиссия, конверсия) — фиксируется в сверке как норма, а не как ошибка.
  • Отмена после capture — возвратом, а не «удалением платежа».
  • Chargeback в пользу покупателя при доставленном заказе — документы вручения решают спор, а не мнение магазина.

Возврат денег связан с возвратом товара: решение по товару принимает логистика (выполнение заказов и возвраты), статус заказа меняют интеграции заказов, а платёжный контур исполняет возврат провайдером и кассовое событие «возврат прихода» (фискализация). Разделение ролей предотвращает «возврат без товара» и «товар без возврата денег».

Порядок работы системы при возврате — прямое следствие разделения ролей: сначала подтверждённый статус возврата товара, затем API-вызов возврата провайдеру, затем кассовое событие в ККТ, затем запись в реестрах сверки. Пропуск любого шага порождает расхождение, которое найдёт периодическая сверка.