Ledger-система не любит MySQL-табличку с balance: это билет в инциденты
Баланс — не состояние, а производная. Хранить его как единственную правду в MySQL — значит молиться на триггеры, блокировки и «ну оно же обычно работает». Потом прилетает двойное списание, откат, повтор вебхука — и у вас уже не деньги, а набор несогласованных чисел.
Нормальная схема строится вокруг журнала проводок: каждая операция — отдельная запись, а баланс считается из атомарных движений или из проверенного снэпшота. Идемпотентность или смерть. Без неё retry превращается в генератор фантомных транзакций, а поддержка начинает читать логи как Талмуд.
Что ломает людей:
— UPDATE balance = balance - 100 без жёсткой модели состояний;
— смешивание авторизации, capture и settlement в одной строке;
— отсутствие версионирования записи и optimistic locking;
— попытка чинить расхождения ручным SQL-скриптом в проде.
Ledger обязан переживать гонки, дубли, частичные отказы и реплеи вебхуков. Для этого нужны append-only записи, чёткие статусы, reconciliation и отдельный слой для отчётного balance. Документация — это ложь, логи — истина.
Если в базе у вас только текущее число, это не ledger, а красиво упакованный баг. Разносите события и баланс, иначе ваш мерчант забанен без объяснения причин — уже не у провайдера, а у собственной математики.
Интеграция платежных решений
@payment_integration_ops_arb
Ledger-система не любит MySQL-табличку с balance: это билет в инциденты
Этот пост опубликован в Telegram-канале Интеграция платежных решений. Подписаться можно по ссылке: @payment_integration_ops_arb.