当社が運営する RIKKA M&A で、売り手の登録番号の照合を始めました。売り手が入力したインボイス(適格請求書発行事業者)の登録番号を、国税庁の「適格請求書発行事業者公表システム Web-API」で照合します。照合できた売り手にだけ、案件ページの出品者欄に「適格請求書発行事業者」と表示します。本番での照会は、2026-10-22 に始まりました。
なぜ照合が必要か
買い手が差し引ける消費税の額が変わる
WEBサイトやアプリの事業を買うと、譲渡代金のうち営業権やドメイン・コンテンツなどの資産の対価は、消費税の課税の対象です。国税庁の質疑応答事例「営業の譲渡をした場合の対価の額」では、営業権と有形固定資産が課税の対象で、土地が非課税として扱われています。
買い手が課税事業者で、売上の額から計算する方式(簡易課税・2 割特例・3 割特例)を使っていない場合は、支払った消費税を、自分が納める消費税から差し引けます(仕入税額控除)。そのためには、売り手から受け取った適格請求書を保存しておく必要があります(消費税法 30 条 7 項)。適格請求書を出せるのは、登録を受けた適格請求書発行事業者だけです。
登録していない売り手から買った場合も、経過措置で一部は差し引けます。ただし、差し引ける割合は段階的に下がります(国税庁 インボイス Q&A 問113、令和8年4月改訂)。
| 買った時期 | 差し引ける割合 |
|---|---|
| 2026-10-01〜2028-09-30 | 70% |
| 2028-10-01〜2030-09-30 | 50% |
| 2030-10-01〜2031-09-30 | 30% |
税込 1,100 万円の案件を、全額が課税の対象として今月買う場合で比べます。消費税に当たる 100 万円のうち、売り手が登録していれば 100 万円すべてを、登録していなければ 70 万円まで差し引けます。差は 30 万円です。2026-10-01 以後に始まる課税期間からは、1 人の未登録の相手からの仕入れが年に税込 1 億円を超えると、超えた分にはこの経過措置そのものが使えません。
なお、売上の額から計算する方式を使う買い手には、適格請求書の保存は要りません(国税庁「インボイス制度の理解のために」令和8年4月、13 頁)。表示が判断の材料になるのは、仕入税額控除を実際の額で計算する買い手です。
入力された番号を、そのまま表示の根拠にできない
登録番号は、売り手が自分で入力します。打ち間違い、他人の番号、取り消された番号でも、入力そのものはできます。照合せずに「適格請求書発行事業者」と出せば、確かめていないことを、当社の画面が保証する形になります。上の例のとおり、買い手はこの表示で数十万円の違いを見積もります。
番号を見せないので、買い手は自分で確かめられない
番号さえ分かれば、国税庁の公表サイトで誰でも確かめられます。ただし、公表サイトでは番号から氏名や法人名を引けます。個人の売り手の氏名もそのまま公表されています。RIKKA M&A では、一般の閲覧者に売り手の氏名を出していないため、番号も出しません。そうすると、買い手は自分では確かめられません。そこで、当社が公表情報と照合し、結果だけを表示することにしました。同業のラッコM&Aも、登録番号は公式の API で確認すると案内しています。
公表サイトではなく、Web-API で 1 件ずつ引く
公表サイトの利用規約は、検索機能に対して、スクレイピングなどのプログラムで情報を取得することを禁じています。プログラムから引くなら、国税庁にアプリケーション ID の発行を届け出て、Web-API を使います。
- 届出には、公表情報をどう取得し、どう使うかが分かる資料を添えて、審査を受けます。届出は 2026-09-28 に受け付けられ、ID は 2026-10-22 に届きました(24 日)。公表サイトの Q&A 4-3 には「1か月から1か月半程度の期間を要する場合があります」とあります
- ID は原則として、Web-API と通信するシステムごとに発行されます。同じメールアドレスで複数の届出はできないので、開発環境と本番は同じ ID を使います
- Web-API には、架空の事業者のデータを返す検証環境があります。接続先が設定されていないときの既定は、検証環境にしました。設定が欠けたときに、本番の公表情報を引かない側へ倒すためです
使うのは、登録番号を指定して 1 件を引く機能だけです(第二編「リクエストの設定方法及び提供データの内容について」2)。
GET https://web-api.invoice-kohyo.nta.go.jp/1/num?id=<アプリケーション ID>&number=T<13 桁>&type=21&history=0
type=21 は JSON、history=0 は最新の情報だけです。照会するのは、売り手が番号を入力して保存したときの 1 回です。通信に失敗したときだけ、定期処理が 15 分・1 時間・6 時間・それ以降は 1 日の間隔で照会し直します。照会し終えた番号は、照会し直しません。入力画面からの照会は、利用者ごとに 1 時間 10 回までにしています。登録の取消・失効も追いかけて照会しません(ラッコID も、登録後の状態は追わないと案内しています)。ただし、照会した時点で公表されていた取消・失効の年月日は、表示のたびに今日の日付と比べます。
**ID を記録に出さない作りにしました。**ID はクエリ文字列に載るので、HTTP クライアント(Guzzle)の例外のメッセージをそのまま記録すると、要求の URL ごと ID が残ります。利用規約は第 9 条で ID の第三者への開示を禁じています。記録するのは、失敗の種類と HTTP ステータスだけです。
もう 1 つ、利用規約の第 6 条は、取得元の明示を「このサービスは、適格請求書発行事業者公表システムWeb-API機能を利用して取得した情報をもとに作成しているが、サービスの内容は国税庁によって保証されたものではない」という文で求めています。サイトの他の文に合わせて「です・ます」に直す案もありましたが、規約が文を「」で示していて、言い換えを認める記載が見当たらないので、文言のまま入力画面とヘルプに置きました。
該当なしは、200 の空配列で返った
登録の無い番号を照会したときに、どんな応答が返るか。これは仕様書に書かれていませんでした。エラーコードの一覧(別紙2)に 0 件のコードは無く、応答の count は「条件に合致したデータの総件数」とあるだけです。
この区別は表示に直結します。
- 該当なしをエラーと取り違えると、照会が終わらず、売り手の画面は「照会待ち」のままになる
- 一時的な通信のエラーを該当なしと取り違えると、売り手に「この番号は公表されていません」と誤って伝える
実装では、200 で、照会した番号の行が無ければ「公表されていない」、HTTP のエラーは「照会が完了しなかった」として照会し直す対象にしました。ID が届いた日に、検証環境で実測しました。
| 照会した番号 | 応答 | 判定 |
|---|---|---|
T0000000000017(検証環境のサンプルデータ) | 200・announcement に 1 件 | 公表されている |
T1999999999990(形は正しく、登録の無い番号) | 200・count が "0"・announcement が [] | 公表されていない |
該当なしは HTTP のエラーではなく、200 の空の配列でした。想定と同じだったので、コードは変えていません。本番の Web-API でも、公表されている他社の番号を照会して、登録年月日まで正しく取れることを確かめました。
逆に、エラーのほうは、type=21(JSON)を指定していても、エラーコードとメッセージを CSV で返します(検証環境のページの注 3)。そのため、200 以外の応答は本文を JSON として読まず、HTTP のステータスで照会の失敗として扱っています。
自社の公表名とも、文字列では一致しない
照合では、番号が公表されているかに加えて、公表されている氏名又は名称が、本人確認で提出された名義と一致するかも確かめます。他人の番号を入れた場合や、法人の売り手が代表者個人の番号を入れた場合に、ラベルを出さないためです。
ここで、公表名は全角で公表されます(第二編 別紙1 のリソース定義書)。当社の公表名は「株式会社studio C」で、英字も空白も全角です。本人確認の「株式会社studio C」とは、文字列としては一致しません。そこで、比べる前に両方を次の順にそろえます。
- NFKC で、全角の英数字・空白・丸括弧・「㈱」を半角にする
- 「(株)」「(有)」「(同)」などの法人の種類の略記を、正式名に戻す
- 空白・中黒・ダッシュ類を取り除く(姓と名の間の区切りの違い)
- 旧字体・異体字を通用字体にする
- 英字を小文字にする
public static function normalize(string $value): string {
$value = self::nfkc($value);
$value = strtr($value, self::CORPORATE_ABBREVIATIONS);
$value = self::stripSeparators($value);
$value = KanjiVariants::toCommon($value);
return mb_strtolower($value);
}
4 の対応表は 307 組です。
- 301 組: 常用漢字表(平成22年内閣告示第2号)の本表で、見出しの字に丸括弧で添えられている康熙字典体から取りました。文化庁の PDF から抜き出し、抜き出しで括弧が落ちた「弁(辨・瓣・辯)」「餅(餠)」は、本表の画像で確かめて足しました。NFKC だけで見出しの字になる 62 組(CJK 互換漢字)は、1 で済むので除いています
- 6 組: 髙→高、﨑→崎、𠮷→吉、栁→柳、邉→辺、濵→浜。かな漢字変換で出にくく、本人確認では通用字体で入力されやすい一方、公表サイトには登録どおりの字体で載りうる字です
「嶋と島」「冨と富」のように、人名では別の字として扱われる組は入れていません。別人を同じ名義と判定しないためです。人名用漢字の表(戸籍法施行規則)は、e-Gov では画像で収録されていて文字として取り出せなかったので、出典にしていません。
公表名に丸括弧の併記(旧姓など)があるときは、括弧の外と中のそれぞれとも比べます。個人の通称・旧姓が公表されていれば、それとも比べます。それでも合わなければラベルは出さず、売り手の入力画面に公表名と本人確認の名義を並べて、合わない理由を見せます。運営が手作業で確かめる工程はありません。
番号は出さず、判定は表示のたびに行う
出品者欄に出すのは「適格請求書発行事業者」のラベルだけです。番号と公表名は、画面のテンプレートの変数にも渡していません。公表名や照会の結果は、売り手本人と運営の画面にだけ出します。
保存するのは照会の結果だけで、ラベルを出すかの判定は、表示のたびに行います。照会の結果に、そのときの本人確認の状態・名義・今日の日付(日本時間)を合わせて、「公表されていない」「取消済み」「名義が合わない」「登録日の前」などの 9 通りに分けます。
日付で判定が変わるので、表示のキャッシュに 1 つ手当てが要りました。Drupal のログインしていない人向けのページキャッシュは、キャッシュの有効期限(max-age)を見ません。登録日や取消日を迎えても、キャッシュされたページは古い判定のままです。そこで、1 日 1 回の定期処理で、その日に登録日・取消日・失効日を迎えた売り手のキャッシュタグを無効にしています。
ID が届いても、コンテナに入っていなかった
ID が届いた日、開発環境の .env に ID を書き足し、PHP のコンテナを作り直しました。それでも照会が始まりませんでした。コンテナの中で getenv() を呼ぶと、空が返ります。
原因は docker-compose.yml でした。PHP のコンテナは、environment: に 1 つずつ列挙した環境変数だけを受け取る書き方になっていて、この ID の行がありませんでした。.env に足しただけでは届かず、getenv() はエラーにならずに空を返します。照会の処理は「ID が空なら照会しない」作りなので、どこにもエラーが出ません。
同じ漏れは、これで 5 度目でした。同じ日に洗い出すと、メールの差出人と運営の宛先の 2 つは、.env にあるのにコンテナに届いていませんでした。ほかに、.env にも無い 2 つも、列挙されていませんでした。この 4 つと ID を environment: に足したうえで、同じ漏れを機械で止めるテストを書きました。
settings.phpとカスタムモジュールのコードからgetenv()を字句で拾い、すべてがdocker-compose.ymlのenvironment:に列挙されていることを確かめる- 配列をループして読むもの(
getenv($name))は配列を展開して拾い、展開できなければ黙って飛ばさずに違反にする - コンテナに渡さない環境変数は、理由を書いた例外の一覧に載せる。どのコードも読まなくなった例外も落とす
docker-compose.yml から ID の行を抜いた写しを読ませ、テストが落ちることも確かめました。本番は、この変更を載せた配備でコンテナが作り直され、照会が始まりました。
まとめ
- 登録番号の表示は、買い手が差し引ける消費税の額(いまは 100% か 70% か)に直結する。番号を伏せるなら、確かめる役目は運営側に移る
- 公表サイトの検索をプログラムで引くことは利用規約が禁じている。Web-API の ID は届出から 24 日かかったので、作り始めるときに届け出ておく
- 仕様書に書かれていない応答の形は、実装の前提として書き残し、ID が届いたら最初に実測する。Web-API の該当なしは 200 の空配列だった
- 公表名は全角で、自社名ですら文字列では一致しない。表記をそろえる規則は、別人を同じにしない範囲にとどめる
.envに書いた値が届いているかは、コードが読む環境変数と compose の列挙を突き合わせるテストで止める

