정산 수수료 테이블 컬럼 오류 수정
목차
정산 화면은 손대기 무서운 영역 중 하나다. 숫자 하나 틀리면 바로 CS로 이어지고, 테이블 컬럼이 밀리면 수수료율이 다른 항목에 표시되는 것처럼 보여서 운영팀이 혼란스러워한다. 이번 작업은 그 두 가지를 같이 잡았다. 수수료 테이블의 th/td 컬럼 불일치 수정, 그리고 충전(카드/가상계좌) 항목을 편집 가능하게 바꾼 것.
th/td 컬럼 불일치, 왜 생기나
HTML 테이블에서 <th> 개수와 각 <tr> 안의 <td> 개수가 안 맞으면 브라우저가 알아서 렌더링해준다. 이게 문제다. 에러를 뱉지 않으니까 QA에서도 잡기가 애매하다. 겉보기엔 테이블이 정상적으로 표시되는데, 특정 컬럼의 헤더가 실제 데이터와 한 칸씩 밀려있는 상태가 된다.
수수료 테이블은 계층별 요율, 건당 수수료, 적용 구간 같은 컬럼이 있어서 밀림이 발생하면 요율 숫자가 엉뚱한 계층 아래 표시된다. 운영팀 입장에선 "왜 최하위 계층 요율이 저렇게 낮게 나오냐"는 질문이 나올 수 있는 상황.
원인은 흔한 패턴이었다. 기능 추가하면서 <th>에 컬럼을 하나 더 넣었는데, 데이터 행의 <td>는 그대로였던 것. 서버사이드 렌더링이든 클라이언트 렌더링이든 이 패턴은 반복된다. 수정 자체는 간단하지만, 발견이 늦어지면 운영 데이터 신뢰도에 영향을 준다.
간단하게 체크하는 방법은 아래처럼 컬럼 수를 상수로 빼두는 것이다.
// 테이블 컬럼 수를 상수로 관리하면 mismatch 잡기 쉬움
private static final int FEE_TABLE_COLUMN_COUNT = 5;
// 렌더링 전 validate: row.getCells().size() == FEE_TABLE_COLUMN_COUNT
프론트엔드라면 컴포넌트 단에서 columns 배열을 단일 소스로 두고 th와 td 모두 같은 배열로 순회하면 불일치가 구조적으로 불가능해진다. 이번엔 기존 코드 구조상 빠른 수정으로 갔지만, 중장기적으론 컬럼 정의를 한 곳에서 관리하는 방향이 맞다.
수수료 계층 구조와 계산 로직
이번 도메인의 수수료는 유통 계층별 차등 모델이다. 하위 계층이 더 높은 요율을 부담하고, 상위 계층은 그 차액을 마진으로 가져가는 구조.
| 계층 | 요율 | 비고 |
|---|---|---|
| 최하위 | 1.0% | 최대 부담 |
| 중간 | 0.8% | 차액 0.2% 수익 |
| 최상위 | 0.6% | 차액 0.2% 수익 |
비율 수수료에 건당 고정 수수료가 더해지는 구조라 계산은 아래처럼 된다.
// 비율 수수료 + 건당 고정 수수료 합산
long feeAmount = (long)(txAmount * feeRate) + perTxFee;
여기서 (long) 캐스팅 위치가 중요하다. 곱셈 결과를 먼저 캐스팅하면 소수점 이하가 날아가는데, 이 손실이 건당 수십 원씩 쌓이면 정산 기간 전체로는 의미있는 차이가 생길 수 있다. 정산 도메인에서 부동소수점 처리는 항상 신경 써야 하는 부분이다. BigDecimal을 쓰는 게 엄밀하지만, 성능과 가독성 트레이드오프가 있어서 팀마다 선택이 다르다.
이번에 validation도 함께 추가했다. 계층별 요율 순서 체크 - 하위 계층 요율이 상위보다 낮으면 마진이 음수가 된다. 설정 오류가 실제 정산에 반영되기 전에 잡아야 하는 조건이라 배치 실행 전에 걸러내는 게 맞다.
// 계층 요율 순서 validation
for (int i = 0; i < tiers.size() - 1; i++) {
if (tiers.get(i).getRate() <= tiers.get(i + 1).getRate()) {
throw new IllegalStateException("상위 계층 요율이 하위 계층보다 낮거나 같음: tier=" + i);
}
}
예외 메시지에 어느 계층 인덱스에서 문제가 생겼는지 같이 넣어두면 운영 로그 볼 때 훨씬 편하다.
충전 항목 편집 가능하게 바꾼 이유
카드 충전과 가상계좌 충전 항목이 기존엔 읽기 전용이었다. 정산 화면에서 보여주기만 하는 용도였던 것 같은데, 운영 과정에서 수동 조정이 필요한 케이스가 생겼다. 결제 대행사 정산 데이터와 내부 집계가 소액 차이가 나는 경우, 수동으로 맞춰야 할 때 편집이 안 되면 운영팀이 다른 경로로 우회해야 한다.
편집 가능하게 열 때 같이 고려한 것들:
- 수정 이력 남기기. 누가, 언제, 얼마에서 얼마로 바꿨는지. 정산 감사(audit) 관점에서 필수.
- 수정 권한 분리. 아무나 바꿀 수 있으면 안 되니까 특정 역할만 편집 가능하게.
- 수정 가능 범위 제한. 확정된 정산 건에 대한 소급 변경은 막는 게 맞다.
이번 작업 범위에서 이 세 가지를 다 구현한 건 아니고, 우선 편집 UI를 열어두는 것부터 했다. 이력 관리 부분은 다음 작업으로 이어지는 항목이다.
작업 규모 자체는 크지 않았다. 컬럼 수 맞추고, 유효성 검증 추가하고, 입력 필드 활성화한 게 전부다. 근데 정산 도메인은 작은 버그가 실제 금액 분쟁으로 이어질 수 있어서 이런 수정들이 더 조심스럽다. 배포 후 정산 배치 한 사이클 돌고 나서 결과 확인하는 것까지 포함해서 마무리됐다.
댓글 0
첫 댓글 달아줘.