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

UC-OVR-010. От завершённой сделки до выплаты комиссии и реферального вознаграждения

Назначение

Сквозной финансовый контур платформы: завершение сделки в crm порождает комиссионное начисление в rewards, из него удерживается доля ПИН, пул агентства делится между агентством и агентом (с учётом персонального оверрайда — «agent-boost»), параллельно приводившему инвестора партнёру начисляется реферальное вознаграждение; застройщик подтверждает начисление (при необходимости — с корректировкой суммы), финансовый оператор ПИН регистрирует акт фактического поступления денег (MoneyReceived) — это единый гейт денежных следствий: кошельки получателей кредитуются, реферальное начисление авто-подтверждается (Approved), доли открываются платёжным поручениям; агентство и оператор ПИН формируют платёжные поручения, отмечают фактическую выплату, и кошельки получателей дебетуются. Сценарий оркеструет crm (завершение сделки), rewards (начисления, удержание, распределение, акт, поручения) и wallet (кредиты/дебеты балансов), доводя деньги от «продажа зарегистрирована» до «агент/агентство/партнёр получили».

Числовой пример-ориентир (валюта одна, суммы иллюстративны, база — цена по правилу застройщика): ставка застройщика 10 % → удержание ПИН −1.5 п.п. → пул агентства 8.5 % → доля агента 3 % (по политике по умолчанию) либо 5 % (по персональному оверрайду «agent-boost»), остаток пула — удержание агентства; реферальное вознаграждение партнёру — сверх пула, его платит ПИН.

Metadata

ПолеЗначение
Статусdraft
Owning teamrewards
Primary capabilitycommission-settlement
Risk levelhigh

Scope И Участники

УчастникРоль
Менеджер застройщикаЗавершает сделку (crm); подтверждает начисление (± корректировка суммы) или отклоняет его (rewards)
Финансовый оператор ПИНРегистрирует акт поступления средств (гейт MoneyReceived); формирует и выплачивает реферальные поручения
Руководитель/бухгалтер агентстваНастраивает политику распределения (в т.ч. agent-boost); формирует, утверждает и отмечает выплату агентского поручения
Агент (получатель-Executor)Получатель доли комиссии — активный участник-исполнитель сделки на момент завершения
ПартнёрПолучатель реферального вознаграждения за приведённого инвестора
crm (deal)Издатель факта завершения сделки: цены, атрибуты объекта, получатель комиссии (Executor), атрибуция основателя (Origin)
rewardsОркестратор контура: комиссионное и реферальное начисления, снапшот удержания ПИН, распределение три строки, акт поступления, поручения
walletКредитует счета получателей по гейту денег, дебетует по факту выплаты; журнал проводок
notificationsУведомления агенту/агентству/партнёру на каждом статусном переходе

Preconditions

  • Сделка доведена до завершения (Sale → Completed) по регламенту оформления (UC-CRM-005); опубликовано pin.crm.deal-completed.v1 (deal-completed.md) с CommissionRecipientUserId (= Executor на момент завершения), иммутабельной атрибуцией OriginAgentUserId/OriginAgencyCompanyId, обеими ценами (BasePrice/FinalPrice, единая валюта) и CompletedAt.
  • У застройщика на момент CompletedAt действует правило вознаграждения, покрывающее объект (UC-RWD-001); иначе комиссионное начисление не создаётся (см. отказы).
  • Действуют условия удержания ПИН (агентские или глобальные, UC-RWD-007); их отсутствие — штатный fallback 0 п.п. (пул = вся комиссия).
  • У агентства настроена активная политика распределения с опциональным персональным оверрайдом агента (UC-RWD-005); её отсутствие — fallback «весь пул агенту».
  • Реферальная ветка срабатывает только при активной реферальной связи инвестора и применимой ставке на CompletedAt (UC-RWD-009).

Основной Сценарий

  1. Завершение сделки (crm). Менеджер застройщика подтверждает завершение после Росреестра; crm публикует pin.crm.deal-completed.v1. Получатель комиссии фиксируется снимком Executor на момент завершения (если исполнитель по ходу сделки менялся — комиссию получает актуальный Executor, а не основатель); Origin-атрибуция уходит иммутабельным снапшотом для воронки агентства и антифрода.
  2. Комиссионное начисление (rewards, system). По событию rewards подбирает правило застройщика на asOf = CompletedAt, считает валовую комиссию (CommissionAmount, в примере 10 % = 1 000 000 при базе 10 000 000), резолвит условия удержания ПИН на тот же момент и снимает снапшот (PlatformRetentionPercentagePoints = 1.5, PlatformFeeAmount = база × 1.5 / 100 = 150 000, AppliedPlatformTermsId); создаёт CommissionAccrual в PendingConfirmation (получатель = CommissionRecipientUserId, tenant = AgencyCompanyId, снапшот правила для воспроизводимости). Строк распределения ещё нет — UC-RWD-003.
  3. Реферальная ветка (независимая, атомарно с п.2). Если у инвestора активная реферальная связь и есть ставка на CompletedAt, тем же событием создаётся ReferralAccrual в Pending (Amount = FinalPrice × Percent / 100), привязанное к комиссионному начислению; вознаграждение платит ПИН сверх пула агентства — UC-RWD-009.
  4. Подтверждение застройщиком (rewards). Менеджер застройщика подтверждает начисление, при расхождении с договором — с корректировкой валовой суммы и обязательной причиной. В момент подтверждения строятся три строки распределения: Platform = PlatformFeeAmount (удержание ПИН, 150 000); пул = CommissionAmount − PlatformFeeAmount (8.5 % = 850 000) делится активной политикой агентства — Agent по персональному оверрайду «agent-boost» либо по правилу по умолчанию (в примере агент получает 3 % = 300 000 по умолчанию или 5 % = 500 000 по оверрайду), Agency — остаток пула. Начисление переходит PendingConfirmation → Confirmed; выплата пока недоступна — UC-RWD-004.
  5. Акт поступления средств — гейт денег (rewards). Застройщик перечисляет комиссию пакетным платежом; финансовый оператор ПИН заводит «Акт поступления средств», подбирает покрытые Confirmed-начисления, сверяет сходимость (Σ позиций = сумме поступления) и регистрирует акт. Регистрация — единый атомарный гейт всех денежных следствий: начисления Confirmed → MoneyReceived, связанные Pending-рефералки авто-подтверждаются Pending → Approved, публикуются построчные события получения денег — UC-RWD-010.
  6. Кредиты кошелька (wallet). По событиям гейта кошелёк кредитует счета: доля агента → AgentCommission, удержание агентства → AgencyCommission, удержание ПИН → PlatformRevenue, апрувнутая рефералка → ReferralCommission партнёра; нулевые строки проводок не порождают — с этого момента получатели видят суммы на балансах (UC-WLT-001).
  7. Агентское поручение (rewards). Руководитель агентства формирует платёжное поручение за период — захватываются свободные Agent-строки начислений в MoneyReceived; утверждает поручение и после фактической выплаты вне платформы отмечает его выплаченным. Каскадом начисления со всеми выплаченными Agent-строками переходят MoneyReceived → PaidUC-RWD-005.
  8. Реферальное поручение (rewards). Оператор ПИН собирает Approved-рефералки в реферальное поручение (ReferralReward), утверждает и после выплаты вне платформы отмечает выплаченным; рефералки Approved → PaidUC-RWD-009.
  9. Дебеты кошелька (wallet). По событиям выплаты поручений кошелёк дебетует счета получателей: доли агентов — с AgentCommission, реферальные вознаграждения — с ReferralCommission; баланс показывает невыплаченный остаток обязательств (UC-WLT-002).

Sequence

Постусловие

После полного прохода сценария гарантированно:

  • по сделке существует ровно одно CommissionAccrual (tenant = AgencyCompanyId, получатель = Executor на момент завершения) со снапшотом правила застройщика и снапшотом удержания ПИН (PlatformRetentionPercentagePoints/PlatformFeeAmount/AppliedPlatformTermsId) — расчёт воспроизводим при любых последующих правках правил/условий/политик;
  • начисление прошло PendingConfirmation → Confirmed → MoneyReceived → Paid; при подтверждении построены ровно три строки распределения Platform/Agency/Agent, их сумма равна валовой комиссии, строка Platform равна удержанию ПИН, пул (CommissionAmount − PlatformFeeAmount) поделён политикой агентства (доля агента — по оверрайду «agent-boost» либо правилу по умолчанию);
  • при активной связи и ставке существует ReferralAccrual, прошедшее Pending → Approved → Paid (авто-Approved — атомарный эффект регистрации акта); вознаграждение партнёра — сверх пула, пул агентства им не уменьшен;
  • зарегистрирован неизменяемый «Акт поступления средств» (Registered), Σ его позиций = сумме фактического поступления от застройщика;
  • сформированы, утверждены и отмечены выплаченными агентское (AgencyCommission) и реферальное (ReferralReward) поручения; каскад Paid доведён до начислений и рефералок;
  • в wallet по каждому получателю проведены кредит (по гейту денег) и дебет (по выплате): счета AgentCommission/AgencyCommission/PlatformRevenue/ReferralCommission сведены с журналом проводок, баланс = Σ кредитов − Σ дебетов;
  • на каждом статусном переходе агент/агентство/партнёр уведомлены.

Промежуточные состояния, наблюдаемые пользователями: (1) начисление создано — «ожидает подтверждения застройщиком»; (2) подтверждено — «подтверждено, деньги ещё не получены», выплата недоступна; (3) акт зарегистрирован — балансы кредитованы, доли доступны поручениям; (4) поручение выплачено — балансы дебетованы, в ЛК «получили».

Альтернативные Сценарии И Отказы

СитуацияПоведение
Сделка без агента (CommissionRecipientUserId не задан)Комиссионное начисление не создаётся (идемпотентный skip); реферальная ветка при активной связи выполняется отдельно (UC-RWD-003 A2)
У застройщика нет правила на CompletedAtКомиссионное начисление не создаётся (метрика «нет правила»); менеджер застройщика может завести начисление вручную; рефералка без родителя остаётся Pending — гейт денег непроходим до появления родителя (UC-RWD-009 A4)
Условий удержания ПИН нет на CompletedAtFallback 0 п.п.: PlatformFeeAmount = 0, строка Platform = 0, весь CommissionAmount — пул агентства (метрика «платформа теряет доход»)
Удержание ПИН ≥ ставки правила (пул ≤ 0)Событие целиком уходит в DLQ (REWARDS_PLATFORM_RETENTION_EXCEEDS_RULE): ни одно начисление (в т.ч. реферальное) не создаётся; менеджер ПИН правит условия/правило, событие переигрывается (UC-RWD-007 A5)
У агентства нет активной политики распределенияFallback «весь пул агенту»: строка Agency = 0, Agent = пул; строка Platform строится независимо от политики (UC-RWD-004 A2)
Застройщик подтверждает с корректировкой суммыВаловая сумма заменяется (с обязательной причиной), исходная фиксируется; пул и строки Agency/Agent считаются от новой суммы, удержание ПИН (PlatformFeeAmount) неизменно; сумма ≤ удержания ПИН → отказ (пул должен быть положителен)
Застройщик отклоняет начислениеНачисление отменяется (Cancelled, DeveloperRejected) с причиной; спор — вне rewards, через support; выплаты не наступают
Сделка отменена после начисления, до получения денегНачисление и рефералка отменяются consumer-ом отмены (кошелёк не затронут — кредита ещё не было); из MoneyReceived/Paid отмена запрещена — только компенсирующее ручное начисление-сторно
Σ акта ≠ Σ позиций при регистрацииРегистрация блокируется (REWARDS_RECEIPT_SUM_MISMATCH), акт остаётся Draft, каскад не выполняется; оператор выравнивает состав/сумму до регистрации (UC-RWD-010 A1)
Одно начисление в двух актах (гонка)Начисление — максимум в одном не-отменённом акте (уникальный индекс): победитель включает позицию, проигравший пересобирает состав; двойное подтверждение получения денег структурно исключено
Поручение сформировано до регистрации актаНачисления в Confirmed в автосборку не попадают (гейт не пройден) — поручение пустое, утверждение заблокировано; строки появятся после регистрации акта
Ошибочно выплаченное поручение (Paid)Терминально: компенсация вне rewards (сторнирующее ручное начисление застройщика + новое поручение на остаток)
Дебет кошелька не покрыт балансом (рассинхрон rewards↔wallet)Не бизнес-отказ, а детектор рассинхрона: транзакция не проводится, сообщение в DLQ + алерт + issue Reconciliation Center; покрытые позиции того же события проводятся (UC-WLT-002 A1)
Отмена Approved-рефералки (фрод/расторжение) до включения в поручениеОператор ПИН отменяет; кошелёк компенсирует кредит партнёра зеркальной проводкой; занятую поручением рефералку отменить нельзя

Согласованность И Идемпотентность

  • Событийная развязка контекстов. crm, rewards и wallet синхронизируются только событиями; каждый переход (Confirmed/MoneyReceived/Paid/реферальный Approved/Paid) публикуется атомарно с мутацией и доводит эффект до потребителей в окне eventual-consistency (кредиты/дебеты кошелька — секунды).
  • Снапшоты вместо пересчёта. Правило застройщика, удержание ПИН и политика агентства фиксируются снапшотами (AppliedRuleSnapshot, PlatformFeeAmount/AppliedPlatformTermsId, AppliedPolicyId); последующие правки правил/условий/политик уже созданные начисления не пересчитывают — расчёт воспроизводим и аудируем.
  • Единый денежный гейт. Ни кредита кошелька, ни доступности выплаты, ни авто-Approved рефералки нет до регистрации акта поступления средств (MoneyReceived) — подтверждение застройщиком признаёт обязательство, но деньги открываются только фактом поступления. Регистрация акта — атомарный каскад «либо всё, либо ничего».
  • Идемпотентность и порядок. Комиссионная и реферальная ветки идемпотентны по DealId (first-seen); переходы каждого начисления/поручения упорядочены ключом-идентификатором на своей партиции; повтор доставки/ регистрации — no-op (двойного MoneyReceived/Approved/Paid не бывает). Кредиты/дебеты кошелька идемпотентны по паре «вид операции + источник» — повторная доставка не двоит баланс.
  • Разделение денег. Удержание ПИН считается от базы цены и не зависит от политики агентства; политика делит только пул; реферальное вознаграждение платит ПИН сверх пула (пул агентства им не уменьшается) — три потока денег независимы и сходятся в журнале кошелька.
  • Атрибуция. Получатель доли агента — Executor на момент завершения; Origin-снапшот (агент/агентство- основатель) иммутабелен и в расчёте суммы не участвует — историческая атрибуция и антифрод переживают смену исполнителя.

Acceptance Criteria (Given/When/Then)

  • Happy (сделка → выплата). Дано: сделка завершена, у застройщика есть правило (10 %), действуют условия удержания ПИН (1.5 п.п.) и активная политика агентства с оверрайдом агента. Когда: проходит весь контур — начисление, подтверждение, регистрация акта, оба поручения. Тогда: построены три строки (Platform 1.5 п.п., пул 8.5 п.п. → Agency + Agent по оверрайду 5 п.п.), начисление доведено до Paid, кошельки кредитованы по гейту и дебетованы по выплате, получатели уведомлены.
  • Получатель — Executor, а не Origin. Дано: по ходу сделки исполнитель менялся. Когда: сделка завершается. Тогда: доля агента адресована CommissionRecipientUserId (Executor на момент завершения), а OriginAgentUserId/OriginAgencyCompanyId несут иммутабельную атрибуцию и в сумме не участвуют.
  • Гейт денег. Дано: начисление подтверждено, но акт не зарегистрирован. Когда: агентство пытается собрать поручение. Тогда: Agent-строки в автосборку не попадают, кошелёк не кредитован; после регистрации акта — доступны, балансы кредитованы.
  • Авто-Approve рефералки. Дано: рефералка Pending с родителем-комиссионным начислением. Когда: акт с родителем зарегистрирован. Тогда: рефералка атомарно Pending → Approved, счёт ReferralCommission партнёра кредитован; прямой перевод в Approved вне гейта отклоняется.
  • Удержание ПИН съедает ставку. Дано: удержание ≥ ставки правила. Когда: обрабатывается завершение. Тогда: оба начисления не создаются, событие в DLQ; после правки условий/правила replay создаёт начисления.
  • Корректировка застройщиком. Дано: подтверждение с adjustedAmount и причиной. Когда: строится распределение. Тогда: пул и доли Agency/Agent считаются от новой суммы, Platform неизменна; без причины или при сумме ≤ удержания ПИН — отказ.
  • Идемпотентность контура. Дано: повторная доставка deal-completed, повторная регистрация акта, повторная отметка выплаты. Когда: события переигрываются. Тогда: второго начисления/каскада/дебета нет, балансы кошелька не задвоены.

Source Of Truth И Данные

ДанныеВладелецConsistency rule
Факт завершения, цены, Executor/OrigincrmПубликуется атомарно, ровно один раз на DealId (терминальность)
Комиссионное/реферальное начисления, распределение, акт, порученияrewardsСнапшоты правил/условий/политики иммутабельны; переходы — только событиями и через гейт денег
Удержание ПИН (условия)rewards (платформенная сущность)Резолюция на asOf = CompletedAt; снапшот в начисление не пересчитывается
Балансы и журнал проводокwalletКредит по гейту, дебет по выплате; идемпотентность «вид операции + источник»; Balance = Σ кредитов − Σ дебетов

Контракты И Зависимости

  • Событие-триггер: deal-completed.md.
  • UC сервисов (комиссия): UC-RWD-003, UC-RWD-004, UC-RWD-005, UC-RWD-007, UC-RWD-010.
  • UC сервисов (рефералка/кошелёк): UC-RWD-009, UC-WLT-001, UC-WLT-002.
  • Предшествующие сценарии: UC-OVR-005 (лид → сделка), UC-OVR-006 (бронь → оформление → завершение).
  • Сквозной процесс: commission-settlement-saga.md.
  • ADR: 0066 (удержание ПИН + реферальные ставки, три строки распределения), 0067 (гейт MoneyReceived, корректировки), 0065 (кошелёк, кредиты/дебеты), 0052 (two-sided сущности, платформенные сущности), 0056 (акт вместо биллинг-сервиса).

Наблюдаемость

  • critical metrics: конверсия «начисление → подтверждение → получение денег → выплата»; возраст старейшего Confirmed без акта; доля начислений с fallback 0 п.п. (потеря дохода ПИН); глубина DLQ финансовых топиков; расхождения балансов кошелька с журналом.
  • trace path: crm (завершение) → шина событий → rewards (начисление → подтверждение → акт → поручения) → wallet (кредиты/дебеты) → notifications.
  • alerts: REWARDS_PLATFORM_RETENTION_EXCEEDS_RULE в DLQ; рост Confirmed-начислений без акта; рассинхрон rewards↔wallet (дебет без покрытия → Reconciliation Center).

Риски И Guardrails

  • Риск: двойное получение денег по одному начислению. Control: начисление — максимум в одном не-отменённом акте (уникальный индекс), регистрация — идемпотентный каскад.
  • Риск: выплата раньше поступления денег. Control: единый гейт MoneyReceived — доли доступны поручениям только после регистрации акта.
  • Риск: рассинхрон балансов кошелька и начислений. Control: идемпотентные проводки «вид операции + источник», no-negative guard, Reconciliation Center; журнал не правится, только компенсирующие проводки.
  • Риск: непрослеживаемый расчёт при правке правил/условий/политики. Control: иммутабельные снапшоты на каждом шаге; корректировка суммы — только с причиной и append-only аудит-строкой.

Обратные ссылки

Автоссылки: где используется этот документ.