채널 계층 요율 검증과 정산 일괄 등록 기능 추가
목차
채널 포털은 각 외부 채널 사업자가 자신의 현황을 확인하고 설정하는 공간이다. 잔액, 거래 내역, 하위 채널 현황을 한눈에 볼 수 있는 대시보드가 핵심인데, 이번 작업은 그 안에서도 운영 효율과 계산 정확성을 동시에 잡아야 하는 기능 두 가지를 묶어서 처리했다.
계층 요율 검증 로직
채널 구조가 상위-하위로 이어지는 다단계 형태다 보니, 요율 순서를 잘못 입력하면 마진이 음수가 나오는 버그가 생길 수 있다. 규칙 자체는 단순하다. 상위 채널 요율 < 하위 채널 요율. 상위가 더 낮아야 상위가 차익을 남기는 구조가 성립한다. 이게 뒤집히면 하위가 상위보다 낮은 요율로 수수료를 물게 되고, 계산 결과가 마이너스로 나온다.
단일 채널 등록 화면에서는 UI 단에서도 어느 정도 가이드가 되지만, 일괄 등록 엑셀에서는 사람이 수십 개 행을 직접 채우다 보니 실수가 생길 수밖에 없다. 그래서 업로드 시점에 계층 검증을 강제로 거치도록 했다.
def validate_channel_rate_hierarchy(parent_rate: Decimal, child_rate: Decimal, channel_id: str):
if parent_rate >= child_rate:
raise ValidationError(
f"채널 {channel_id}: 상위 요율({parent_rate}%)이 하위 요율({child_rate}%) 이상입니다. "
"마진이 음수가 됩니다."
)
실제로는 채널 트리를 재귀로 순회하면서 각 노드 쌍을 비교해야 해서 조금 더 복잡해지지만, 핵심 조건은 저거다. 오류가 발생하면 어느 행 어느 채널 ID에서 걸렸는지 구체적으로 알려줘야 운영팀이 수정할 수 있다. 그냥 "검증 실패"만 뱉으면 50개 행 중 어디가 문제인지 다시 훑어봐야 한다.
일괄 등록 흐름은 대략 이렇다.
| 단계 | 처리 내용 |
|---|---|
| 1. 파싱 | 엑셀 행 전체 읽기, 필수 컬럼 누락 체크 |
| 2. 형식 검증 | 요율 범위(0~100%), 중복 채널 ID 체크 |
| 3. 계층 검증 | 상위/하위 요율 순서 확인 |
| 4. DB 저장 | 트랜잭션 단위로 일괄 insert |
| 5. 결과 반환 | 성공 건수, 실패 행 목록 |
3단계에서 막히면 4단계로 넘어가지 않는다. 부분 저장 상태로 운영에 들어가는 게 가장 골치 아프기 때문에, 전체 통과 아니면 전체 롤백이다.
정산 배치와 멱등성
정산 UI 개선도 같이 했는데, 사실 화면 자체보다 뒤에 깔린 배치 로직이 더 신경 쓰이는 부분이었다. 정산 배치는 멱등성이 중요하다. 같은 기간을 두 번 돌려도 결과가 달라지면 안 된다는 뜻인데, 이게 말로는 당연한 것 같아도 구현할 때 생각보다 구멍이 생기기 쉽다.
가장 흔한 실수는 "이미 정산된 건 건너뛴다"는 로직을 넣었는데, 체크 조건이 기간 범위가 아니라 상태 컬럼 하나에 의존하는 경우다. 수동으로 상태를 되돌리거나 재처리 요청이 오면 그 가정이 무너진다. 기간 + 채널 ID 조합으로 유니크 키를 걸어두고 upsert로 처리하는 방식이 더 안전하다.
INSERT INTO settlements (channel_id, period_start, period_end, amount, fee, net_amount)
VALUES (%s, %s, %s, %s, %s, %s)
ON CONFLICT (channel_id, period_start, period_end)
DO UPDATE SET
amount = EXCLUDED.amount,
fee = EXCLUDED.fee,
net_amount = EXCLUDED.net_amount,
updated_at = now();
이렇게 해두면 재실행해도 같은 값으로 덮어쓰기만 하고 중복 생성은 없다.
수수료 계산에서 반올림 방향도 정리했다. 일반적으로 수수료를 내는 쪽은 내림으로, 그러니까 실제보다 조금 덜 내는 방향으로 처리하는 게 분쟁을 줄인다. 1원 단위 오차가 쌓이면 장기적으로 회사 쪽 손실이 되긴 하지만, 파트너 채널이 "왜 계산이 이상하냐"고 민원 넣는 상황이 더 비용이 크다. 특히 계층이 3단계 이상 이어지면 각 단계마다 반올림이 누적되니까, 어느 방향으로 처리할지 한 번 정해두고 전 레이어에서 일관되게 쓰는 게 맞다.
정산 화면 UI에서는 결국 숫자 표기 일관성이 제일 체감 품질을 좌우한다. 총 거래액, 수수료, 실수령액 세 줄이 핵심인데, 천 단위 구분자 없이 나오거나 어떤 건 '원' 단위가 붙고 어떤 건 빠지면 그것만으로 신뢰가 깎인다. 마이너스 금액은 빨간색으로 직관적으로 구분해주는 것도 작은 것 같지만 실제로 빠지면 티가 난다.
작업 규모 자체는 크지 않았다. 계층 검증 함수 하나, 배치 upsert 쿼리 수정, UI 표기 정리. 근데 이런 종류의 작업이 쌓이지 않으면 운영팀 쪽에서 데이터 정합성 문제로 개발팀에 계속 연락이 오게 된다. 정산은 특히 금전이 직결되니까, 한 번 오류가 나면 신뢰 손상이 다른 도메인보다 훨씬 빠르게 온다. 작더라도 이쪽 버그는 밀리지 않고 처리하는 게 맞다.
댓글 0
첫 댓글 달아줘.