정산
핵심 요약
정산 생성은 정산액을 계산·기록하는 단계이며 실제 지급 완료 증거가 아닙니다. pending 상태와 지급 확정을 구분하세요.
실행 전 대상 주문·수수료·청크 점유·중단 복구 한계를 확인하세요. 여러 D1 배치를 하나의 트랜잭션으로 간주하면 안 됩니다.
정산은 수동 발생 실행입니다 — POST /api/v1/settlements(셀러). be-cloudflare/src/settle_impl.rs에서:
전제 조건
- 셀러는 승인되어야 합니다:
verification.status='APPROVED'가 필요 — 미승인 셀러는 정산할 수 없습니다. - 대상은 셀러의 주문 중
status IN ('paid','partially_refunded')**그리고settlement_id IS NULL**인 것,refunded_krw차감 후 순액.
실행 (여러 배치로 처리됨)
D1 트랜잭션 범위
D1의 개별 배치는 원자적이지만 여러 배치를 하나의 트랜잭션으로 묶지는 못합니다. 중간에 프로세스가 종료되면 정산 레코드 없이 주문만 점유된 상태가 남을 수 있습니다. 실제 운영 전 금융 무결성 격차 분석을 확인하세요.
- 시퀀스:
UPDATE counters SET n=n+1 WHERE name='settlement' RETURNING n→ 정산 번호ST-YYYY-NNNN. - 클레임: 각 대상 주문이 조건부
UPDATE orders SET settlement_id=? WHERE id=? AND settlement_id IS NULL과affected=1검증으로 클레임됩니다 — 중복 점유를 방지하도록 설계됐습니다. 정산 INSERT가 나중에 실패하면 코드가 점유 해제를 시도합니다 (settlement_id=NULL). - 기록:
INSERT INTO settlements (…, status='pending', …)와 함께seller_settings요율(pg_fee_rate,platform_fee_rate)로 계산된gross_krw,pg_fee_krw,platform_fee_krw,net_krw,order_ids_json. - Ledger + audit + outbox가 같은 배치에:
transaction_ledgersettlement엔트리,audit_eventssettle엔트리(무결성 해시 체인),outboxsettlement.settle이벤트.
응답: {ok:true, id, settlement_no, status:"pending", gross_krw, net_krw, orders}.
상태 모델
- 정산은 **
pending**으로 생성됩니다 — 지급은 별도 단계; 생성 시점 상태는 절대paid가 아닙니다. - 셀러 플랜/빌링 수집 경로가 없습니다 —
platform_fee_krw는 정산 시 발생하지만 아직 수집하는 것이 없습니다 (제한 사항 §3.4).
읽기
GET /api/v1/settlements(셀러 소유 / admin). 셀러 콘솔 페이지: fe/pages/settlements/.
관련
- 주문이 정산을 공급; 환불은 발생 전
refunded_krw를 통해amount_krw를 줄입니다. - 수수료율은
seller_settings에 있습니다(GET/PATCH /settings). - 무결성: ledger·audit 검증 API가 존재하지만 모든 정합성과 외부 PG 정산 대사가 검증된 것은 아닙니다(
GET /ledger/verify,GET /audit/verify, admin).