# 정산 시스템 종합 정리 (Settlement System Overview)

- **작성일**: 2026-06-24
- **목적**: 입금 수수료 + P2P 수수료에서 발생하는 **모든 수익**(시스템 / 총판 / 매장 / 출금파트너)이 **하나의 정산 파이프라인**으로 흐르는 구조를 한눈에 정리.
- **관련 문서**: `FEE_POLICY_REDEFINITION_2026_06_24.md`(수수료 정의·보너스), `P2P_MATCHING_ARCHITECTURE.md`, `CRYPTOMENTS_V2_DDL.sql`
- **관련 코드**: `core/.../settlement/SettlementService.java`, `core/.../p2p/P2pSettlementService.java`, `common/.../mapper/SettlementMapper.java`

---

## 1. 큰 그림 — 2개 수익 원천 × 4종 참여자 × 1개 파이프라인

```
[수익 원천]                  [분배 대상]                 [공통 정산 파이프라인]

입금 수수료 (DEPOSIT) ─┐                                ┌─ ① 발생: FEE 원장 기록
                       ├─→ 시스템(SYSTEM)        ─┐     │
P2P 수수료 (P2P)      ─┘    총판(DISTRIBUTOR)     ├────▶├─ ② 일일 집계: settlement_daily_fees
                            매장(MERCHANT)         │     │      (참여자별 share_amount)
   + 출금자 보너스 ────────▶ 출금파트너(WITHDRAW)  ─┘     │
                                                        ├─ ③ 실현: MASTER→SETTLEMENT (realized)
                                                        └─ ④ 출금: SETTLEMENT_WITHDRAW
```

핵심: **수익이 어디서(입금/P2P) 발생하든, 누구 몫(시스템/총판/매장/출금파트너)이든 → 전부 `settlement_daily_fees`로 모여 동일한 실현·출금 절차를 탄다.** 차이는 "②에서 어떻게 쪼개느냐"뿐이다.

---

## 2. 수익 원천별 분배 모델 비교

| 구분 | 입금 수수료 (DEPOSIT) | P2P 수수료 (P2P) |
|---|---|---|
| **수수료 부담** | 입금 회원 (`deposit_fee_rate`) | 구매자 (`p2p_fee_rate ?? p2p.fee_rate`) |
| **집계 메서드** | `aggregateDailyFees` (라인 346) | `aggregateDailyP2pFees` (라인 491) |
| **원장 출처** | FEE 원장 (P2P 제외) | FEE 원장 (`reference_type=P2P_SETTLEMENT`) |
| **분배 방식** | **다단계 트리 마진** (매장→총판→시스템) | **체인 쉐어** (매장+상위총판) + 시스템 잔여 |
| **율 정의** | `parent_fee_rate`/`min_fee_rate` 트리 | `p2p_order_shares.share_rate` 스냅샷 |
| **출금자 보너스** | 없음 | **있음** (`p2p_matches.withdraw_bonus_rate`, P2P 레그) |
| **fee_source** | `DEPOSIT` | `P2P` |
| **변경 여부** | **현행 유지** | 보너스 추가(신규) |

### 2.1 입금 수수료 — 트리 마진 분배 (현행 유지)

입금 발생 매장부터 최상위까지 트리를 올라가며 각 계층이 마진을 가져간다 (`aggregateDailyFees`).

```
입금 매장:   마진 = deposit_fee_rate − min_fee_rate
중간 총판:   마진 = remainingRate − parent_fee_rate
최상위:      SYSTEM 몫 = parent_fee_rate(계약 수익률),  최상위 총판 = 잔여
각 참여자 share_amount = totalFee × (마진 / deposit_fee_rate)
```

### 2.2 P2P 수수료 — 체인 쉐어 + 출금자 보너스

```
구매자측 쉐어 S = Σ(매장+상위총판 × share_rate)   = FEE × share_rate / fee_rate
출금자 보너스 B = 출금파트너 × bonus_rate          = FEE × bonus_rate / fee_rate   (신규)
시스템         = FEE − S − B   (≥ 0, 상한 §FEE정의서 2.3)
```

> 입금은 "트리 마진", P2P는 "체인 쉐어"로 계산식은 다르나, **결과물(참여자별 `settlement_daily_fees` 행)은 동일 포맷**이라 이후 파이프라인은 공유된다.

---

## 3. 참여자(수익 주체) 정의

| 참여자 | participant_type | 수익 원천 | 정의 |
|---|---|---|---|
| **시스템(Cryptoments)** | `SYSTEM` | 입금 + P2P | 트리 최상위 계약 수익률(입금) / 쉐어·보너스 제외 잔여(P2P) |
| **총판(상위 파트너)** | `PARTNER` | 입금 + P2P | 입금: 트리 마진 / P2P: 자신의 `p2p_share_rate` |
| **매장(입금/구매자 파트너)** | `PARTNER` | 입금 + P2P | 입금: `deposit_fee_rate − min_fee_rate` / P2P: 자신의 `p2p_share_rate` |
| **출금파트너** | `PARTNER` | **P2P 보너스만** | P2P 출금 주문 매칭 시 `withdraw_bonus_rate` 보너스 (유동성 공급 인센티브) |

- `settlement_daily_fees`에서 시스템은 `participant_partner_id=NULL`, 나머지는 파트너 ID.
- **fee_role**(신규)로 P2P 행을 `BUYER_SHARE`(매장/총판) / `WITHDRAW_BONUS`(출금파트너) / `SYSTEM` 구분.

---

## 4. 공통 정산 파이프라인 4단계

| 단계 | 트리거 | 코드 | 결과 |
|---|---|---|---|
| **① 발생 (원장)** | 입금 확정 / P2P 매칭 정산 | `credit`/`recordFee`, `P2pSettlementService.completeSettlement` | `ledger_entries`에 CREDIT + FEE 기록 |
| **② 일일 집계** | 스케줄러 매일 새벽 | `aggregateDailyFees`(입금) + `aggregateDailyP2pFees`(P2P) | `settlement_daily_fees` 참여자별 행 + `settlement_balances.unrealized_balance` 누적 |
| **③ 실현** | 스케줄러 / 수동 | `realizeFees` | UNREALIZED→REALIZED, MASTER→SETTLEMENT 온체인 이체, `unrealized→realized_balance` |
| **④ 출금** | 파트너 요청 | `SETTLEMENT_WITHDRAW` 출금 | `realized_balance` 차감 + `frozen_amount`, SETTLEMENT→지정주소 |

### 4.1 잔액 상태 전이 (`settlement_balances`)

```
[② 집계]   unrealized_balance += share_amount        (수수료 발생, 아직 MASTER에 묶임)
[③ 실현]   unrealized_balance → realized_balance      (MASTER→SETTLEMENT 이체 완료, 출금 가능)
[④ 출금]   realized_balance → frozen_amount → 출금     (지정 주소로 송금, total_withdrawn 누적)
```

### 4.2 스케줄러 (scheduler 모듈)

| Job | 주기 | 역할 |
|---|---|---|
| `SettlementDailyAggregationJob` | 매일 00:30 | 전일 입금 + P2P 수수료 집계 (②) |
| `SettlementRealizationJob` | 매일 01:00 | 미실현 → 실현 전환 (③) |

---

## 5. 데이터 모델 (정산 코어 4테이블)

```
ledger_entries                  (① 발생: CREDIT / FEE / DEBIT / ADJUSTMENT)
      │  entry_type='FEE'
      ▼
settlement_daily_fees           (② 집계: 참여자별 share_amount, fee_source, fee_role)
      │  status: UNREALIZED → REALIZED
      ▼
settlement_balances             (잔액: unrealized / realized / frozen / total_withdrawn)
      │  realize
      ▼
settlement_realizations         (③ 실현: MASTER→SETTLEMENT 온체인 이체 기록)
```

| 테이블 | 핵심 컬럼 | 비고 |
|---|---|---|
| `ledger_entries` | entry_type, amount, reference_type/id | 복식부기 원장. FEE가 정산 입력 |
| `settlement_daily_fees` | fee_source(DEPOSIT/P2P), **fee_role**, participant_type, participant_partner_id, share_rate, share_amount, status | 일별·참여자별 수수료 분배 (신규: fee_role) |
| `settlement_balances` | participant_type, participant_partner_id, unrealized_balance, realized_balance, frozen_amount, total_withdrawn | 참여자별 누적 잔액 |
| `settlement_realizations` | from(MASTER)/to(SETTLEMENT) wallet, amount, tx_hash | 실현 온체인 이체 |

---

## 6. 통합 흐름 (end-to-end)

```
┌─ 입금 수수료 ────────────────┐      ┌─ P2P 수수료 ─────────────────────────┐
│ deposit FEE 원장             │      │ P2P_SETTLEMENT FEE 원장               │
│  └ aggregateDailyFees        │      │  └ aggregateDailyP2pFees             │
│     트리 마진 분배           │      │     체인 쉐어 + 출금자 보너스         │
│     · 매장 마진              │      │     · BUYER_SHARE (매장/총판)        │
│     · 총판 마진              │      │     · WITHDRAW_BONUS (출금파트너)     │
│     · SYSTEM(최상위 계약율)  │      │     · SYSTEM (잔여)                   │
└──────────────┬───────────────┘      └──────────────┬───────────────────────┘
               │   settlement_daily_fees (fee_source로 구분, 동일 포맷)
               └───────────────┬──────────────────────┘
                               ▼
              settlement_balances.unrealized_balance  (참여자별 누적)
                               │  realizeFees (매일 01:00)
                               ▼
              settlement_balances.realized_balance     (MASTER→SETTLEMENT)
                               │  SETTLEMENT_WITHDRAW
                               ▼
                       파트너/시스템 출금
```

---

## 7. 핵심 불변식 (검증 포인트)

1. **합 보존**: 매장·일자 단위로 `Σ(참여자 share_amount) = totalFee`. (입금=트리 마진 합, P2P=쉐어+보너스+시스템)
2. **시스템 ≥ 0**: P2P는 상한(`Σshare_rate + bonus_rate ≤ fee_rate`)으로 보장. 입금은 트리 구조상 항상 성립.
3. **멱등성**: ② 집계는 `settlement_daily_fees` UK로 재실행 안전. (보너스 행 추가에 따라 UK에 `fee_role` 포함 필요 — FEE정의서 §6)
4. **레그 격리(P2P)**: 보너스는 `leg_type='P2P'`만. TORQ·PARTNER 레그는 수수료·보너스 모두 없음.
5. **원천 격리**: 입금/P2P 집계는 `reference_type`(P2P_SETTLEMENT 포함/제외)으로 상호 배타 → 이중 집계 없음.

---

## 8. 이번 재정의로 추가되는 것 (요약)

정산 시스템의 **뼈대(4단계·4테이블)는 그대로**, P2P 분배 단계에만 보너스가 더해진다.

| 항목 | 변경 | 위치 |
|---|---|---|
| 입금 수수료 트리 | 변경 없음 | `aggregateDailyFees` |
| P2P 출금자 보너스 | **신규** | `aggregateDailyP2pFees` 확장 |
| `partners.p2p_withdraw_bonus_rate` | 신규 컬럼 | 보너스율 오버라이드 |
| `system_settings['p2p.withdraw_bonus_rate']` | 신규 키 | 보너스율 글로벌 기본 |
| `p2p_matches.withdraw_bonus_rate` | 신규 컬럼 | 매칭 시점 보너스율 스냅샷 |
| `settlement_daily_fees.fee_role` | 신규 컬럼 | BUYER_SHARE/WITHDRAW_BONUS/SYSTEM 구분 |
| PARTNER 레그 수수료 면제 | 코드 수정 | `P2pSettlementService.completeSettlement` |

상세 정의·산식·구현 지침은 `FEE_POLICY_REDEFINITION_2026_06_24.md` 참조.
