
5 августа 2026 г.4 минуты чтенияАдминистратор
Заказ, платёж и выплата: три истории одной покупки
Разбираем позднее подтверждение после отмены, устаревший экран и частичный возврат. Какие состояния и ограничения нужны рабочему интерфейсу.
Можно отгрузить оплаченный заказ и ещё не получить выплату в банк. Можно вернуть часть денег и сохранить факт исходной оплаты. Трудности начинаются, когда всё это приходится помещать в одну зелёную метку. Для рабочего интерфейса нужны три связанные истории и правила, которые не позволят одной истории незаметно переписать другую.
Для управления операциями удобно вести три связанные истории: коммерческий заказ, платёжную попытку и движение средств к банковскому счёту. Их можно показывать на одном экране, но нельзя сводить к единственному переключателю «оплачено / не оплачено».
Одна покупка, три момента времени
Условный пример: магазин продаёт комплект за 80 евро. В понедельник в 10:00 создаётся заказ. В 10:02 провайдер подтверждает оплату, но событие до системы магазина доходит в 10:04. Во вторник товар отгружают. По условиям нашего вымышленного договора средства становятся доступны для выплаты в среду и уходят в очередную выплату в четверг.
Во вторник заказ одновременно имеет состояния «оплачен» и «отправлен», а связанная выплата ещё не выполнена. Противоречия нет. Ошибка возникнет, если команда сочтёт отсутствие банковского поступления основанием повторно списать 80 евро или потребовать от покупателя новую оплату.
Теперь добавим частичный возврат на 20 евро после отгрузки. В учебной модели сумма оплаты остаётся 80 евро, сумма возврата равна 20 евро, остаток после возврата составляет 60 евро до комиссий. Перезаписывать первоначальную оплату числом 60 неудобно: исчезает история, с которой придётся сверять отчёт провайдера.
У заказа собственный жизненный цикл
Заказ отвечает на вопросы о товаре и обязательстве продавца: создан, принят, готовится, отправлен, выполнен, отменён. Названия выбирает сам бизнес. Заказ может быть отменён после оплаты, частично исполнен или оплачен несколькими частями. Поэтому отмена заказа должна запускать проверку платёжных последствий, а не просто скрывать строку из рабочего списка.
Платёж отвечает на другой вопрос: что произошло с конкретной попыткой внести деньги? В карточной схеме авторизация и списание могут быть отдельными этапами. Например, документация Adyen различает авторизацию, capture и settlement. У другого провайдера названия и набор состояний могут отличаться.
Провайдер также может иметь отдельный объект для всего процесса оплаты. Stripe PaymentIntent хранит состояние такого процесса и связывает попытки оплаты. При проектировании своей системы важно выяснить, какой идентификатор обозначает заказ, какой попытку, а какой итоговую финансовую операцию.
Задайте ограничения, которые проверяются автоматически
Удобно начать с нескольких внутренних условий целостности. Один идентификатор события не должен второй раз запускать исполнение. Подтверждённый возврат сохраняет связь с исходным платежом. Для каждой отгрузки есть либо допустимое подтверждение оплаты, либо явно одобренное коммерческое исключение. Суммы и валюты сравниваются по установленным правилам, а расхождение отправляется в отдельную очередь.
Не пытайтесь выразить всю логику порядком статусов «создан → успешно → закрыт». Представим, что заказ отменили в 10:03, а подтверждение оплаты, возникшее в 10:02, получили в 10:04. Платёж действительно состоялся, коммерческий заказ действительно отменён. Предлагаемый результат обработки: сохранить оба факта, запретить автоматическую отгрузку и открыть задачу на согласованное урегулирование. Возврат здесь ещё нужно разрешить и выполнить, его нельзя считать состоявшимся по факту отмены заказа.
На экране сотрудника покажите причину ожидания: «платёж подтверждён, исполнение остановлено после отмены». Это информативнее общего «ошибка». Следом нужны владелец и разрешённые действия. У покупателя может быть более короткое объяснение, но оно должно опираться на ту же запись.
Какие поля спасают расследование
- Внутренний номер заказа и идентификаторы всех связанных платежей.
- Первоначальная сумма и валюта, суммы подтверждённых списаний и возвратов.
- Исходный статус провайдера вместе с вашим понятным оператору статусом.
- Время события у источника и время его получения вашей системой.
- Номер выплаты, её состав, ожидаемая дата и банковское подтверждение, когда оно появится.
Даты доступности средств и отправки выплаты тоже стоит разделять. В документации Stripe о выплатах график перечисления отделён от срока, за который деньги становятся доступными. Для другого продукта проверяйте его собственные правила, включая выходные, время отсечения и первоначальные задержки.
Проверка на старой фотографии данных
Интерфейс всегда показывает данные на некоторый момент. Поэтому рядом со статусом полезны время последнего подтверждения и источник. Если оператор открыл карточку двадцать минут назад, денежное действие должно проверять актуальное состояние повторно. Иначе два сотрудника могут последовательно принять правильное решение по одной устаревшей картине.
Добавьте в тестирование такой учебный сценарий: первая смена создаёт возврат, вторая ещё видит старый экран и пытается создать такой же. Ожидаемое поведение системы нужно определить заранее: показать уже начатое действие, его идентификатор и статус, а не молча создать дополнительную операцию.
Историю исправлений храните отдельно от исходных событий. Тогда завтра можно восстановить и реальную последовательность, и то, что сотрудник знал в момент решения. Это особенно полезно при разборе поздних подтверждений: сегодняшнее знание результата не должно искажать оценку вчерашнего действия.
Ручное решение тоже оставляет историю
Повторное уведомление не должно создавать ещё одну отгрузку. Запоздалое уведомление не должно бесследно переписывать более свежие данные. Adyen описывает возможные дубли и необходимость учитывать хронологию событий. Проверьте эти сценарии по правилам используемого API.
Наконец, определите, какие переходы может делать оператор вручную. Вместо кнопки «сделать оплаченным» полезнее отдельная процедура разбора с обязательной ссылкой на подтверждение. Она сохраняет причину решения, автора и время. Так исключение остаётся видимым и проверяемым.
В отдельной очереди оставляйте оплаты без заказа, заказы без подтверждения, неразобранные возвраты и выплаты без банковского совпадения. У каждой позиции нужны возраст ожидания, владелец и следующий шаг.
Проверьте модель на одном заказе, отменённом до получения подтверждения оплаты. Система должна сохранить оба факта, показать задачу на урегулирование и не запустить ни повторное списание, ни автоматическую отгрузку. Такой тест проверяет смысл статусов лучше, чем смена цвета в интерфейсе.
Комментарии · 0
Комментариев пока нет — будьте первым.
Войти · войдите, чтобы оставить комментарий.