개발 slecs

채널 일괄 등록 시 계층별 요율 순서 검증 추가

목차

채널 일괄 등록 기능을 추가하면서 계층별 요율 순서 검증 로직을 함께 넣었다. 작업 자체는 크지 않았는데, 이걸 빠뜨리면 마진이 음수로 뒤집히는 조용한 버그가 생기기 때문에 반드시 처리해야 했다.

채널 포털은 외부 채널 사업자가 자신의 현황을 확인하고 설정하는 공간이다. 대시보드에서 잔액, 거래 내역, 하위 채널 현황 등을 한눈에 볼 수 있고, 수수료 설정과 마진 계산 결과도 함께 표시된다. 구조적으로는 상위-하위 채널이 트리 형태로 연결돼 있고, 각 계층마다 서로 다른 요율이 붙는다.

기존엔 채널을 하나씩 등록해야 했는데, 운영팀 요청으로 엑셀 업로드로 다수를 한 번에 넣는 일괄 등록을 붙이게 됐다. 문제는 엑셀에는 상위/하위 관계와 각 채널의 요율이 함께 들어오는데, 이 순서가 잘못 입력돼도 그냥 통과되면 곤란하다는 것이었다.

왜 요율 순서 검증이 필요했나

계층 구조에서 요율의 방향이 틀리면 마진 계산이 망가진다. 상위 채널의 요율이 하위 채널보다 낮아야 한다는 전제 아래 마진을 (하위 요율 - 상위 요율) * 거래액 으로 계산하는데, 이 순서가 뒤집히면 결과가 음수가 된다. 수수료 계산 로직은 금전 관련이라 오류가 나면 신뢰 손상으로 바로 이어진다. 조용히 잘못된 값이 쌓이는 것보다는 업로드 시점에 명확하게 튕겨내는 게 낫다.

검증 흐름은 대략 이렇다:

for each row in uploaded_rows:
    parent_rate = get_rate(row.parent_channel_id)
    child_rate  = row.rate

    if child_rate <= parent_rate:
        raise ValidationError(
            f"채널 {row.channel_code}: 하위 요율({child_rate}%)이 "
            f"상위 요율({parent_rate}%) 이하입니다."
        )

실제 구현은 조금 더 복잡하다. 업로드 파일 안에서 부모-자식 관계가 같은 파일 내에 섞여 있을 수 있어서, 행 순서에 의존하면 안 된다. 파일 전체를 파싱해서 채널 코드 기준으로 맵을 먼저 만들고, 그 다음 순회하면서 부모를 조회하는 방식으로 처리했다. DB에 이미 등록된 채널이 부모인 경우도 있어서 DB 조회도 병행했다.

오류 반환은 첫 번째 오류에서 멈추지 않고 파일 전체를 스캔해서 오류 목록을 모아 한 번에 내려준다. 행마다 하나씩 고쳐서 재업로드하는 번거로움을 줄이기 위해서다.

정산 계산에서 반올림 처리 방향

수수료 계산에서 원 단위 끊는 방식이 결과에 생각보다 많이 영향을 준다. 정책적으로 수수료를 내는 쪽에 유리하게 내림 처리하는 게 일반적이고, 분쟁도 적다. 올림으로 처리하면 사업자 입장에선 매번 1원씩 더 내는 구조가 돼서 장기적으로 불만이 쌓인다.

상황 처리 방향 이유
수수료 징수 (채널이 납부) 내림(floor) 수수료 납부자 유리 방향
정산 지급 (플랫폼이 지급) 내림(floor) 지급 초과 방지
마진 계산 표시 내림(floor) 표시값과 실지급 일치

계층이 깊어질수록 반올림 오차가 누적될 수 있어서, 중간 계산은 소수점을 유지하고 마지막 단계에서만 정수로 변환하는 게 맞다. 중간에 미리 내림하면 단계마다 오차가 쌓인다.

정산 배치는 멱등성을 꼭 보장해야 한다. 같은 기간에 대해 두 번 실행해도 결과가 동일해야 하는데, 이걸 위해 정산 키(settlement_period + channel_id)에 유니크 제약을 걸고 재처리 시 기존 레코드를 업데이트하는 방식으로 처리했다. 배치가 중간에 실패해서 부분 실행된 후 재실행될 때를 대비한 것이다.

정산 화면 숫자 표기

정산 UI에서 사용자가 가장 오래 보는 건 숫자다. 총 거래액, 수수료, 실수령액 세 가지가 핵심인데, 이 세 숫자가 명확하게 읽히지 않으면 지원 문의가 늘어난다.

표기 원칙은 단순하게 유지했다:

  • 천 단위 구분자 , 단위를 항상 붙인다 (1,234,567원)
  • 마이너스 금액은 빨간색으로 표시해서 시각적으로 바로 구분되게 한다
  • 수수료 요율은 소수점 둘째 자리까지 표시한다 (2.50%)
  • 컬럼 너비는 금액 기준으로 우측 정렬, 같은 자릿수끼리 눈으로 비교하기 쉽게

숫자 포맷을 프론트에서만 처리하면 엑셀 다운로드나 API 응답에서 포맷이 다르게 나올 수 있어서, 포맷 유틸은 공통 모듈로 뽑아 재사용하는 게 낫다. 이번엔 기존에 이미 있던 포맷터를 그대로 가져다 썼다.

작업 규모는 크지 않았지만 운영 안정성 측면에서 빠뜨릴 수 없는 변경이었다. 업로드 시점에 잘못된 데이터를 걷어내는 게, 이미 들어간 데이터를 나중에 수정하는 것보다 훨씬 적은 비용이 든다.

댓글 0

첫 댓글 달아줘.