GST 송장 데이터 모델 기초: 최소 필드, HSN 처리 방식, 준수 송장 생성과 조정을 단순화하는 관리자 화면 요구사항.

대부분의 GST 송장 문제는 ‘복잡한 세법’ 문제가 아닙니다. 데이터 누락이나 일관성 없는 자료가 원인입니다. 감사에서 실패하는 이유는 송장을 판매 항목, 거래 상대, 공급지, 세액 산출 방식과 깔끔하게 연결하지 못하기 때문입니다.
흔한 원인 중 하나는 HSN이 없거나 오래되었거나 잘못된 수준에 적용된 경우입니다. 팀이 제품에 HSN을 저장해도 송장 라인은 다른 SKU명이나 옵션에서 생성되어 최종 문서에 HSN이 반영되지 않는 일이 종종 생깁니다. 또 흔한 문제는 잘못된 세금 분할입니다. 배송 주소만 보고 공급지를 추정해 IGST를 부과해야 할 곳에 CGST+SGST를 부과(또는 그 반대)하는 경우가 있습니다. 이는 공급지 결정을 위해 사용된 주 코드(state code)를 저장하지 않았기 때문입니다.
재무팀은 그 즉시 영향을 받습니다. 조정 작업이 매일의 수작업이 됩니다: 송장 합계가 주문과 맞지 않고, 주문이 결제 게이트웨이 정산과 일치하지 않으며, 환불은 일련의 수동 메모로 이어집니다. 라인 항목별 작은 반올림 차이도 송장 PDF, GST 보고서, 장부 간 불일치를 만들 수 있습니다.
다음 패턴이 대부분의 불일치 고통을 유발합니다:
GST 송장 데이터 모델의 목표는 단순합니다: 모든 숫자를 재현하고 설명할 수 있도록 주문, 제품, 당사자, 세금, 송장, 신용장에 대해 최소한의 필드를 저장하세요. 작게 유지하되 세금 유형, 요율, 보고에 법적으로 중요한 필드는 절대 제거하지 마세요.
GST 송장을 쉽게 생성하고 나중에 쉽게 조정하려면 작은 객체 집합으로 시작하고 각 객체는 단일 역할만 수행하게 하세요. 깨끗한 GST 송장 데이터 모델은 테이블 수가 많음보다 사실을 시간 경과에 따라 안정적으로 유지하는 것이 중요합니다.
다음은 대부분의 팀이 첫날에 필요로 하는 핵심 레코드입니다:
**Invoice(송장)**는 Order와 분리되어야 합니다. 주문은 변경될 수 있습니다(주소 편집, 품목 취소, 부분 이행). 송장은 그러면 안 됩니다. 송장은 변경으로 인해 ‘흐르지’ 않도록 안정적인 번호, 날짜, 합계를 가져야 합니다.
세금 정확도의 중심은 Line Items(라인 항목) 입니다. 각 주문 라인(그리고 이후 각 송장 라인)은 해당 항목의 정확한 수량, 단가, 할인 및 세금 분해를 보유해야 합니다. 여기에서 HSN/SAC와 GST 요율이 실제로 적용됩니다.
재무팀을 구하는 한 가지 세부: **스냅샷(snapshot)**을 저장하세요. 송장을 생성할 때 제품 설명, HSN/SAC, 세율, 가격 정보를 송장 라인에 복사하세요. 현재의 제품 마스터에 의존하지 마세요. 요율과 이름은 변할 수 있습니다.
옵션이지만 초기에 추가할 가치가 있는 항목은 반품(Returns), 환불(Refunds), **신용장(Credit Notes)**을 별도 레코드로 두는 것입니다. 예: 두 개 항목 주문에서 고객이 하나만 반품하면 원래 송장 라인을 참조하는 신용장을 만들고 결제 환불 레코드는 게이트웨이 거래를 참조하도록 하세요. 이를 명시적 객체로 유지하면 월말 GST 장부의 수동 수정이 줄어듭니다.
Koder.ai에서 이를 구축한다면 각 객체를 먼저 간단한 화면(생성, 보기, 편집)으로 다루고, 스냅샷과 라인 수준 필드가 마련된 후에 송장 생성을 추가하세요.
HSN(상품용)과 SAC(서비스용)는 ‘송장 전용’ 세부사항이 아닙니다. 제품 또는 서비스 정의에서 시작해 송장을 발행할 때 각 송장 라인으로 복사됩니다. 이렇게 하면 혼합 장바구니도 정확해지고 각 라인이 독립적으로 감사될 수 있습니다.
실용적인 최소 데이터 모델 예시는 다음과 같습니다:
Product에 HSN/SAC를 두면 관리자 팀이 한 곳에서 유지관리하기 쉽습니다. 이를 InvoiceLine으로 복사하면 과거 송장이 안정적으로 유지됩니다. 제품이 나중에 변경되더라도 당시의 사실을 송장에서 확인할 수 있습니다. 이것이 재무 조정 시 깨지지 않는 GST 송장 데이터 모델의 핵심입니다.
HSN 저장은 단순하게 하세요: **코드(code)**는 필수, **설명(description)**은 선택, 변경 이력을 원하면 effective_from 날짜는 선택입니다. 대부분의 팀은 모든 라인 항목에 설명을 둘 필요는 없지만 예외 처리 시 재무팀에 도움이 됩니다.
혼합 장바구니는 정상입니다: 하나의 송장에 여러 라인과 여러 HSN/SAC 코드가 있을 수 있습니다. 송장 하나에 한 코드만 강제하려 하지 마세요. 합계는 송장 수준에서 집계되고 분류는 라인 수준에서 유지됩니다.
변경 관리가 문제를 일으킵니다. 간단한 규칙을 사용하세요:
관리자 화면은 Product의 세금 필드를 편집하는 한 곳과 송장 라인에서 발행 시 캡처된 내용을 확인하는 읽기 전용 보기만 있으면 충분합니다. 빠르게 화면을 구축하려면 Koder.ai와 같은 도구가 이 모델로 기본 CRUD 페이지와 데이터 테이블을 최소한의 노력으로 생성해 줍니다.
GST 송장 데이터 모델은 대부분 당사자 정보에서 실패합니다. 구매자나 판매자 신원이 조금이라도 다르면 송장이 문서상 유효하더라도 반품과 조정에서 문제가 됩니다.
판매자(seller), 구매자(buyer), 수취지(ship-to)를 동일인일 때에도 별도의 당사자로 취급하세요. 이렇게 하면 고객이 다른 배송 주소를 추가하거나 여러 GST 등록으로 판매할 때 나중에 발생하는 해킹을 방지할 수 있습니다.
필드를 단순하고 명확하게 유지하세요. 다음 항목은 송장과 보고서에서 보통 필요합니다:
주(state)는 사람이 읽을 수 있는 이름과 주 코드 두 가지로 저장하세요. 보고 및 공급지 규칙에서 코드가 자주 필요합니다.
주문에 프로필의 주소만이 아니라 청구와 배송 주소를 모두 캡처하세요. 프로필은 변경되므로 송장은 변경되면 안 됩니다.
공급지(place of supply)는 발행 시 주문에서 복사한 특정 주 코드로 송장에 저장하세요. 나중에 ‘재계산’하지 마세요. 규칙이 ‘배송지 기준’이면 그 결과와 해당 결정을 내리기 위해 사용된 주 코드를 함께 저장하면 감사와 분쟁 해결이 쉬워집니다.
B2B인 경우 구매자 GSTIN은 일반적으로 필수이며 입력 시 길이와 형식을 검증해야 합니다. B2C인 경우 GSTIN은 비어 있을 수 있지만 CGST/SGST 또는 IGST 적용 여부를 결정하기 위해 전체 주소와 주는 여전히 필요합니다.
대부분 시스템에 유용한 단순 규칙: 구매자 GSTIN이 있으면 B2B로 처리하고, 없으면 B2C로 처리하세요. 예외가 필요하면 customer_type 필드를 따로 저장하세요.
지점이나 사업부마다 다른 GST 등록이 있다면 “Seller Entity”를 별도 레코드로 모델링하고 각 레코드에 고유 GSTIN과 주소를 두세요. 각 주문은 정확히 하나의 seller entity를 참조하고 각 송장은 발행 시 해당 세부사항을 복사해 과거 송장이 나중에 판매자 주소가 변경되더라도 정확하게 유지되도록 하세요.
Koder.ai 같은 도구가 이러한 레코드의 관리자 폼을 빠르게 생성해 주지만 핵심 구조는: 판매자 엔터티 분리, 주문 시 스냅샷, 그리고 명시적 공급지 주 코드입니다.
가장 일반적인 분할은 간단합니다: 공급지가 공급자와 동일한 주면 CGST + SGST, 다른 주면 IGST입니다. 시스템은 ‘합계에서 나중에 재계산’해서는 안 됩니다. 작은 차이(반올림, 할인, 배송)가 불일치를 만듭니다.
최소한 세금 숫자는 송장 헤더가 아니라 송장 라인 수준에 저장하세요. 이렇게 하면 송장의 모든 루피를 설명하고 제품, HSN, 수익으로 다시 매칭할 수 있습니다.
실용적인 라인별 최소 필드 예시는 다음과 같습니다:
할인은 시스템이 복잡해지는 지점입니다. 한 가지 규칙을 정하고 명확히 저장하세요. 할인으로 과세 전 가격을 낮춘다면(품목 할인 및 쿠폰의 일반적 방식) 원래의 총액, 할인액, 결과 과세표준을 저장하세요. 주문 수준 쿠폰이 있다면(보통 라인별 과세표준 비율에 따라) 각 라인에 할당된 할인액을 저장해 세금 계산이 설명 가능하도록 하세요.
반올림은 일관되게 적용하고 기록하세요. 라인 수준에서 반올림할지 송장 수준에서만 반올림할지 선택하고 인쇄한 반올림 결과를 저장하세요. 많은 팀은 라인별로 세금을 계산하고 소수점 둘째 자리로 반올림한 후 합산하고 마지막에 invoice_rounding_adjustment 필드로 정확한 결제액을 맞춥니다.
배송 및 취급비는 숨겨진 추가 항목이 되어서는 안 됩니다. 별도의 송장 라인으로 취급하고 자체 HSN/서비스 코드와 세율 규칙을 적용하세요. 예: 두 제품과 배송비가 있는 주문은 각각 과세표준과 세금 구성 항목을 가진 세 개의 라인으로 처리되어 재무 조정이 쉬워집니다.
세금이 계산된 후에도 송장은 유효하고 감사 가능하며 나중에 조정하기 쉬운 “문서” 필드를 필요로 합니다. GST 송장 데이터 모델에서 송장 헤더는 법적 기록처럼 취급하세요: 미래에 제품이나 고객 데이터가 변경되더라도 안정적이어야 합니다.
우선 헤더 기본 항목을 저장하세요: 송장 번호, 발행일(송장에 기재되는 날짜), 송장 유형(세금 송장, 수출, B2B, B2C 등), 통화. 대부분 INR로 청구하더라도 통화를 저장하면 수출이나 다중 통화 마켓플레이스에서 발생하는 엣지 케이스를 피할 수 있습니다.
번호 관리는 많은 팀을 힘들게 합니다. 시리즈나 접두사(예: “FY25-INV-”)를 유지하고 재무 연도도 저장하며 데이터베이스 수준에서 고유성을 강제하세요. 또한 관리자가 동시에 같은 번호를 발행하지 못하도록 시리즈별 “다음 번호” 제어를 관리자에 저장하세요.
합계는 명시적으로 저장해야 합니다. 도출만 하지 마세요. 소계(과세표준), 총 세액, 총액, 별도 반올림 금액을 저장하세요. 라인 항목에서 나중에 재계산하면 작은 규칙 변경으로 옛 송장과 신고 값이 달라질 수 있습니다.
상태는 실생활의 수명주기를 반영하고 필요 시 레코드를 잠그게 하세요:
마지막으로 생성된 아티팩트 메타데이터: PDF 템플릿 버전, 생성 타임스탬프, 파일 식별자를 저장하세요. 해시(hash)는 선택 사항이지만 PDF가 변경되지 않았음을 증명해야 할 경우 유용합니다.
예: 지원 담당자가 템플릿 업데이트 후 PDF를 재생성하면 송장 합계와 번호는 동일하게 유지되어야 하지만 저장된 템플릿 버전이 PDF 레이아웃이 달라진 이유를 설명해 줍니다.
깨끗한 GST 송장을 원하면 송장 화면에서 시작하지 마세요. 그것을 생성하는 입력 화면에서 시작하세요. 좋은 GST 송장 데이터 모델은 이러한 입력이 통제되고 일관될 때 작게 유지됩니다.
제품 마스터는 이후 불일치의 시작점입니다. 엄격하게 관리하세요. 각 SKU는 정확히 하나의 기본 HSN(서비스는 SAC), 기본 GST 요율 및 특정 날짜에만 적용되는 예외를 가져야 합니다.
실용적인 제품 화면은 보통 다음을 필요로 합니다:
‘계산기’ UI를 피하세요. 대신 시스템이 일관되게 적용할 수 있는 입력을 저장하세요: 요율 테이블, 따르는 공급지 규칙, 그리고 intra-state vs inter-state를 결정하는 방식(보통 공급자 주와 배송지 주를 비교).
세금 화면은 요율을 카테고리/HSN 그룹별로, 유효 날짜, 그리고 구매자가 유효한 GSTIN을 제공했을 때 무엇을 할지에 대해 집중하세요.
고객 화면은 GSTIN과 검증 상태, 기본 청구 및 배송 주소를 캡처해야 합니다. 사용자가 자유롭게 주를 입력하지 못하게 하고 통제된 목록을 사용하세요. 그래야 “KA”와 “Karnataka”가 서로 다른 값이 되지 않습니다.
회사 프로필 화면도 중요합니다: 법적 명칭, GSTIN, 등록 주소, 송장 시리즈 설정(접두사, 다음 번호, 회계연도 경계). 권한으로 이를 잠그세요. 변경은 모든 미래 문서에 영향을 줍니다.
복잡한 시스템이 필요하지는 않지만 추적 기록은 필요합니다. 누가 HSN/SAC, GST 요율, 송장 시리즈 설정, 회사 GSTIN을 변경했는지와 이전 값, 새 값, 타임스탬프, 변경 사유를 기록하세요.
Koder.ai와 같은 도구로 화면을 구축한다면 감사 로깅과 유효 날짜를 처음부터 주요 필드로 취급하세요. 초기에 추가 비용이 거의 없고 나중에 재무 검토 시 수시간을 절약합니다.
적법한 송장은 멋진 서식보다 적절한 시점에 사실을 고정하는 것입니다. 이 흐름을 중심으로 GST 송장 데이터 모델을 설계하면 재무작업이 조사 작업이 아니라 단순한 매칭이 됩니다.
세금을 계산하기 전에 주문 스냅샷을 잠그세요: 품목, 수량, 단가, 할인, 배송/취급비, 고객 GSTIN(있다면), 청구 및 배송 주소, 공급지 신호. 스냅샷은 제품 가격이나 HSN 매핑이 나중에 변경되더라도 변경되면 안 됩니다.
스냅샷에서 세금을 계산하고 송장 라인을 생성하세요. 각 송장 라인은 발행 시점의 HSN/SAC, 세율, 과세표준, 세액을 복사해야 하며 나중에 실시간 조회하면 안 됩니다.
송장 번호와 발행일을 할당한 다음 발행 상태로 표시하세요. 이 시점부터 송장 레코드의 가격, 세율, HSN 코드, 주소에 대한 편집을 차단하세요. 허용이 필요하면 재무에 영향을 주지 않는 메모나 내부 태그로 제한하세요.
발행된 송장에서 PDF/인쇄 보기를 생성한 뒤 신고할 최종 합계(과세표준 합계, CGST/SGST/IGST 합계, 반올림, 총액)를 저장하세요. 추가 안전을 원하면 문서 버전이나 체크섬을 저장해 출력물이 저장된 숫자와 일치함을 증명하세요.
발행 후 변경은 규칙을 따라야 합니다:
관리자 화면에 이 흐름을 반영하면 팀은 재무 조정을 깨뜨리지 않고 빠르게 송장을 발행할 수 있습니다.
결제를 주문의 단일 “지불/미지불” 플래그로 취급하면 조정이 복잡해집니다. 결제와 환불을 주문과 송장을 가리키는 별도 레코드로 유지해 재무가 은행 정산을 매칭할 수 있게 하세요.
적법한 송장은 발행 후 안정되어야 합니다. 고객이 부분 결제하거나 나중에 환불이 발생하면 그 이동을 결제 또는 환불 엔트리로 기록하고 송장 합계를 변경하지 마세요.
보통 조정을 쉽게 하는 최소 필드는 다음과 같습니다:
고객이 한 항목을 반품하면 ‘송장을 줄이지’ 말고 원래 송장에 연결된 신용장을 발행하세요. 송장 레지스터는 깨끗하게 유지되고 환불은 신용장에 연결됩니다.
재무에게 한 화면에서 다음 질문에 답하게 하세요: 발행된 내역, 수납된 내역, 미지급 내역, 환전된 내역은 무엇인가? 연령대(0-7, 8-30, 31-60, 60+일)와 관련된 결제 및 환불 항목으로 드릴다운할 수 있게 하세요.
월별로 대부분의 팀이 필요로 하는 내보내기 목록:
예: 주문 금액이 Rs 10,000이고 오늘 Rs 6,000을 지급하고 다음 주 Rs 4,000을 지급하면 송장 금액은 Rs 10,000으로 유지됩니다. 재무 뷰는 두 번째 정산이 올 때까지 잔액 Rs 4,000을 보여주고, 정산 후 전액 수납으로 표시합니다. 송장 발행 문서는 변경되지 않습니다.
대부분의 GST 송장 문제는 ‘세법 논리’ 문제가 아니라 기록 관리 문제입니다. PDF의 수치가 재무 내보내기와 맞지 않거나 몇 달 뒤 송장을 설명할 수 없는 상황이 발생합니다.
첫 번째 함정은 화면에서만 세금을 계산하는 것입니다. 누군가가 송장을 열 때마다 CGST/SGST/IGST를 다시 계산하면 요율 변경, 반올림 규칙 변경, 버그 수정 후에 결국 서로 다른 결과가 나옵니다. 발행 시 사용한 계산된 세금 분해를 저장하세요(입력값도 함께 저장할 수 있음).
두 번째 함정은 발행된 송장을 편집하도록 허용하는 것입니다. 송장이 최종이면 변경은 신용장이나 대체 흐름을 통해 이루어져야 합니다. 그렇지 않으면 ‘고객에게 발송된 PDF가 장부와 왜 다른가?’라는 논쟁이 생깁니다.
GST 송장 데이터 모델에서 자주 발생하는 불일치 패턴:
간단한 예: 구매자가 Karnataka에 있고 배송지는 Maharashtra인 경우, 시스템이 실수로 청구 주를 공급지로 선택하면 CGST+SGST를 부과해야 할 곳에 IGST가 잘못 적용될 수 있습니다. 실시간으로 세금을 재계산하면 그 오류가 나중에 ‘스스로 고쳐진 것처럼’ 보이며 재무는 발행 문서와 일치하지 않는 숫자를 보게 됩니다.
관리자 화면을 만들 때(맞춤 또는 Koder.ai 같은 플랫폼을 사용하든) 작은 가드레일을 추가하세요: 발행된 송장은 잠그고, 공급지 입력 옆에 계산된 세금 유형을 보여주며, 발행 시 사용한 HSN, 요율, 반올림 내역을 불변 스냅샷으로 보관하세요.
송장을 고객에게 보내거나 ‘발행’으로 표시하기 전에 빠른 점검을 실행하세요. 대부분의 작은 실수가 나중에 큰 조정 문제로 번집니다. GST 송장 데이터 모델을 구축 중이라면 이러한 검사를 검증 규칙과 관리자 UI에 포함시키는 것이 좋습니다.
간단한 예: 고객이 결제 후 배송 주소를 업데이트해 주가 변경되면 동일한 송장 번호로 세금을 바꿔 재발행하면 레지스터와 결제 기록이 일치하지 않습니다. 안전한 방법은 원래 송장을 불변으로 유지하고 조정 문서를 발행하는 것입니다.
다음 단계: 먼저 화면과 검증을 구현하고 반복하세요. Koder.ai에서는 Planning Mode로 레코드와 관리자 화면(HSN/SAC 매핑이 있는 제품, 고객/GSTIN 세부, 세금 규칙, 송장)을 설계하고 앱을 생성해 실제 주문 몇 건을 끝까지 테스트한 뒤 스냅샷과 롤백을 이용해 워크플로를 안전하게 개선하는 것이 좋습니다. 더 깊은 커스터마이제이션이나 리뷰가 필요하면 소스 코드를 내보내 전통적인 개발 프로세스에서 계속 발전시키세요.