수수료·쿠폰·정산 배치를 한 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
첫 댓글 달아줘.