개발 slecs

수수료·쿠폰·정산 배치를 한 PR로 묶어 잔액 정합성 확보

목차

수수료·정산·쿠폰 한 번에 묶은 날

오늘 만진 건 네 덩어리. 수수료 조회, 결제대행사 설정, 정산 배치, 쿠폰 상태 API. 하나하나 떼면 작은데 묶어 보니 결국 "파트너가 돈을 내고 받는 흐름" 전체가 한 줄로 이어짐. 정산 도메인은 이렇게 한 번에 손대는 게 정신 건강에 좋다. 부분만 고치면 나중에 숫자 안 맞을 때 어디서 깨진지 못 찾음.

바코드/쿠폰 API가 왜 정산이랑 같이 붙었나

쿠폰 상태 조회는 단순히 "이 코드 살아 있냐" 확인이 아님. 사용 처리되는 순간 수수료 PENDING 3건이 만들어지고, hold 끝나면 CONFIRMED로 바뀌면서 파트너 잔액이 움직임. 즉 쿠폰 상태가 곧 정산 트리거라서 같은 PR에 묶는 게 자연스러웠음.

  • 충전 수수료 PENDING
  • 결제 수수료 PENDING
  • 판매대금 PENDING

세 건이 동시에 떨어지지 않으면 나중에 환불 처리할 때 한 건만 남아서 잔액이 어긋남. DDL에 상태 컬럼 추가한 것도 이걸 강제하려고.

DDL 스키마 추가에서 신경 쓴 것

이번에 컬럼 늘리면서 가장 오래 고민한 건 인덱스. 정산 배치가 매일 쿼리 때리는데 status + created_at 복합으로 안 묶으면 풀스캔 각이었음.

항목 결정 이유
상태 컬럼 enum 대신 varchar 추후 상태 추가 시 ALTER 부담
인덱스 (status, created_at) 배치 조회 패턴이 상태→시간 순
정산일 날짜 컬럼 분리 월말 집계 쿼리 단순화

enum 안 쓴 게 맞는지는 6개월 뒤에 봐야 알 듯. 지금은 상태 종류가 늘어날 가능성이 더 커 보였음.

컨트롤러 4개 분리한 이유

한 컨트롤러에 다 박을 수도 있었는데 분리함. 권한 경계가 다르기 때문.

수수료 조회   → 파트너 본인 + 관리자
결제대행사 설정 → 관리자만
정산 배치    → 시스템 호출
쿠폰 상태    → 외부 API 키 인증

인증 방식이 네 개라 한 곳에 두면 인터셉터가 지옥이 됨. 미리 쪼갰다.

정산 배치에서 삽질한 부분

hold 기간이 가상계좌 2시간, 카드 3일로 다른데 처음엔 한 쿼리로 처리하려다 망함. 가상계좌가 카드 hold에 묻혀서 2시간 지나도 CONFIRMED로 안 넘어감. 결제수단별로 쿼리 쪼개고 나서야 정상.

  • 결제수단별 hold 만료 조건 분기
  • 만료된 PENDING만 잠금 걸고 UPDATE
  • 잔액 변동은 별도 트랜잭션에서

한 트랜잭션에 다 넣으니 락 경합으로 배치가 30초씩 늦어짐. 분리 후 3초 안쪽.

회고

도메인 4개 같이 만지는 건 위험한데, 정산처럼 끝단이 다 연결된 도메인은 오히려 같이 만지는 게 안전함. 부분 PR로 쪼갰으면 중간 상태에서 잔액 깨졌을 듯. 다음.

댓글 0

첫 댓글 달아줘.