품목별 금액을 더했는데 청구 총액과 1원이 다릅니다. 작은 차이라고 무시하면 환불과 부분 취소에서 같은 문제가 반복됩니다. 금액 계산은 숫자 형식만 바꿔 끝나는 일이 아닙니다. 어떤 단계에서 자릿수를 줄이고 남는 금액을 어디에 배정할지 업무 규칙으로 정해야 합니다. 이 글은 소프트웨어 정합성 관점의 설계이며 세무·회계 기준은 별도로 확인해야 합니다.
소수 계산과 통화 표현을 구분한다
일반적인 이진 부동소수점은 일부 십진 소수를 정확하게 표현하지 못합니다. 따라서 금액 계산에는 십진 연산이나 정수 최소 단위 저장을 검토합니다. 다만 정수로 저장해도 할인율을 적용하거나 여러 품목에 나누면 다시 반올림 문제가 생깁니다.
통화마다 사용하는 소수 자릿수와 결제 수단의 처리 단위가 다를 수 있습니다. 모든 금액을 무조건 100배한 정수로 저장하는 가정은 피합니다. 금액과 통화 코드를 함께 다루고 외부 결제 서비스의 입력 단위도 확인해야 합니다.
반올림 시점이 결과를 바꾼다
개별 품목에서 반올림한 뒤 더하는 방식과 전체 금액을 더한 뒤 반올림하는 방식은 항상 같은 결과를 내지 않습니다. 수량 곱셈, 할인, 세금, 배송비의 순서까지 포함해 어느 단계의 값이 확정 금액인지 정의합니다.
화면에서는 두 자리만 보여 주면서 서버는 더 많은 자릿수로 계산할 수도 있습니다. 이 경우 표시된 중간값을 사용자가 더한 결과와 최종값이 다를 수 있습니다. 표시용 값과 계산용 값을 구분하고 차이가 생기는 이유를 설명할 수 있어야 합니다.

잔액은 규칙에 따라 배분한다
가상의 예로 최소 단위 기준 100을 세 품목에 동일하게 배분하면 33씩 나눈 뒤 1이 남습니다. 한 품목에 34를 배정해야 총액이 보존됩니다. 이때 매번 우연히 먼저 조회된 품목에 잔액을 주면 재계산 결과가 달라질 수 있습니다.
비례 배분에서는 각 품목의 정밀한 몫을 구한 뒤 절사 잔여가 큰 순서로 남는 최소 단위를 배정하는 방식을 검토할 수 있습니다. 동률에는 고정된 품목 키 같은 보조 기준이 필요합니다. 이 방식이 모든 계약에 맞는 것은 아니므로 업무 규칙을 먼저 합의합니다.
부분 환불은 원래 배분을 사용한다
주문 전체에 적용된 할인을 취소된 품목에 다시 계산하면 최초 청구 때와 다른 몫이 나올 수 있습니다. 원래 품목별로 확정한 할인액과 세액, 배분 근거를 저장하면 부분 환불을 같은 기준으로 처리하기 쉽습니다.
이미 확정한 거래를 현재 정책으로 덮어쓰지 않습니다. 변경된 정책은 새 버전으로 관리하고 과거 정정은 원거래를 참조하는 조정 기록으로 남깁니다. 금액의 합계뿐 아니라 어떤 규칙으로 만들어졌는지가 중요한 데이터입니다.

프런트엔드와 서버가 같은 규칙을 쓴다
사용자 화면의 계산은 안내용으로 제공하더라도 최종 청구액은 서버가 검증해야 합니다. 언어와 라이브러리의 기본 반올림 방식이 다를 수 있으므로 기본값에 기대지 말고 모드와 자릿수를 명시합니다. 숫자를 문자열로 주고받는 계약도 검토할 수 있습니다.
외부 입력을 십진 값으로 바꾸기 전에 이진 부동소수점을 거치면 이미 오차가 들어갈 수 있습니다. 입력부터 저장과 계산, 출력까지 자료형의 흐름을 점검합니다. 숫자 타입을 바꾼 한 줄보다 경계 전체를 일관되게 다루는 것이 중요합니다.
합계 보존을 자동 테스트한다
배분한 금액의 합이 원래 총액과 같은지, 같은 입력은 같은 결과를 내는지, 전액 환불이 원청구액을 넘지 않는지 확인합니다. 경계 자릿수, 음수 조정, 수량 변경, 동률 배분, 매우 큰 금액을 테스트 데이터에 포함합니다.
실제 정산 파일과 차이가 날 때는 중간 계산값, 정책 버전, 확정 시각을 비교할 수 있어야 합니다. 작은 금액을 임의로 맞추는 보정 코드를 추가하기 전에 최초로 달라지는 계산 단계를 찾습니다. 재현 가능한 계산이 운영 신뢰의 출발점입니다.
실무 체크리스트
- 통화 단위·반올림 모드·적용 시점을 명시했는가
- 잔액 배분 순서가 결정적이며 총액을 보존하는가
- 부분 환불이 최초 확정 배분과 정책 버전을 참조하는가
참고 자료: Python decimal의 십진 연산과 반올림 모드. 공식 문서는 십진 수와 반올림 동작을 설명합니다. 본문의 배분·환불 정책은 설계 제안이며 해당 문서가 특정 회계 처리의 적법성을 보장하는 것은 아닙니다.
본문 이미지는 이해를 돕기 위해 생성한 개념 삽화이며 실제 측정 자료나 고객 현장 사진이 아닙니다.
#금액계산 #반올림 #정산시스템 #Decimal #SaaS #청구서 #데이터정합성 #환불설계 #백엔드개발 #업무시스템