UC-OVR-010. От завершённой сделки до выплаты комиссии и реферального вознаграждения
Назначение
Сквозной финансовый контур платформы: завершение сделки в crm порождает комиссионное начисление в
rewards, из него удерживается доля ПИН, пул агентства делится между агентством и агентом (с учётом
персонального оверрайда — «agent-boost»), параллельно приводившему инвестора партнёру начисляется
реферальное вознаграждение; застройщик подтверждает начисление (при необходимости — с корректировкой
суммы), финансовый оператор ПИН регистрирует акт фактического поступления денег (MoneyReceived) — это
единый гейт денежных следствий: кошельки получателей кредитуются, реферальное начисление
авто-подтверждается (Approved), доли открываются платёжным поручениям; агентство и оператор ПИН
формируют платёжные поручения, отмечают фактическую выплату, и кошельки получателей дебетуются. Сценарий
оркеструет crm (завершение сделки), rewards (начисления, удержание, распределение, акт, поручения) и
wallet (кредиты/дебеты балансов), доводя деньги от «продажа зарегистрирована» до «агент/агентство/партнёр
получили».
Числовой пример-ориентир (валюта одна, суммы иллюстративны, база — цена по правилу застройщика): ставка застройщика 10 % → удержание ПИН −1.5 п.п. → пул агентства 8.5 % → доля агента 3 % (по политике по умолчанию) либо 5 % (по персональному оверрайду «agent-boost»), остаток пула — удержание агентства; реферальное вознаграждение партнёру — сверх пула, его платит ПИН.
Metadata
| Поле | Значение |
|---|---|
| Статус | draft |
| Owning team | rewards |
| Primary capability | commission-settlement |
| Risk level | high |
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).
Основной Сценарий
- Завершение сделки (
crm). Менеджер застройщика подтверждает завершение после Росреестра;crmпубликуетpin.crm.deal-completed.v1. Получатель комиссии фиксируется снимкомExecutorна момент завершения (если исполнитель по ходу сделки менялся — комиссию получает актуальный Executor, а не основатель);Origin-атрибуция уходит иммутабельным снапшотом для воронки агентства и антифрода. - Комиссионное начисление (
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. - Реферальная ветка (независимая, атомарно с п.2). Если у инвestора активная реферальная связь и есть
ставка на
CompletedAt, тем же событием создаётсяReferralAccrualвPending(Amount = FinalPrice × Percent / 100), привязанное к комиссионному начислению; вознаграждение платит ПИН сверх пула агентства — UC-RWD-009. - Подтверждение застройщиком (
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. - Акт поступления средств — гейт денег (
rewards). Застройщик перечисляет комиссию пакетным платежом; финансовый оператор ПИН заводит «Акт поступления средств», подбирает покрытыеConfirmed-начисления, сверяет сходимость (Σ позиций = сумме поступления) и регистрирует акт. Регистрация — единый атомарный гейт всех денежных следствий: начисленияConfirmed → MoneyReceived, связанныеPending-рефералки авто-подтверждаютсяPending → Approved, публикуются построчные события получения денег — UC-RWD-010. - Кредиты кошелька (
wallet). По событиям гейта кошелёк кредитует счета: доля агента →AgentCommission, удержание агентства →AgencyCommission, удержание ПИН →PlatformRevenue, апрувнутая рефералка →ReferralCommissionпартнёра; нулевые строки проводок не порождают — с этого момента получатели видят суммы на балансах (UC-WLT-001). - Агентское поручение (
rewards). Руководитель агентства формирует платёжное поручение за период — захватываются свободныеAgent-строки начислений вMoneyReceived; утверждает поручение и после фактической выплаты вне платформы отмечает его выплаченным. Каскадом начисления со всеми выплаченнымиAgent-строками переходятMoneyReceived → Paid— UC-RWD-005. - Реферальное поручение (
rewards). Оператор ПИН собираетApproved-рефералки в реферальное поручение (ReferralReward), утверждает и после выплаты вне платформы отмечает выплаченным; рефералкиApproved → Paid— UC-RWD-009. - Дебеты кошелька (
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) |
Условий удержания ПИН нет на CompletedAt | Fallback 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 п.п.) и активная политика агентства с оверрайдом агента. Когда: проходит весь контур —
начисление, подтверждение, регистрация акта, оба поручения. Тогда: построены три строки (
Platform1.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/Origin | crm | Публикуется атомарно, ровно один раз на 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 аудит-строкой.
Обратные ссылки
Автоссылки: где используется этот документ.
- scenarios (1): Кросс-сервисные сценарии PIN (OVR)
- registries (1): Реестр use cases и user stories PIN