Rebrand repository from "Re:Link" to "Startover" across the codebase. Updates include package names and scopes (@relink/* -> @startover/*), import paths, Next.js transpile settings, vitest name, UI text and docs, Dockerfile and CI/workflow names, deploy scripts and repo paths, and example/production env values. Also add auth-related env vars, an apps/web .env symlink, and small formatting/typing cleanups in several TSX/TS files and tests to accommodate the rename.
30 KiB
Startover 계약-에스크로-분쟁 정책서
문서 버전: 1.0.0 기준일: 2026-03-07 적용 범위: Startover MVP Phase 1 DRI: 대표 (제품 정책), FINANCE_OPERATOR (정산 실행), TRUST_OPERATOR (계약·검수·분쟁)
목적
이 문서는 Startover 플랫폼에서 계약 생성, 전자서명 증적 수집, 에스크로 결제, 검수 절차, 정산 해제, 분쟁 처리, 환불, 수동 보정에 관한 운영 기준을 정의한다. 모든 개발 구현과 운영 의사결정은 이 문서를 최우선 기준으로 삼는다.
1. 계약 생성 규칙
1-1. 계약 생성 전제조건
계약은 아래 조건이 모두 충족된 경우에만 생성할 수 있다.
| 조건 | 설명 |
|---|---|
| 매칭 요청 상태 | MatchRequest.status = ACCEPTED 상태여야 한다. PENDING, REVIEWING, REJECTED, EXPIRED 상태에서는 계약 생성이 불가능하다. |
| 폐업자 계정 상태 | 계약 당사자인 폐업자의 계정이 활성 상태여야 한다. |
| 업체 인증 상태 | 계약 상대방 업체의 VendorCertification.status = APPROVED 상태여야 한다. 인증이 유효하지 않거나 SUSPENDED 상태인 업체와는 계약을 생성할 수 없다. |
| 매장 상태 | 해당 매장의 상태가 CONTRACTED 전환이 허용된 상태 (MATCHING 또는 RESERVED)여야 한다. |
| 중복 계약 없음 | 동일한 matchRequestId로 이미 DRAFT 이상의 계약이 존재하면 신규 생성이 불가능하다. |
계약 생성은 매칭 수락 시 시스템이 자동으로 시작하거나, 운영자가 운영 콘솔에서 수동으로 개시할 수 있다.
1-2. 계약 유형별 참여자 구성
계약 유형은 Contract.contractType 필드로 구분하며, 유형에 따라 계약 당사자와 역할이 달라진다.
| 계약 유형 | 코드 | 폐업자 역할 | 상대방 역할 | 계약 목적 |
|---|---|---|---|---|
| 시설 인수 | ACQUISITION |
양도인 (매도인) | 창업자 (양수인) | 영업시설, 비품, 권리금 일부 양도 |
| 철거 용역 | DEMOLITION |
의뢰인 | 철거업체 (수급인) | 내부 시설 및 설비 철거 용역 |
| 인테리어 공사 | INTERIOR |
의뢰인 또는 창업자 | 인테리어업체 (수급인) | 매장 인테리어 공사 용역 |
MVP에서 INTERIOR 계약의 의뢰인이 창업자인 경우, 폐업자는 계약 당사자가 아니며 매장 상태 전환에만 연동된다.
1-3. 템플릿 코드와 버전 관리 원칙
- 계약서는 반드시
Contract.templateCode로 지정된 표준 템플릿을 기반으로 생성한다. 임의로 작성한 계약서를 직접 업로드하여 계약 효력을 부여하는 것은 MVP에서 허용하지 않는다. - 템플릿은 계약 유형별로 구분하며, 법무 검토를 통과한 버전만 유효 템플릿으로 등록한다.
- 계약 생성 시점에 사용된 템플릿 버전은
ContractVersion.versionNo에 고정 기록한다. 이후 템플릿이 개정되어도 기존 계약에 소급 적용하지 않는다. - 템플릿 개정이 발생하면 신규
templateCode또는 버전 번호를 부여하고, 개정 이력과 유효 기간을 별도 마스터 테이블에 관리한다. - 법무 검토가 완료되지 않은 템플릿은
feature flag: contract_template_draft뒤에 두고 운영 환경에 노출하지 않는다.
1-4. 계약서 문서 해시 저장과 무결성 검증
- 계약서 문서는 생성 즉시 객체 스토리지에 저장하고
ContractVersion.documentStorageKey에 경로를 기록한다. - 저장 완료 시 문서 전체에 대한 SHA-256 해시를 계산하여
ContractVersion.documentSha256에 저장한다. - 서명 완료 이후 계약서 문서에 변조가 의심되는 경우, 저장된 해시와 현재 파일의 해시를 대조하여 무결성을 검증한다.
- 계약 문서는 계약 종료 후에도 법적 보존 의무 기간(최소 5년) 동안 삭제하지 않는다. 보존 기간은 법무 검토 결과를 우선 적용한다.
1-5. 계약 상태 전이
DRAFT -> GENERATED -> SIGNING -> SIGNED -> IN_PROGRESS -> COMPLETED
-> CANCELLED
| 전이 | 조건 | 실행 주체 |
|---|---|---|
DRAFT -> GENERATED |
템플릿 렌더링 및 문서 저장 완료 | 시스템 자동 |
GENERATED -> SIGNING |
계약 당사자에게 서명 요청 발송 | 시스템 자동 |
SIGNING -> SIGNED |
양측 서명 완료 | 시스템 자동 (서명 증적 수집 후) |
SIGNED -> IN_PROGRESS |
에스크로 결제 완료 | 시스템 자동 |
IN_PROGRESS -> COMPLETED |
에스크로 정산 해제 완료 | 운영자 승인 후 시스템 |
IN_PROGRESS -> CANCELLED |
분쟁 해결 결과가 전액 환불인 경우, 또는 운영자 판단 | 운영자 직접 |
SIGNING -> CANCELLED |
서명 기한 초과 (기본 7일) | 시스템 자동 또는 운영자 |
2. 서명 증적 규칙
2-1. 전자서명 증적에 반드시 포함해야 할 정보
모든 서명 행위는 SignatureEvidence 레코드로 저장한다. 아래 항목은 누락 없이 수집해야 한다.
| 항목 | 필드 | 설명 |
|---|---|---|
| 서명자 식별자 | userId |
서명한 사용자의 내부 ID |
| 서명자 역할 | signerRole |
계약 내 역할 (예: TRANSFEROR, TRANSFEREE, CLIENT, CONTRACTOR) |
| 서명 시각 | signedAt |
서명이 완료된 UTC 타임스탬프 (밀리초 단위) |
| 서명 IP | ipAddress |
서명 요청이 전송된 클라이언트 IP 주소 |
| User-Agent | userAgent |
서명에 사용된 브라우저/기기 정보 |
| 문서 버전 | contractVersionId |
서명 당시 적용된 ContractVersion의 ID |
| 문서 해시 | documentHash |
서명 당시 문서의 SHA-256 해시 (저장 해시와 일치 여부 검증용) |
| 증적 유형 | evidenceType |
서명 방식 코드 (아래 참조) |
| 제공자 코드 | providerCode |
서명 기술 제공자 (예: STARTOVER_CHECKBOX, KAKAOPAY_SIGN) |
| 서명 해시 | signatureHash |
서명 행위 자체에 대한 해시 (재현 가능한 증적) |
2-2. MVP 서명 방식
MVP에서는 법적 요건을 충족하는 최소 증적을 수집하는 체크박스 동의 방식으로 시작한다.
MVP 서명 방식 (evidenceType: CHECKBOX_CONSENT)
- 사용자가 계약서 전문을 화면에서 열람한다. 열람 이벤트와 스크롤 완료 여부를 기록한다.
- "본 계약서의 내용을 확인하였으며 동의합니다" 체크박스를 선택한다.
- 선택 시점의 타임스탬프, IP, User-Agent, 문서 버전, 문서 해시를 수집하여
SignatureEvidence를 생성한다. - 사용자에게 서명 완료 확인 이메일 또는 알림톡을 발송하고 발송 기록을 저장한다.
MVP 이후 확장 계획
| 단계 | 방식 | 조건 |
|---|---|---|
| Phase 1 (MVP) | 체크박스 동의 + 메타데이터 저장 | 현재 적용 |
| Phase 1.5 | 카카오페이 전자서명 | 카카오페이 전자서명 API 계약 완료 후 |
| Phase 2 | 공인전자서명 (PASS 등) | 법무 검토 및 거래 규모 기준 충족 시 |
서명 방식이 확장될 때 기존 CHECKBOX_CONSENT 서명의 법적 효력에 영향을 주지 않는다. 확장 방식은 신규 계약부터 적용한다.
2-3. 양측 서명 완료 시 계약 상태 전이
- 계약에 참여하는 모든 역할의
SignatureEvidence가 수집된 시점에 계약 상태를SIGNING -> SIGNED로 전환한다. - 단방향 서명(한쪽만 완료)은 서명 완료로 인정하지 않는다.
- 서명 만료 기간은 계약 생성 후 7일로 설정한다. 기간 내에 양측 서명이 완료되지 않으면 시스템이
SIGNING -> CANCELLED로 전환하고 관련자에게 알림을 발송한다. - 만료된 계약을 재활성화하려면 운영자가 새 계약을 수동으로 생성해야 한다.
3. 에스크로 결제 규칙
3-1. 결제 시점
에스크로 결제는 아래 조건이 모두 충족된 직후에 개시한다.
Contract.status = SIGNED(양측 서명 완료)- 모든 당사자의
SignatureEvidence가 유효한 상태로 저장됨 - 계약 금액이 0원 초과
결제 요청은 계약 서명 완료 이벤트가 발생한 즉시 결제 페이지로 안내하거나, 사용자 확인 단계를 거친 후 PG사에 결제 요청을 보낸다.
3-2. 에스크로 상태 전환 규칙
NOT_STARTED -> DEPOSIT_PENDING -> HOLDING -> RELEASE_REVIEW -> RELEASED
-> REFUNDED
HOLDING -> DISPUTED
RELEASE_REVIEW -> DISPUTED
| 상태 전이 | 조건 | 전환 가능 주체 |
|---|---|---|
NOT_STARTED -> DEPOSIT_PENDING |
결제 요청 발송 | 시스템 자동 |
DEPOSIT_PENDING -> HOLDING |
PG 결제 성공 웹훅 수신 및 idempotency 검증 완료 | 시스템 자동 (웹훅 처리) |
DEPOSIT_PENDING -> NOT_STARTED |
PG 결제 실패 또는 취소 웹훅 수신 | 시스템 자동 |
HOLDING -> RELEASE_REVIEW |
검수 승인 완료 (InspectionRecord.status = APPROVED) |
시스템 자동 |
RELEASE_REVIEW -> RELEASED |
운영자 정산 승인 | TRUST_OPERATOR, FINANCE_OPERATOR, SUPER_ADMIN |
RELEASE_REVIEW -> REFUNDED |
운영자 전액 환불 결정 | FINANCE_OPERATOR, SUPER_ADMIN |
HOLDING -> DISPUTED |
분쟁 접수 완료 | 시스템 자동 (분쟁 접수 즉시) |
RELEASE_REVIEW -> DISPUTED |
정산 검토 중 분쟁 접수 | 시스템 자동 |
DISPUTED -> RELEASED |
분쟁 해결 결과 FULL_RELEASE 또는 NEGOTIATED (정산 포함) |
운영자 분쟁 해결 처리 |
DISPUTED -> REFUNDED |
분쟁 해결 결과 FULL_REFUND |
운영자 분쟁 해결 처리 |
모든 상태 전환 시 AuditLog와 EventLog를 동시에 기록한다.
3-3. PG 웹훅 처리 원칙
idempotency 보장
- 모든 PG 웹훅은
EscrowTransaction.idempotencyKey를 기준으로 중복 처리를 방지한다. - 동일한
idempotencyKey로 이미 처리된 웹훅이 재수신되면 성공 응답을 반환하되 상태 변경은 실행하지 않는다. idempotencyKey는 PG 거래 ID와 이벤트 유형을 조합하여 생성한다.
재시도 정책
- PG 웹훅 수신 실패 시 자동 재시도를 지원한다. 재시도는 지수 백오프(Exponential Backoff) 방식으로 최대 5회 시도한다.
- 재시도 간격: 1분 -> 5분 -> 15분 -> 1시간 -> 4시간
- 5회 모두 실패한 경우
FINANCE_OPERATOR에게 알림을 발송하고 수동 처리 큐에 등록한다.
실패 처리
- 웹훅 처리 중 내부 오류가 발생한 경우 PG에 오류 응답(5xx)을 반환하여 PG의 재전송을 유도한다.
- 내부 오류 발생 시 관련 정보를 구조화 로그로 남기고 Sentry에 오류를 전송한다.
- 웹훅 원문 페이로드는 전체를 보관하여 이후 재처리(replay)가 가능하도록 한다.
검증 원칙
- 수신된 웹훅의 서명(Signature) 또는 HMAC을 반드시 검증한다.
- 웹훅 페이로드의 금액이
Contract에 기록된 계약 금액과 일치하지 않는 경우 처리를 거부하고 운영자에게 알림을 발송한다.
3-4. 금액 단위와 통화
- 모든 금액은 대한민국 원(KRW) 단위로 저장한다.
- 소수점을 허용하지 않는다. 금액 계산 결과에 소수점이 발생한 경우 내림(floor) 처리한다.
- 금액 필드는 부호 없는 정수(unsigned integer)로 저장한다. 음수 금액은 허용하지 않는다.
- 환불 또는 공제 금액은 별도의
EscrowTransaction레코드(transactionType:REFUND또는ADJUSTMENT)로 기록한다.
4. 검수 규칙
4-1. 검수 요청 시점
- 검수는 용역 계약(
DEMOLITION,INTERIOR) 또는 인수 계약(ACQUISITION)에서 업체(수급인) 또는 창업자가 작업 완료를 주장하며 사진을 업로드할 때 시작한다. - 검수 요청은
Contract.status = IN_PROGRESS상태에서만 접수할 수 있다. - 검수 요청 시
InspectionRecord를 생성하고 상태를REQUESTED로 설정한다.
4-2. 검수 승인 주체
검수는 2단계로 진행한다.
| 단계 | 승인 주체 | 역할 |
|---|---|---|
| 1차 | 폐업자 (의뢰인) | 작업 결과를 육안으로 확인하고 만족 여부를 표시한다. |
| 2차 | 운영자 (TRUST_OPERATOR) |
1차 승인된 검수를 최종 확인하여 기준 충족 여부를 판단한다. |
- 폐업자가 1차에서 거부한 경우, 업체는 보완 작업 후 재업로드할 수 있다. 재검수는 새로운
InspectionRecord로 처리한다. - 폐업자가 7일 이내에 1차 승인 또는 거부를 하지 않은 경우, 운영자는 직접 2차 검수를 진행할 수 있다. 이 경우 운영자는 사유를 반드시 기록해야 한다.
- 2차 운영자 승인 없이 에스크로 정산 검토 단계로 전이하지 않는다.
4-3. 검수 사진 최소 요구사항
| 항목 | 요건 |
|---|---|
| 작업 전 사진 | 필수. 최소 3장. 작업 대상 공간의 전체 상태를 확인할 수 있어야 한다. |
| 작업 후 사진 | 필수. 최소 3장. 작업 완료 후 동일 각도에서 촬영한 사진이어야 한다. |
| 주요 부위 상세 사진 | 계약 유형에 따라 추가 요구 (예: 철거의 경우 바닥/벽/배선 상태) |
| 사진 메타데이터 | 촬영 일시(EXIF) 포함 권장. EXIF가 없는 경우 업로드 시각으로 대체. |
| 파일 형식 | JPG, PNG, HEIC 허용. 단일 파일 최대 20MB. |
| 위조 방지 | 업로드 시 파일 해시를 InspectionRecord.evidencePayloadJson에 저장. |
기준 미달(사진 장수 부족, 작업 전 사진 누락 등)인 경우 시스템이 업로드를 거부하고 이유를 안내한다.
4-4. 검수 상태 전이
REQUESTED -> SUBMITTED -> REVIEWING -> APPROVED
-> REJECTED
| 전이 | 조건 | 실행 주체 |
|---|---|---|
REQUESTED -> SUBMITTED |
사진 업로드 완료 및 최소 요건 충족 | 시스템 자동 |
SUBMITTED -> REVIEWING |
폐업자 1차 검토 시작 | 시스템 자동 |
REVIEWING -> APPROVED |
폐업자 1차 승인 + 운영자 2차 승인 | 2단계 각각 실행 |
REVIEWING -> REJECTED |
폐업자 또는 운영자 거부 | 해당 주체 |
검수 승인 후 에스크로 상태가 HOLDING -> RELEASE_REVIEW로 자동 전환된다.
5. 정산 해제 규칙
5-1. 정산 해제 전제조건
아래 조건이 모두 충족되어야 정산 해제 절차를 시작할 수 있다.
| 조건 | 설명 |
|---|---|
| 검수 승인 완료 | 해당 계약의 최종 InspectionRecord.status = APPROVED 상태여야 한다. |
| 분쟁 없음 | 해당 계약에 DisputeCase.status가 OPEN, INVESTIGATING, MEDIATING인 건이 없어야 한다. |
| 에스크로 상태 | EscrowTransaction의 에스크로 상태가 RELEASE_REVIEW여야 한다. |
| 운영자 승인 | MVP에서 모든 정산은 운영자의 명시적 승인이 필요하다. 자동 정산 해제는 허용하지 않는다. |
5-2. 운영자 승인 (MVP 원칙)
MVP 기간 동안 모든 정산 해제는 TRUST_OPERATOR, FINANCE_OPERATOR, SUPER_ADMIN 중 한 명이 운영 콘솔에서 직접 승인해야 실행된다. 자동 정산 해제 기능은 feature flag: auto_escrow_release 뒤에 두고 MVP에서 비활성화 상태로 유지한다.
5-3. 정산 금액 계산
정산 금액 = 계약 금액 - 플랫폼 수수료
플랫폼 수수료 = 계약 금액 * 수수료율 (소수점 이하 내림)
수수료는 KRW 단위이며 소수점 이하를 내림(floor) 처리한다. 수수료 계산 결과와 정산 금액은 EscrowTransaction 레코드에 각각 기록한다.
5-4. 수수료율 정의
| 계약 유형 | 수수료율 | 비고 |
|---|---|---|
ACQUISITION (시설 인수) |
3% | 거래 금액의 3% |
DEMOLITION (철거 용역) |
5% | 용역 금액의 5% |
INTERIOR (인테리어 공사) |
5% | 용역 금액의 5% |
수수료율 변경은 운영 정책 개정 절차를 거쳐야 하며, 변경 효력은 변경 시점 이후 신규 생성 계약부터 적용한다. 기존 계약의 수수료율에 소급 적용하지 않는다.
수수료율은 코드에 하드코딩하지 않고 별도 설정 테이블(FeePolicy)에 관리한다.
5-5. 정산 실행 후 상태 전이
정산 승인이 완료되면 아래 상태가 순차적으로 전환된다.
EscrowTransaction에스크로 상태:RELEASE_REVIEW -> RELEASED- 실제 출금 처리: PG사 또는 수동 정산 방식으로 업체 계좌에 정산 금액 송금
Contract.status:IN_PROGRESS -> COMPLETEDStore.status:CONTRACTED -> CLOSED(해당되는 경우)EventLog:escrow_released,transaction_completed이벤트 기록
PG 출금 API 호출 실패 시 에스크로 상태를 RELEASE_REVIEW로 복귀하고 FINANCE_OPERATOR에게 알림을 발송한다.
6. 분쟁 처리 규칙
6-1. 분쟁 접수 가능 시점
분쟁은 아래 조건에서만 접수할 수 있다.
- 에스크로 상태가
HOLDING또는RELEASE_REVIEW인 상태 - 계약 상태가
IN_PROGRESS인 상태 - 동일 계약에 이미
OPEN,INVESTIGATING,MEDIATING상태의 분쟁 건이 없는 경우
분쟁 접수 주체는 계약 당사자(폐업자, 창업자, 업체) 또는 운영자가 될 수 있다.
6-2. 분쟁 사유 코드
| 코드 | 설명 |
|---|---|
QUALITY_ISSUE |
작업 품질이 계약 기준을 충족하지 못함 |
SCOPE_DIFFERENCE |
실제 작업 범위가 계약서 내용과 다름 |
TIMELINE_BREACH |
계약에서 정한 작업 기간을 초과함 |
DAMAGE |
작업 중 발생한 시설 또는 비품 파손 |
INCOMPLETE_WORK |
작업이 완전히 완료되지 않은 채 검수 요청됨 |
OTHER |
위 항목에 해당하지 않는 기타 사유 |
OTHER 선택 시 사유 텍스트 입력을 필수로 요구한다.
6-3. 분쟁 발생 시 에스크로 자동 보류
분쟁이 접수되면 시스템은 즉시 아래 처리를 실행한다.
DisputeCase.status = OPEN으로 생성- 에스크로 상태를
DISPUTED로 전환 (단, PG 자금은 실제 동결 상태를 유지) - 자동 정산 해제 프로세스가 중단됨
- 계약 당사자 전원 및
TRUST_OPERATOR에게 분쟁 접수 알림 발송 - 분쟁 건이 운영자 처리 큐에 등록됨
분쟁이 접수된 상태에서 정산을 임의로 해제하는 것은 불가능하다. 정산을 재개하려면 반드시 분쟁 해결 절차를 완료해야 한다.
6-4. 운영자 조사 및 중재 프로세스
| 단계 | 상태 | 주요 활동 | 담당 역할 |
|---|---|---|---|
| 접수 | OPEN |
분쟁 내용 확인, 당사자 진술 수집 요청 | TRUST_OPERATOR |
| 조사 | INVESTIGATING |
계약서, 검수 사진, 커뮤니케이션 이력 검토, 추가 증빙 요청 | TRUST_OPERATOR |
| 중재 | MEDIATING |
당사자에게 조정안 제시 및 수락 여부 확인 | TRUST_OPERATOR, OPS_MANAGER |
| 해결 | RESOLVED |
해결 방식과 사유 기록, 후속 정산 또는 환불 처리 | TRUST_OPERATOR, FINANCE_OPERATOR |
| 종료 | CLOSED |
분쟁 건 최종 종료 (합의 또는 해결 불가 종료 포함) | TRUST_OPERATOR |
- 분쟁 접수 후 2영업일 이내에 운영자가 조사를 시작해야 한다.
- 조사 기간은 최대 10영업일로 한다. 기간 내 해결이 어려운 경우 당사자에게 사유를 안내하고 기간을 연장할 수 있다.
- 모든 조사 및 중재 단계에서 운영자의 메모와 사유 코드를
DisputeCase에 기록한다.
6-5. 분쟁 해결 유형
| 해결 코드 | 설명 | 정산 처리 |
|---|---|---|
FULL_RELEASE |
분쟁 기각, 정산 정상 진행 | 전액 정산 해제 |
PARTIAL_REFUND |
일부 환불 후 나머지 정산 | 환불액과 정산액을 분리하여 각각 처리 |
FULL_REFUND |
전액 환불 | 업체에 정산 없음, 의뢰인에게 전액 환불 |
NEGOTIATED |
당사자 합의 도달 | 합의 내용에 따라 정산 및 환불 처리 |
분쟁 해결 유형(DisputeCase.resolutionCode)과 해결 요약(resolutionSummary)은 반드시 기록해야 한다. 기록 없이 분쟁 상태를 RESOLVED로 전환할 수 없다.
6-6. 분쟁 해결 후 정산 처리
분쟁 해결 시 정산 처리는 아래 순서로 진행한다.
- 운영자가
DisputeCase의 해결 코드와 금액(환불액, 정산액)을 기록 DisputeCase.status = RESOLVED로 전환- 에스크로 상태를 해결 방식에 따라
RELEASED또는REFUNDED로 전환 PARTIAL_REFUND의 경우 환불EscrowTransaction과 정산EscrowTransaction을 각각 생성- PG 또는 수동 방식으로 환불 및 정산 실행
- 계약 상태 전환:
IN_PROGRESS -> COMPLETED또는CANCELLED
7. 환불 규칙
7-1. 환불 가능 사유
환불은 아래 사유에 해당하는 경우에만 진행할 수 있다.
| 사유 | 설명 | 처리 방식 |
|---|---|---|
| 분쟁 해결 결과 환불 | DisputeCase.resolutionCode가 FULL_REFUND 또는 PARTIAL_REFUND |
분쟁 해결 절차 완료 후 처리 |
| 계약 서명 전 취소 | Contract.status = SIGNING 이전 취소 |
자동 환불 (PG 취소) |
| 업체 귀책 철수 | 업체가 계약을 이행하지 않고 철수한 경우 운영자 판단 | 운영자 승인 후 전액 환불 |
| 매장 사정으로 인한 계약 불능 | 폐업자의 불가피한 사유로 계약 진행 불가 | 운영자 검토 후 전액 또는 부분 환불 |
| 기타 운영 판단 | 서비스 오류, 플랫폼 귀책 등 | SUPER_ADMIN 또는 FINANCE_OPERATOR 승인 |
환불은 원칙적으로 전액 또는 부분으로만 처리하며, 계약 금액을 초과하는 환불은 허용하지 않는다.
7-2. 환불 금액 계산
| 환불 유형 | 계산 방식 |
|---|---|
| 전액 환불 | 에스크로에 입금된 원금 전액 반환. 플랫폼 수수료를 환불 금액에서 공제하지 않는다. |
| 부분 환불 | 운영자가 환불액을 직접 지정. 나머지는 업체에 정산. 환불액 + 정산액 = 계약 금액. |
수수료 환급 여부:
- 업체 귀책 또는 플랫폼 귀책의 경우: 수수료 전액 환급
- 의뢰인 단순 변심 또는 의뢰인 귀책의 경우: 수수료 비환급 (단, MVP에서는 운영자 재량 허용)
7-3. 환불 운영자 승인 필수
모든 환불은 FINANCE_OPERATOR 또는 SUPER_ADMIN의 명시적 승인이 필요하다. 시스템이 자동으로 환불을 실행하는 경우는 계약 서명 전 PG 취소 건에 한한다.
환불 승인 시 아래 정보를 반드시 기록한다.
- 환불 사유 코드
- 환불 금액 (전액 또는 부분)
- 승인자 ID
- 승인 시각
- 운영 메모
7-4. 환불 후 계약 상태 전이
| 환불 유형 | 계약 상태 전이 | 에스크로 상태 전이 |
|---|---|---|
| 전액 환불 | IN_PROGRESS -> CANCELLED |
DISPUTED -> REFUNDED 또는 RELEASE_REVIEW -> REFUNDED |
| 부분 환불 | IN_PROGRESS -> COMPLETED |
DISPUTED -> RELEASED (정산 완료 후) |
| 서명 전 취소 | SIGNING -> CANCELLED |
DEPOSIT_PENDING -> NOT_STARTED |
8. 운영자 수동 보정 규칙
8-1. 수동 보정이 필요한 상황
수동 보정은 시스템이 자동으로 처리할 수 없는 예외 상황에서만 실행한다.
- PG 웹훅 수신 실패로 인한 에스크로 상태 불일치
- 분쟁 해결 후 부분 환불 금액의 수동 분배
- 계약 금액 오류 정정 (계약 생성 단계의 시스템 오류)
- 운영자 판단에 의한 에스크로 보류 또는 해제
- 기타 정산 이상 건 처리
8-2. 수동 보정 가능 주체
| 작업 | 허용 역할 |
|---|---|
| 에스크로 상태 수동 전환 | TRUST_OPERATOR, FINANCE_OPERATOR, SUPER_ADMIN |
| 정산 금액 수동 보정 | FINANCE_OPERATOR, SUPER_ADMIN |
| 환불 금액 수동 결정 | FINANCE_OPERATOR, SUPER_ADMIN |
| 계약 상태 수동 전환 | TRUST_OPERATOR, SUPER_ADMIN |
| 수수료 면제 처리 | SUPER_ADMIN |
OPS_MANAGER와 SUBSIDY_OPERATOR는 계약-에스크로-정산 영역의 수동 보정 권한을 갖지 않는다.
8-3. 수동 보정 시 필수 기록 항목
수동 보정 실행 전 아래 정보를 입력하지 않으면 보정을 진행할 수 없다.
| 항목 | 설명 |
|---|---|
| 보정 사유 코드 | 미리 정의된 코드 중 선택 (예: WEBHOOK_FAILURE, DISPUTE_RESOLUTION, CONTRACT_ERROR, OPERATOR_OVERRIDE) |
| 보정 전 상태 | 변경 전 에스크로 상태 또는 금액 (시스템이 자동 캡처) |
| 보정 후 상태 | 변경 후 예상 상태 또는 금액 |
| 운영 메모 | 보정 배경과 판단 근거를 서술 (최소 20자 이상) |
| 관련 문서 또는 링크 | 분쟁 건 ID, 채팅 스레드 ID, 외부 근거 링크 등 |
8-4. AuditLog 필수 기록
모든 수동 보정은 AuditLog에 아래 정보를 반드시 기록한다.
| 필드 | 내용 |
|---|---|
actorId |
보정을 실행한 운영자 ID |
actorRole |
운영자 역할 |
targetEntity |
보정 대상 엔티티 (예: EscrowTransaction, Contract) |
targetId |
보정 대상의 ID |
action |
수행한 작업 코드 |
beforeState |
변경 전 상태 (JSON 스냅샷) |
afterState |
변경 후 상태 (JSON 스냅샷) |
reasonCode |
보정 사유 코드 |
memo |
운영 메모 |
occurredAt |
보정 실행 시각 |
AuditLog 기록은 삭제하거나 수정할 수 없다. 감사 로그는 최소 7년간 보존한다.
9. Feature Flag 규칙
9-1. MVP Feature Flag 목록
MVP Phase 1에서 아래 기능은 feature flag 뒤에 두고 기본값은 비활성화(false) 상태로 유지한다.
| Flag 이름 | 기능 설명 | MVP 기본값 | 활성화 조건 |
|---|---|---|---|
contract_template_draft |
법무 검토 미완료 템플릿 사용 허용 | false |
법무 검토 완료 후 true로 전환 |
auto_escrow_release |
검수 승인 후 운영자 승인 없이 자동 정산 해제 | false |
정산 운영 안정화 확인 후 단계적 활성화 |
kakao_sign_enabled |
카카오페이 전자서명 사용 | false |
카카오페이 전자서명 API 계약 완료 후 |
partial_refund_ui |
부분 환불 UI 운영 콘솔 노출 | true |
MVP 출시 시 활성화. 단, 실행은 FINANCE_OPERATOR 이상만 가능. |
dispute_auto_hold |
분쟁 접수 시 에스크로 자동 보류 | true |
MVP 출시 시 활성화. 비활성화 금지. |
inspection_photo_min |
검수 사진 최소 요건 강제 검증 | true |
MVP 출시 시 활성화. |
fee_policy_override |
개별 계약 수수료율 수동 오버라이드 | false |
SUPER_ADMIN 필요 시 개별 활성화 |
vendor_auto_contract |
업체 인증 승인 즉시 계약 생성 자동화 | false |
운영 안정화 후 검토 |
9-2. Feature Flag 운영 원칙
- Feature flag 값의 변경은
SUPER_ADMIN만 실행할 수 있다. - Flag 변경 시 변경자 ID, 변경 시각, 이전 값, 이후 값, 사유를
AuditLog에 기록한다. dispute_auto_hold와inspection_photo_min은 운영 안전을 위해 비활성화를 원칙적으로 금지한다. 비활성화가 필요한 경우 대표와 CTO의 동시 승인이 필요하다.- Feature flag는 환경별(개발/스테이징/운영)로 독립적으로 관리한다. 스테이징에서 활성화한 flag가 운영 환경에 자동으로 적용되지 않는다.
10. 계약-에스크로 흐름 전체 요약
[매칭 수락]
|
v
[계약 생성 (DRAFT -> GENERATED)]
|
v
[서명 요청 발송 (SIGNING)]
|
[양측 서명 완료]
|
v
[계약 SIGNED / 에스크로 DEPOSIT_PENDING]
|
[PG 결제 완료 웹훅]
|
v
[에스크로 HOLDING / 계약 IN_PROGRESS]
|
+--[분쟁 접수]---> [에스크로 DISPUTED / DisputeCase OPEN]
| |
| [조사/중재]
| |
| [해결 유형 결정]
| |
| +-----------+-----------+
| | | |
| [FULL_RELEASE] [PARTIAL] [FULL_REFUND]
| | | |
| v v v
| [RELEASED] [RELEASED [REFUNDED]
| +REFUNDED]
|
v
[검수 요청 (REQUESTED -> SUBMITTED -> REVIEWING)]
|
[폐업자 1차 승인 + 운영자 2차 승인]
|
v
[에스크로 RELEASE_REVIEW]
|
[운영자 정산 승인]
|
v
[에스크로 RELEASED / 계약 COMPLETED]
부록 A. 관련 운영 역할 요약
| 역할 | 계약 | 에스크로 | 검수 | 분쟁 | 정산 | 환불 | 수동 보정 |
|---|---|---|---|---|---|---|---|
SUPER_ADMIN |
O | O | O | O | O | O | O |
TRUST_OPERATOR |
O | 보류/해제 | O | O | - | - | 상태 전환 |
FINANCE_OPERATOR |
- | 정산/환불 | - | 정산 | O | O | 금액 보정 |
OPS_MANAGER |
조회 | 조회 | - | 중재 지원 | - | - | - |
SUBSIDY_OPERATOR |
- | - | - | - | - | - | - |
부록 B. 주요 용어 정의
| 용어 | 정의 |
|---|---|
| 에스크로 | 거래 대금을 제3자(PG사 또는 플랫폼)가 보관하다가 조건 충족 시 수령인에게 지급하는 결제 방식 |
| 정산 해제 | 에스크로에 보관된 금액을 수급인(업체)에게 지급하는 행위 |
| 검수 | 용역 또는 거래 완료 여부를 사진 및 현장 확인을 통해 검증하는 절차 |
| 분쟁 | 계약 당사자 간 계약 이행 관련 이의 제기 |
| 수동 보정 | 시스템 자동화 범위 밖의 예외 상황에서 운영자가 직접 상태 또는 금액을 변경하는 행위 |
| idempotency | 동일한 요청이 여러 번 실행되어도 결과가 동일하게 유지되는 성질 |
| AuditLog | 운영자 및 시스템의 모든 상태 변경 이력을 변경 불가 형태로 기록하는 감사 로그 |
이 문서는 Startover MVP 운영 기준 문서이며, 구현 코드보다 이 문서가 우선합니다. 정책 변경이 필요한 경우 이 문서를 먼저 개정하고 개정 이력을 기록한 뒤 코드 구현에 반영합니다.