# Re:Link 계약-에스크로-분쟁 정책서 > 문서 버전: 1.0.0 > 기준일: 2026-03-07 > 적용 범위: Re:Link MVP Phase 1 > DRI: 대표 (제품 정책), FINANCE_OPERATOR (정산 실행), TRUST_OPERATOR (계약·검수·분쟁) --- ## 목적 이 문서는 Re:Link 플랫폼에서 계약 생성, 전자서명 증적 수집, 에스크로 결제, 검수 절차, 정산 해제, 분쟁 처리, 환불, 수동 보정에 관한 운영 기준을 정의한다. 모든 개발 구현과 운영 의사결정은 이 문서를 최우선 기준으로 삼는다. --- ## 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` | 서명 기술 제공자 (예: `RELINK_CHECKBOX`, `KAKAOPAY_SIGN`) | | 서명 해시 | `signatureHash` | 서명 행위 자체에 대한 해시 (재현 가능한 증적) | ### 2-2. MVP 서명 방식 MVP에서는 법적 요건을 충족하는 최소 증적을 수집하는 체크박스 동의 방식으로 시작한다. **MVP 서명 방식 (evidenceType: `CHECKBOX_CONSENT`)** 1. 사용자가 계약서 전문을 화면에서 열람한다. 열람 이벤트와 스크롤 완료 여부를 기록한다. 2. "본 계약서의 내용을 확인하였으며 동의합니다" 체크박스를 선택한다. 3. 선택 시점의 타임스탬프, IP, User-Agent, 문서 버전, 문서 해시를 수집하여 `SignatureEvidence`를 생성한다. 4. 사용자에게 서명 완료 확인 이메일 또는 알림톡을 발송하고 발송 기록을 저장한다. **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. 정산 실행 후 상태 전이 정산 승인이 완료되면 아래 상태가 순차적으로 전환된다. 1. `EscrowTransaction` 에스크로 상태: `RELEASE_REVIEW -> RELEASED` 2. 실제 출금 처리: PG사 또는 수동 정산 방식으로 업체 계좌에 정산 금액 송금 3. `Contract.status`: `IN_PROGRESS -> COMPLETED` 4. `Store.status`: `CONTRACTED -> CLOSED` (해당되는 경우) 5. `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. 분쟁 발생 시 에스크로 자동 보류 분쟁이 접수되면 시스템은 즉시 아래 처리를 실행한다. 1. `DisputeCase.status = OPEN`으로 생성 2. 에스크로 상태를 `DISPUTED`로 전환 (단, PG 자금은 실제 동결 상태를 유지) 3. 자동 정산 해제 프로세스가 중단됨 4. 계약 당사자 전원 및 `TRUST_OPERATOR`에게 분쟁 접수 알림 발송 5. 분쟁 건이 운영자 처리 큐에 등록됨 분쟁이 접수된 상태에서 정산을 임의로 해제하는 것은 불가능하다. 정산을 재개하려면 반드시 분쟁 해결 절차를 완료해야 한다. ### 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. 분쟁 해결 후 정산 처리 분쟁 해결 시 정산 처리는 아래 순서로 진행한다. 1. 운영자가 `DisputeCase`의 해결 코드와 금액(환불액, 정산액)을 기록 2. `DisputeCase.status = RESOLVED`로 전환 3. 에스크로 상태를 해결 방식에 따라 `RELEASED` 또는 `REFUNDED`로 전환 4. `PARTIAL_REFUND`의 경우 환불 `EscrowTransaction`과 정산 `EscrowTransaction`을 각각 생성 5. PG 또는 수동 방식으로 환불 및 정산 실행 6. 계약 상태 전환: `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 | 운영자 및 시스템의 모든 상태 변경 이력을 변경 불가 형태로 기록하는 감사 로그 | --- *이 문서는 Re:Link MVP 운영 기준 문서이며, 구현 코드보다 이 문서가 우선합니다. 정책 변경이 필요한 경우 이 문서를 먼저 개정하고 개정 이력을 기록한 뒤 코드 구현에 반영합니다.*