GST請求書データモデル:HSNと注文に必要な最小フィールド
GST請求書のデータモデルの基本:最小限のフィールド、HSNの扱い、準拠した請求書作成と照合を簡素化するために必要な管理画面。

GST請求書でよく起きる失敗
大半のGST請求書の問題は「複雑な税の計算」ではなく、欠落や不整合なデータです。監査で落ちるのは、請求書が何を売ったか、誰に、どこで供給されたか、税がどう計算されたかにきれいに結びつかない場合です。
よくあるトリガーは、HSNが欠けている、古い、あるいは誤ったレベルに適用されているケースです。チームが商品にHSNを保存していても、請求書行は別のSKU名やバリアントから作られるために最終的な書類にHSNが載らないことがあります。もう一つ頻発する問題は税区分の誤りです。配送先の住所から「供給地」を推測して州コードを保存していなかったために、IGSTを請求してしまった(または逆)といったケースです。
財務チームはこれをすぐに感じ取ります。照合が日常の手作業になり、請求書合計が注文と合わず、注文が決済の入金と合わず、返金処理が一連の手作業ノートになります。行項目ごとの小さな端数差でも、請求書PDF、GSTレポート、台帳の間で不一致を生みます。
不一致の原因となるパターンは次の通りです。
- 商品と請求書の明細行で同じHSN、GST率、課税金額フィールドを共有していない。
- 税が複数箇所で計算され(カートと請求書など)、結果が異なる。
- 合計が「総額」だけで保存され、課税対象金額や各税成分の内訳がない。
- 請求書番号が編集可能、あるいはシリーズ間で重複している。
- 返金を適切なクレジットノートではなく、負の注文として記録している。
GST請求書のデータモデルの目的は単純です。注文、商品、当事者、税、請求書、クレジットノートの最低限のフィールドを保存し、すべての数字が後で再現・説明できるようにすること。小さく保つ一方、税区分や率、報告に必要な法的に重要なフィールドは落とさないでください。
必要最低限のレコードセット
GST請求書を簡単に作成し、後で照合しやすくするには、小さなオブジェクト群を用意し、それぞれ単一の役割に集中させます。きれいなデータモデルはテーブル数ではなく、事実を時間とともに安定させることにあります。
多くのチームが初日から必要とするコアレコードは次の通りです。
- Customer(顧客):誰が買ったか(名前、電話/メール、B2BならGSTIN)
- Address(住所):配送先と請求先、及び州や供給地を決めるシグナル
- Product(またはService):何を売ったか(単位、基本価格、デフォルトのHSN/SAC)
- Order(注文):商取引イベント(カート、割引、送料、ステータス)
- Payment(支払い):お金の動き(ゲートウェイ参照、方法、確定額、日付)
**Invoice(請求書)**はOrderとは別に扱うべきです。注文は変更され得ます(住所編集、項目キャンセル、部分出荷)。請求書はそうあってはなりません。番号、日付、合計が後から「ずれる」ことがないよう安定させる必要があります。
税の正確さの基点は**明細行(Line Items)**です。各注文の明細行(後に請求書の明細行)には、その項目固有の数量、単価、割引、税内訳を保持すべきです。ここにHSN/SACやGST率が適用されます。
財務チームを救う細かい工夫としては、スナップショットを保存することです。請求書を生成する際に、商品説明、HSN/SAC、税率、価格を請求書明細にコピーしてください。現在のマスターに依存すると、後で名前や率が変わったときに過去の請求書が不安定になります。
早めに追加すると便利なオプションは返品、返金、クレジットノートを別レコードとして扱うことです。例えば、2点注文のうち1点が返品された場合、元の請求書行を参照するクレジットノートを発行し、支払い返金はゲートウェイ取引を参照するようにすると、月末での手作業修正を防げます。
Koder.aiでこれを構築するなら、各オブジェクトをまずはシンプルな画面(作成、表示、編集)として扱い、スナップショットと行レベルのフィールドが整ってから請求書生成を追加してください。
HSNとSAC:モデル内での位置づけ
HSN(物品)とSAC(サービス)は「請求書だけの情報」ではありません。商品/サービス定義で始まり、請求書を発行する瞬間に各請求書行へコピーされます。これにより混合カートも正しく処理でき、各行が独立して監査可能になります。
実務的な最小データモデル例は次の通りです。
- Product:id, name, SKU, unit (UOM), base_price, tax_category_id, hsn_or_sac_type, hsn_or_sac_code
- InvoiceLine:id, invoice_id, product_id(手入力行は任意), description, unit, qty, unit_price, tax_category_id, hsn_or_sac_type, hsn_or_sac_code
ProductにHSN/SACを持たせると管理が一箇所で済みます。InvoiceLineへコピーすることで過去の請求書が安定します。商品が後で変わっても、その時点での事実が請求書に残るのが重要です。
HSN保存は単純に:コードは必須、説明は任意、**effective_from(日付)**は変更履歴を追いたいなら任意で持たせます。多くのチームは各行に詳細説明まで要らない場合が多いですが、例外チェック時に役立ちます。
混合カートは普通に起きます:一つの請求書に複数の明細行があり、それぞれ複数のHSN/SACコードを持つことが自然です。請求書単位で一つのコードに無理にまとめないでください。合計は請求書ヘッダでまとめ、分類は行レベルで保持します。
変更管理で失敗しやすいので小さなルールを設けてください。
- 発行済みの請求書行上のHSN/SACは上書きしない。
- 商品のHSN/SACが変わったら将来の注文に対してProductを更新するだけにする。
- 履歴を追うなら、既存を編集するのではなく新しいeffective_fromレコードを追加する。
管理画面としては、Productの税情報を編集できる一ヶ所と、請求書行上で発行時に何がキャプチャされたかを確認する読み取り専用ビューがあれば十分です。短期間で画面を作るなら、Koder.aiのようなツールはCRUDページやデータテーブルをこのモデルから自動生成できます。
当事者情報:GSTIN、住所、供給地
GST請求書のデータモデルで最もよく失敗するのは当事者情報です。買手や売手の情報が少しでもずれていると、請求書は形式上は有効でも申告や照合で面倒になります。
売手、買手、配送先を別々の当事者として扱ってください。たとえ同一人物でも分けておくと、顧客が別の配送先を追加した場合や複数のGST登録から販売する場合の後工程でハックする必要がなくなります。
最低限保存すべきフィールド(買手と売手)
地味で明示的なフィールドを保存してください。請求書やレポートでよく必要になるものです。
- 法的名称(請求書に表示される形)
- 商号(任意だが便利)
- GSTIN(売手は必須、買手はNULL許容)
- 電話/メール(必須でないがサポート上有用)
- 住所行、都市、州、国、PIN/郵便番号
州は表示用の名称と報告に使う州コードの両方で保存してください。多くの報告や供給地ルールは州コードに依存します。
請求先と配送先、供給地
注文上に請求先と配送先の両方をキャプチャしてください。プロフィールは変わりますが、請求書は変わるべきではありません。
供給地(place of supply)は請求書に発行時の州コードとして保存してください(注文からコピー)。後で再計算してはいけません。ルールが「配送先州」ならその結果を保存し、その判断に使った州も併せて保存しておくと監査や紛争処理が楽になります。
B2BとB2C:GSTINが必須なとき
B2Bでは買手GSTINが通常必須で、入力時に長さや形式のバリデーションを行ってください。B2CではGSTINは空でもよいですが、CGST/SGSTかIGSTかを判定するために完全な住所と州は必要です。
多くのシステムで有効なシンプルルール:買手GSTINがあればB2B、なければB2Cとして扱う。例外が必要なら明示的にcustomer_typeフィールドを持たせてください。
複数の事業体(複数のGSTIN)
支店や事業部が別々のGST登録を持つ場合は、売手エンティティを独立レコードとしてモデル化し、それぞれにGSTINと住所を持たせます。各注文は必ず一つの売手エンティティを参照し、各請求書はその詳細をコピーしておくと、売手住所が後で変わっても過去の請求書が正確に残ります。
Koder.aiのようなツールはこれらの管理フォームを素早く生成できますが、構造のポイントは:売手エンティティを分離、注文時スナップショット、供給地州コードを明示的に保存することです。
保存すべき税計算フィールド
一般的な区分は単純です:供給地が売手と同一州ならCGST+SGST、異州ならIGST。システムは「後で合計から再計算する」ようにしてはなりません。端数や割引、送料が不一致を生む主因だからです。
最低限、税は請求書行レベルで保存してください。これにより請求書上の一円単位まで説明でき、商品、HSN、収益に紐づけられます。
請求書行ごとの実用的な最低項目は次の通りです。
- taxable_value(行レベルの割引配分後)
- gst_rate_percent
- cgst_rate_percent, sgst_rate_percent, igst_rate_percent(使用した分割を保存)
- cgst_amount, sgst_amount, igst_amount(計算された金額を保存)
- line_total(taxable_value + 税額)
割引は混乱を招きやすいポイントです。ルールを一つに決めて明確に保存してください。割引が税前で価格を下げる場合(通常の行割引やクーポン)、元の総額、割引額、結果としての課税対象金額を保存します。注文全体のクーポンがある場合は、行ごとに按分(通常は各行の割引前課税値に比例)して各行に割り当て、税計算が説明できるようにしてください。
端数処理は一貫させて記録してください。端数を行ごとに丸めるか請求書レベルのみで丸めるかを選び、印字した結果を保存します。多くのチームは行ごとに税を計算して小数点2位で丸め、合算後にinvoice_rounding_adjustmentフィールドで最終的な支払額に調整します。
送料や手数料は隠れた付加項目にしてはいけません。別の請求書行として扱い、固有のHSN/サービスコードと税率ルールを持たせましょう。例えば、商品2点と送料1行の合計は3行になり、それぞれ課税対象金額や税金成分を持つため、照合がずっと楽になります。
請求書ドキュメントのデータ:番号、日付、合計、ステータス
税が計算された後も、請求書は法的に有効で監査可能なドキュメントとしてのヘッダ情報を必要とします。請求書ヘッダは将来商品や顧客データが変わっても安定するべきです。
ヘッダの基本は:請求書番号、発行日(請求書に記載する日付)、請求書タイプ(tax invoice、export、B2B、B2C等)、通貨です。主にINRでもエクスポートや多通貨マーケットプレイスのために通貨を保存することを推奨します。
番号管理はトラブルの温床です。シリーズやプレフィックス(例:"FY25-INV-")を保持し、会計年度を保存し、データベースレベルで一意性を保証してください。管理画面にシリーズごとの「次の番号」制御を置き、管理者二人が同じ番号を発行してしまう事態を防ぎます。
合計は明示的に保存してください。小計(課税対象合計)、合計税額、総額、端数調整などを保存します。後で行明細から再計算すると、小さなルール変更で過去の請求書が申告と合わなくなる恐れがあります。
ステータスは実際のライフサイクルを反映し、必要に応じてレコードをロックします。
- Draft(下書き、編集可能)
- Issued(発行済み、番号割当て、PDF生成)
- Cancelled(監査のため保持、削除しない)
- Refunded(支払いが差し戻された、場合によりクレジットノートが必要)
- Credit noted(クレジットノート発行、原請求書とリンク)
最後に生成物のメタデータも保存してください:PDFテンプレートのバージョン、生成タイムスタンプ、ファイル識別子。ハッシュはオプションですが、PDFが改ざんされていないことを証明するのに便利です。
例:サポート担当がテンプレート更新後にPDFを再生成しても、請求書の合計や番号は同一であるべきです。保存されたテンプレートバージョンはレイアウト差異の説明になります。
商品、税、顧客情報の管理画面
きれいなGST請求書を望むなら、請求書画面から始めないでください。まずはそれを支える管理ページから始めます。入力がコントロールされ一貫していれば、データモデルは小さく保てます。
商品マスター(SKUとHSN/SACの紐付け)
商品マスターは将来の不整合の発生源なので厳格に扱ってください。各SKUは正確に一つのデフォルトHSN(サービスならSAC)とデフォルトのGST率、および日付限定の例外を持つべきです。
実用的な商品画面に必要な項目は:
- SKUと商品名(請求書に表示したい形)
- HSN/SACコード、GST率、税カテゴリ(使用している場合)
- Active from/to(変更が古い請求書を書き換えないように)
- 価格上書き(特別なMRPやチャネル別価格)
- ステータス(有効/無効)と無効化の理由
税設定(率と州内/州外の判定入力)
「計算機」的なUIは避けてください。代わりに、システムが一貫して適用できる入力を保存します:率テーブル、採用する供給地ルール、売手州と配送先州を比較して州内/州外を決める方法など。
税画面は次に集中させます:HSNグループごとの税率、適用開始日、買手が有効なGSTINを提供したときとそうでないときにどう扱うか。
顧客と会社プロフィール(請求書に載る相手)
顧客画面はGSTINとその検証状態、デフォルト請求先・配送先住所をキャプチャすべきです。州は自由入力にせず制御リストを使ってください。"KA"と"Karnataka"が別の値にならないように。
会社プロフィール画面も同様に重要です:法的名称、GSTIN、登録住所、請求書系列設定(プレフィックス、次番号、会計年度境界)。これは権限でロックしてください。変更が将来のすべてのドキュメントに影響を与えます。
監査ログの基本(信頼と追跡)
複雑な仕組みは不要ですが、履歴は必須です。誰がHSN/SAC、GST率、請求書系列設定を変更したか、旧値と新値、タイムスタンプ、理由をログしてください。
Koder.aiのようなツールで構築するなら、監査ログと有効日を初日から第一級のフィールドとして扱ってください。早めに追加しておくと財務レビュー時に大きく役立ちます。
手順:注文から準拠した請求書まで
準拠した請求書は華美なフォーマットではなく、正しい事実を正しいタイミングで固定することです。このフローを中心にデータモデルを設計すれば、財務の仕事は調査ではなく単なる照合になります。
1)顧客が実際に買ったものを固定する
税を計算する前に、注文スナップショットをロックします:項目、数量、単価、割引、送料、顧客GSTIN(あれば)、請求先・配送先住所、供給地の判断材料。スナップショットは商品価格やHSNマッピングが後で変わっても変更してはいけません。
2)スナップショットを請求書行に変換(税属性をコピー)
スナップショットから税を計算し、請求書行を生成します。各請求書行はHSN/SAC、税率、課税対象金額、当時使った税額をコピーし、後でライブ参照しないようにします。
3)請求書を発行して不変にする
請求書番号と発行日を割り当て、請求書を発行済みにマークします。それ以降は請求書上の価格、税率、HSNコード、住所の編集をブロックします。許可する変更は内部メモや非財務的なタグに限定してください。
4)最終ドキュメントを生成し合計を保存する
発行済み請求書からPDF/印刷ビューを生成し、申告する合計(課税合計、CGST/SGST/IGSTの合計、端数、総額)を保存します。さらに安全を期すならドキュメントのバージョンやチェックサムを保存して、出力が保存された数値と一致することを証明できるようにします。
5)法的な手段で変更を扱う
発行後の変更はルールに従わせてください:
- 価格訂正が必要:元の請求書を参照するクレジットノート(またはデビットノート)を発行する。
- 注文が発行後にキャンセル:許される場合は請求書を取り消すか、クレジットノートを発行する。
- 顧客が発行後に住所を更新:請求書を書き換えず、適切な書類で訂正し監査ログを残す。
- 部分返金:返金対象の行/金額だけをカバーするクレジットノートを発行する。
- 代替出荷:新しい注文/請求書を作り、サイレントな編集はしない。
管理画面にこのフローを組み込めば(Koder.aiのPlanning Modeで設計するのは有効です)、チームは照合を壊さずに迅速に請求書を発行できます。
照合を楽にする:支払い、返金、台帳
支払いを注文の単一フラグ(paid/unpaid)で扱うと照合が泥沼になります。支払いと返金を注文や請求書に紐づく別レコードとして保持すれば、財務は銀行の入金と突合しやすくなります。
支払いと返金を別レコードで(請求書を編集しない)
発行済み請求書は安定させておくべきです。顧客が分割で支払う、あるいは後で返金がある場合は、支払い/返金エントリを記録し、請求書合計を編集しないでください。
照合を容易にする最低項目例:
- Payment:payment_id, order_id, invoice_id, method, gateway_name, gateway_payment_id, amount, currency, authorized_at, captured_at, settlement_date, status
- Settlement(任意だが有用):settlement_id, gateway_payout_id, settlement_date, gross_amount, fees, net_amount
- Refund:refund_id, order_id, invoice_id, payment_id, credit_note_id(発行した場合), gateway_refund_id, amount, reason, refunded_at, status
- 再利用してはいけない照合キー:order_id, invoice_id, payment_id, refund_id, credit_note_id
顧客が一つの商品を返品したら請求書を減額するのではなく、元の請求書にリンクしたクレジットノートを発行してください。請求書レジスタが綺麗に保たれ、返金はクレジットノートに紐づきます。
財務専用ビューとエクスポート(時間節約)
財務には「何が発行され、何が支払われ、何が未決で、何が逆転されたか」を一画面で答えられるビューを用意してください。エイジング(0-7日、8-30日、31-60日、60日超)と支払い・返金のドリルダウンがあると便利です。
毎月必要になるエクスポート例:
- 発行請求書レジスタ(発行、取消、クレジットノート)
- 税率・HSN/SAC別の税サマリ(GST請求書データモデルに対応)
- 支払い対請求書の照合(invoice_id, payment totals, balance)
- 返金とクレジットノートのレジスタ
- ゲートウェイ決済レポート(payout_id と invoice/payment のマッピング)
例:注文が10,000円で、今日6,000円支払い、来週4,000円支払いの場合、請求書は10,000円のままです。財務ビューは残高4,000円を表示し、次の決済で支払済みに変更しますが発行済みドキュメントは変えません。
コンプライアンスと不一致を招く一般的な落とし穴
多くのGST請求書の問題は「税ロジック」ではなく記録保管の問題です。PDF上の数字が財務エクスポートと一致しない、あるいは数ヶ月後に請求書を説明できないことが原因です。
最初の落とし穴は、請求書表示時に毎回GSTを計算することです。請求書を開くたびにCGST/SGST/IGSTを再計算すると、税率変更や端数処理の変更、バグ修正で結果が変わり、最終的に異なる数字が生まれます。請求書発行時に計算した税内訳を保存してください。
二つ目は発行済み請求書の編集を許すことです。一度確定した請求書の変更はクレジットノートや置換フローで行い、編集は避けてください。さもないと「顧客に出したPDFと帳簿が違うのはなぜか」という議論が起きます。
よく出る不一致パターンは次の通りです。
- 供給地が欠けているか州コードが間違っていて、IGSTが適用されるべきところでCGST+SGSTを適用(または逆)。
- 商品のHSN/SACや税率が更新され、古い注文が新しい値で再計算される。
- 税は保存しているが、UI、PDF生成、CSVエクスポートで端数ルールが異なる。
- 割引をある箇所では税前適用、別の箇所では税後適用している。
- 返金を元の請求書への明確なリンクなしに負の行で記録している。
簡単な例:顧客住所はKarnatakaだが配送先がMaharashtraだったとします。システムが誤って請求先州を供給地に使うと、IGSTではなくCGST+SGSTを請求してしまいます。もし税を都度再計算する実装になっていると、そのエラーは後で「勝手に直る」ことがあり、財務は発行済みドキュメントと帳簿の不一致に直面します。
管理画面を作る際は小さなガードレールを入れてください:発行済み請求書をロック、供給地の入力を計算結果の横に表示、発行時に使ったHSN、率、端数処理の不変スナップショットを保持する、などです。
クイックチェックリストと次のステップ
請求書を顧客に送る、または「発行済み」にする前に素早いチェックを行ってください。小さなミスが後で大きな照合作業を生みます。データモデルを作るなら、これらのチェックをバリデーションルールと管理UIに組み込む価値があります。
発行前の請求書ごとのチェック
- 各明細行にHSN/SACがあり、実際に販売した商品/サービスと合っている。
- GSTINルールが正しく適用されている(B2BかB2Cか)、請求先と配送先の情報が矛盾していない。
- 供給地が保存され、税の分割(CGST/SGST vs IGST)が理にかなっている。
- 合計が正確に合っている:課税合計、各税成分、端数、総額。
- 発行後は請求書がロックされる。修正はクレジットノートや取消フローで行い、履歴を書き換えない。
例えば:顧客が支払い後に配送先を更新して州が変わった場合、同じ請求書番号で税を変えて再発行するとレジスタと支払い記録が一致しなくなります。安全な方法は元の請求書を不変にして、調整用の書類を作ることです。
データ+ワークフローチェック(財務をクリーンに保つため)
- 請求書番号は一意で、方針に沿って連番で、発行時にのみ生成する。
- 税額は率だけでなく計算された税金を保存する(後で率が変わってもレポートが安定する)。
- 明確なステータス遷移を持つ:Draft -> Issued -> Cancelled(とクレジットノート)。
- 期間別に照合できるレポート:請求書レジスタ合計はキャプチャ済み支払い、処理済み返金、未回収残高と一致する。
- 監査フィールドは常に存在する:作成者、発行日時、取消やクレジットノートの理由。
次のステップ:まず管理画面とバリデーションを実装し、反復で進めます。Koder.aiではPlanning Modeでレコードと管理画面(HSN/SACマッピングを持つ商品、顧客/GSTIN詳細、税ルール、請求書)をスケッチしてからアプリを生成し、実際の注文でエンドツーエンドをテストしてください。スナップショットとロールバックを使って安全にワークフローを洗練し、より深いカスタマイズやレビューが必要になったらソースコードをエクスポートして通常の開発プロセスで進めればよいでしょう。
よくある質問
HSNコードとSACコードはどこに保存すべきですか?
HSNまたはSACコードは商品またはサービスに保存し、請求書を発行する際に各請求明細へコピーします。コピーした値を使えば、後から商品マスタが変更されても過去の請求書の正確性を保てます。
1つの請求書に複数のHSNコードまたはSACコードを含められますか?
HSNまたはSACは請求明細単位で管理します。1つの注文には分類の異なる商品とサービスが含まれることがあるため、請求書全体に1つのコードだけを設定すると誤りが生じます。
IGSTとCGSTおよびSGSTはどのように選びますか?
請求書には、仕入先の州、請求先住所、配送先住所、固定の供給地州コードを保存します。仕入先の州と供給地を比較して、CGSTとSGSTの組み合わせかIGSTかを選びます。
すべての請求明細に含めるべき税務項目は何ですか?
各請求明細には、数量、単価、値引額、課税対象額、GST税率、税率ごとの内訳、税額ごとの内訳、最終明細合計が必要です。これらの項目があれば、経理は各合計を販売内容まで追跡できます。
注文と請求書は同じレコードにすべきですか?
いいえ。注文は履行中に変更されることがありますが、発行済みの請求書には固定の番号、日付、取引先情報、税額、合計が必要です。注文のスナップショットから請求書を作成し、発行後はロックします。
請求書を発行する際、どのデータをスナップショットとして保存すべきですか?
商品名、HSNまたはSAC、単位、価格、値引き、税率、税額、顧客情報、住所を請求書レコードにコピーします。過去の請求書を、現在の商品データや顧客データから計算してはいけません。
複数の販売者GSTINはどのように扱うべきですか?
GST登録ごとに個別の販売者エンティティレコードを作成します。各注文で1つの販売者エンティティを選択し、請求書にはそのエンティティの正式名称、GSTIN、登録住所をコピーします。
GSTのために注文全体の値引きを適用するにはどうすればよいですか?
注文全体の値引きは、請求明細に配分します。通常は、値引き前の各明細金額に比例して配分します。配分額を各明細に保存し、値引き後の課税対象額からGSTを計算します。
請求後に顧客が商品を返品した場合はどうすべきですか?
元の請求書は変更しません。元の請求書と対象明細を参照するクレジットノートを作成し、返金レコードは支払いとクレジットノートの両方に紐付けます。
GST照合を容易にするレコードはどれですか?
支払い、返金、決済代行会社の入金を、注文と請求書に紐付けた別々のレコードとして保存します。そうすれば、請求書を変更せずに、経理は請求額、入金額、返金、手数料、未回収残高を照合できます。