インボイス制度 データモデリングの勘所

           · ·

はじめに

インボイス制度 (適格請求書等保存方式) を扱うシステムを設計・実装していると、 同じ論点で何度も立ち止まります。

この記事ではインボイス制度にまつわるアプリケーション設計で繰返し登場するこれらのモデリング上の論点と、現時点で筆者が落としどころにしている設計判断をまとめています。

対象は、日本の消費税・インボイス制度を扱うシステムを実装する開発者です。コード例は Go で書いてありますが、特にプログラミング言語に依存する内容ではありません。

TL;DR

ドメインの基本構造

制度の概要

インボイス制度 (正式名: 適格請求書等保存方式) は令和5年(2023年)10月1日に開始された日本の 消費税 仕入税額控除制度です。 事業者は「適格請求書発行事業者」として登録することで、消費税の請求と仕入税額控除の対象となる適格請求書 (インボイス) を発行できます。

EU や英国の VAT 制度に類似していますが、日本独自の用語と番号体系を持ちます。

主要な登場人物 (Entity)

ドメインモデリング上、押さえるべきエンティティは以下です。

日本語 英訳 (国税庁公式) 説明
適格請求書発行事業者 Business Issuer of Qualified Invoice / Qualified Invoice Issuer 登録を受けた事業者
適格請求書 Qualified Invoice 登録番号等が記載された請求書
登録番号 Registration Number T + 13桁の番号
適格請求書発行事業者公表サイト Announcement Site of Business Issuers of Qualified Invoice 国税庁の公表サイト
インボイス制度 Qualified Invoice-Based Method (Invoice System) 制度全体の英名

「適格請求書発行事業者」の英語表現問題

国税庁の公式英語表記

国税庁の個人事業主向け課税申告書(英語版) 1 では、Business Issuer of Qualified Invoice という表現が一貫して使われています。 複数形は Business Issuers of Qualified Invoice (invoice は単数のまま) です。

例:

ただしこの表現は冗長で、コードで使うには長すぎます。この他、適格請求書発行事業者の登録申請書の英語版 2 では、Qualified Invoice Issuer という英語が使われています。 コードで使うなら、こちらの方がシンプルで実用的です。(それでも充分長いですが)

コードで使う際の推奨表現

実用上、以下のいずれかが妥当です。

# 案A: 簡潔派 (推奨)
qualified_invoice_issuer

# 案B: 国税庁公式に近い
business_issuer_of_qualified_invoice  # 冗長すぎる

# 案C: 制度名を活用
invoice_issuer  # 「インボイス制度」という文脈であればこれでも通るが、一般名詞すぎて文脈なしでは意味が揺れる

個人的なおすすめは qualified_invoice_issuer です。理由は以下の通り。

関連する英訳メモ

日本語 推奨英訳 備考
登録番号 registration number registratedNumber ではない
登録年月日 registered on / registration date 日付のみなら _on
取消年月日 disposed on / disposal date 国税庁API: disposalDate
失効年月日 expired on / expire date 国税庁API: expireDate
公表事項 announcement / public information 「公表」= announcement
法人番号 corporate number 13桁、登録番号の元

登録番号の構造

形式

登録番号は T (ローマ字) + 数字13桁 の14文字で構成されます。

T4810543974266
^ ^^^^^^^^^^^^^
| └─ 13桁の数字
└─ プレフィックス "T"

個人 vs 法人による番号の違い

法人の場合:

個人事業主・人格のない社団等の場合:

「T付き」と「T無し」の使い分け

実装上、登録番号には2つの表現が存在します。

表現 桁数 用途
T4810543974266 14 (T含む) 正規表記。請求書記載、契約書、データの正本
4810543974266 13 (Tなし) 機械処理用。公表サイトURL、内部処理

国税庁公表サイトの詳細ページURLを見ると分かりやすいです。

https://www.invoice-kohyo.nta.go.jp/regno-search/detail?selRegNo=4810543974266
                                                                  ^^^^^^^^^^^^^
                                                                  T を除いた13桁

設計上の推奨: 登録番号を表す型は 1 つに統一し、正規表記 (T 付き) を内部表現とします。 T 無し 13 桁が必要な箇所 (URL クエリパラメータ等) では、メソッドで導出します。

type RegistrationNumber string  // 内部表現は "T..." 形式

// Digits は "T" を除いた13桁の数字部分を返す
func (n RegistrationNumber) Digits() string {
    return strings.TrimPrefix(string(n), "T")
}

この RegistrationNumber を QualifiedInvoiceIssuer のようなドメインモデルの属性として持たせることで、 ドメイン全体で一貫した表現を保ちつつ、必要に応じて機械処理用の形式も提供できます。

type QualifiedInvoiceIssuer struct {
    Number RegistrationNumber
    RegisteredOn       time.Time
    // ...
}

// PublicURL は当該発行事業者の国税庁公表サイトURLを返す
func (q QualifiedInvoiceIssuer) PublicURL() string {
    return "https://www.invoice-kohyo.nta.go.jp/regno-search/detail?selRegNo=" + q.Number.Digits()
}

国税庁公式APIの registratedNumber 問題

国税庁の適格請求書発行事業者公表システム Web-API およびダウンロードファイルでは、登録番号のフィールド名として registratedNumber が使われています。

{
  "registratedNumber": "T4810543974266",
  ...
}

しかし registrated という英単語は存在しません。正しくは以下です。

おそらく registrationregistered が混ざってできた和製英語、または初期実装時のタイポがそのまま標準化されてしまっているのでしょう。 このままコードベースに registrated_number を採用してしまうと、各種スペルチェックで毎回指摘されることになります。

外部 API のフィールド名は変更できないため、境界層でのみ registratedNumber を使い、ドメイン層では英語表現としても正しい RegistrationNumber を使う など、設計上の工夫が必要になります。

package nta // 国税庁APIのレスポンスを扱う境界層

type AnnouncementDTO struct {
    RegistrationNumber string `json:"registratedNumber"` // sic: should be "registered"
    Process           string `json:"process"`
    Correct           string `json:"correct"`
    // ...
}

func (d AnnouncementDTO) ToDomain() (yourapp.Announcement, error) {
    return yourapp.Announcement{
        RegistrationNumber: yourapp.RegistrationNumber(d.RegistrationNumber),
        // ...
    }, nil
}

package yourapp // ドメイン層

type QualifiedInvoiceIssuer struct {
    RegistrationNumber invoice.RegistrationNumber
    RegisteredOn       time.Time
    // ...
}

余談: QualifiedInvoiceIssuer はどの名前空間か?

ここまで QualifiedInvoiceIssuer という型名を当然のように使ってきました。改めて見ると、この型は 「日本の消費税制度」という暗黙のネームスペース にぶら下がっていることに気付きます。

InvoiceIssuerRegistrationNumber も、ドメイン全体が「日本の消費税」という前提を共有しているからこそ、この短い名前で通じています。国内向けのシステムであれば、それで何の問題もありません。

一方、複数国の税制度を扱う要件が入ってきた瞬間、この前提は揺らぎます。EU VAT や英国 VAT の Issuer と、日本のインボイス制度の Issuer が同居する文脈では、QualifiedInvoiceIssuer だけでは「どの制度の発行事業者か」が曖昧になり、読み手の認知的負荷が増します。

たとえば、EU なら VAT Identification Number (VATIN) を持つ VatRegisteredEntity、米国なら Employer Identification Number (EIN) を持つ TaxRegisteredEntity など、国ごとのネームスペースを切り、そのもとで QualifiedInvoiceIssuerVatRegisteredEntity を定義するのが望ましいでしょう。

tax:
  jp:
    invoice_registration:
      number: T4810543974266
      registered_on: 2023-10-01
  eu:
    vat:
      number: DE123456789
      country: DE
  us:
    ein:
      number: 12-3456789

参考リソース

公式

関連制度

周辺概念 (国際比較)


  1. Simplified Tax Form 2025(For Sole proprietors) https://www.nta.go.jp/english/taxes/consumption_tax/pdf/2025/simplified_00.pdf ↩︎

  2. Application for Registration as a Qualified Invoice Issuer(For domestic business enterprises)(Instructions) (PDF/699KB) https://www.nta.go.jp/english/taxes/consumption_tax/201606-9en.pdf ↩︎

comments powered by Disqus