
12 月 28 日、17 時。今日で仕事納めのはずだったのに、受信箱には「年内に領収書をいただけますか」というメールが 11 通たまっています。1 通ずつ注文番号を照合し、宛名を確認し、ひな形に転記して PDF にする。11 通で 2 時間。仕事納めは 19 時を回りました。
このシーン、Shopify でストアを運営していれば一度は経験があるのではないでしょうか。そして重要なのは、この 2 時間をなくす方法が、ストアの業種によって違うということです。BtoB 卸のストアと、個人向けの雑貨店と、越境 EC のストアでは、必要な書類も、宛名の決まり方も、発行のタイミングも異なります。
この記事では「どんなストアなら、どの発行方式が向くか」を業種・運用体制ごとに整理します。そのうえで、それぞれに合うアプリと、自分で実装する場合のコード例を紹介します。
法人のお客様は、原則として全員が経費精算をします。つまり購入者の 10 割が領収書または請求書を必要とするという前提で設計する必要があります。
このタイプのストアで一番コストになるのは、発行の手間そのものより「宛名の往復」です。法人カードで買った場合と個人カードで立て替えた場合では宛名が変わり、同じ会社でも部署によって「正式名称でないと通らない」というルールがあります。ストア側にはこの事情が見えないため、こちらで宛名を決めて発行すると、かなりの確率で修正依頼が返ってきます。
したがってこのケースの最適解は、宛名の入力欄を購入者に渡す方式です。加えて次の 3 点が要件になります。
インボイス(適格請求書)に完全対応していること。2023 年 10 月の制度開始以降、買い手が仕入税額控除を受けるには、適格請求書発行事業者の登録番号と、税率ごとに区分した対価の額・消費税額の記載が必要です。BtoB では相手が必ず控除を受けるため、ここが抜けていると即座に問い合わせになります。
振込先情報が書類に載ること。掛け売り・後払いの取引では、請求書に銀行名・支店名・口座種別・口座番号・口座名義まで載っていないと、購入者側の経理から確認連絡が来ます。
入金前でも請求書を出せること。銀行振込では「請求書をもらってから振り込む」順序になるため、支払い済み注文だけを発行対象にしていると運用が止まります。
個人向けのストアでは、領収書を求める購入者は全体の 1〜2 割程度にとどまります。ただし油断できないのは、その 1〜2 割が特定の時期に集中することです。年末の 12 月、確定申告前の 2 月、期末の 3 月。個人事業主やフリーランスのお客様が経費計上のためにまとめて依頼してくるタイミングです。
このケースで意識したいのは、書類の種類を絞ることです。個人のお客様に「領収書と請求書、どちらにしますか」と選ばせても迷わせるだけなので、発行できる書類タイプを「領収書のみ」に固定するほうが親切です。
但し書きの扱いも個人向けならではです。「お品代として」で足りる方もいれば、「書籍代として」「消耗品費として」のように用途を明示しないと経理に通らない方もいます。候補リストから選べる形にしておくと、自由入力より速く、かつ誤字も減ります。取扱商品に合わせて「衣料品代として」「雑貨代として」のような候補を足しておくと、そのまま使ってもらえる確率が上がります。
宛名を空欄にして印刷後に手書きする、という運用も個人向けでは根強く残っています。宛名の初期値を「空欄」に設定できるかどうかは、地味ですが効く分岐点です。
定期購入では、同じ購入者から毎月注文が発生します。年末にまとめて「1 年分の領収書をください」と言われると、12 件分を手作業で作ることになります。これは件数が読める分、事前に手を打ちやすいケースです。
ここでの要件は、購入者が過去の注文をさかのぼって自分で発行できることです。ただし多くの仕組みには発行できる期間の上限があり、たとえば直近 60 日以内の注文に限られる、といった制限がかかります。1 年分をまとめて出したい場合は、購入者側で毎月発行してもらう運用に誘導するか、古い注文だけストア側で対応する二段構えにします。
定期購入の案内メールに「領収書は注文状況ページからいつでも発行できます」の一文を入れておくだけで、月ごとの発行率が上がり、年末のまとめ依頼が減ります。運用側のちょっとした工夫ですが、効果は大きい部分です。
海外のお客様に日本語の領収書を送っても意味がありません。逆に、日本のお客様に英語の書類を送れば経理で弾かれます。書類の言語が購入者の言語に追従するかが、このケースの分岐点です。
注意したいのは、書式を自分で作り込むほど多言語対応が難しくなるという性質です。テンプレートを自分で編集するタイプの機能を使うと、テンプレート内に文言を直接書くことになるため、その 1 つの言語がすべての購入者に表示されます。越境 EC では、標準デザインのまま使うほうが結果的に安全というのはよくある結論です。
金額の通貨表示も確認しておきたい点です。Shopify Markets で多通貨販売している場合、購入者が実際に支払った通貨で表示されないと、購入者側で照合ができません。加えて日本の登録番号を設定しているストアでは、外貨決済でも消費税額に円換算が併記されると実務が回りやすくなります。
住所の書式も国によって違います。日本の住所は郵便番号を先頭に置く日本式、海外は西洋式が一般的で、これが自動で切り替わるかどうかで見た目の完成度が変わります。
家具、楽器、機材、オーダーメイド品のように単価が高いストアでは、領収書に対する購入者の目が厳しくなります。金額が大きいほど経費計上の必要性が高く、書類の不備が問い合わせに直結します。
このケースで見落とされがちなのが収入印紙の扱いです。紙の領収書では 5 万円以上で印紙税の対象になりますが、電子的に発行した領収書は課税文書に当たらないとされています。ところが購入者側がそれを知らないと「印紙が貼られていないのですが」という問い合わせが来ます。書類に「電子発行のため収入印紙は不要です」という趣旨の注記を入れておくと、この問い合わせが構造的になくなります。
角印(社印)の有無も、高額商材では効きます。法的には必須ではありませんが、押印済みの体裁になっているだけで「正式な書類だ」という安心感が生まれます。角印の画像をアップロードできる仕組みなら、背景を透明にした PNG を用意しておくと発行者情報の上にきれいに重なります。
購入者が注文状況ページから、自分で領収書・請求書を表示・印刷・PDF 保存できるアプリ。
特徴・機能
ここまでに挙げた 5 つのケースのうち、ケース1(BtoB 卸)とケース2(個人向け物販)には特に噛み合います。宛名の入力欄を購入者に渡す設計なので、BtoB で起きる「法人名で再発行してほしい」という往復が構造的になくなります。個人向けでは発行できる書類タイプを「領収書のみ」に絞れるため、購入者を迷わせません。但し書きの候補リストは初期値が「お品代として」「商品代として」「ご購入代金として」の 3 つで、取扱商品に合わせて追加・削除できます。
ケース1 で必要になる「入金前の請求書発行」も、基本設定の「発行対象」を「すべての注文」に切り替えるだけで対応できます。振込先情報は請求書タブに専用の入力欄があり、空欄にしておけば書類に表示されません。銀行名から口座名義まで書いておくと、購入者側の経理からの確認連絡が減ります。請求書専用のフッター文言も領収書とは別に設定できるので、振込手数料の負担についての取り決めをここに書いておく、といった使い方ができます。
ケース4(越境 EC)では、標準デザインのまま使うのが正解になります。購入者の言語に応じて 20 言語で自動表示され、金額は購入者が支払った通貨で表示されます。日本の登録番号を設定していれば、外貨決済でも消費税額に円換算が併記されます。住所は所在国に合わせて自動で整形されるため、日本の住所は日本式、海外の住所は西洋式で出力されます。逆に Liquid テンプレートを編集すると言語切替に対応しなくなるので、多言語のストアはこの機能を使わない判断が正解です。
ケース5(高額商材)向けには、収入印紙の注記を表示する設定が用意されています。オンにすると「電子発行のため収入印紙は不要です」という趣旨の注記が領収書に入り、印紙に関する問い合わせを防げます。角印の画像アップロードも標準機能なので、押印済みの体裁で発行できます。
運用のコツをいくつか挙げておきます。まず、インストール直後にやることは 3 つだけです。設定の「店舗情報」タブで発行者情報を確認・修正し、「インボイス」タブで登録番号を入力し、注文状況ページの編集画面でアプリを追加して保存する。この 3 つで動く状態になります。店舗情報は Shopify に登録済みのストア情報が自動で入るので、正式表記に直したいところだけ書き換えれば済みます。
次に、設定を触ったら必ずプレビュータブで確認してください。特に帯の色を淡い色に変えた場合は、文字色も濃い色に変えないと帯の文字が読めなくなります。プレビューは保存前の編集中の設定をそのまま反映するので、テスト注文を作らなくても仕上がりを確認できます。
最後に、購入者向けの案内です。注文状況ページの文言は空欄にしておけば購入者の言語で自動翻訳されますが、注文確認メールや発送通知メールのテンプレートに「領収書は注文状況ページからご自身で発行いただけます」の一文を足しておくと、問い合わせが来る前に自己解決してもらえます。書類ページのリンクは発行から 30 分間有効で、期限が切れても何度でも発行し直せることも併記しておくと親切です。
価格設定
PDF の請求書を生成し、顧客ポータルからのダウンロードや自動送信に対応するアプリ。
特徴・機能
多言語ストアでの書式管理に強いアプリです。言語ごとにテンプレートを持てるため、ケース4(越境 EC)で「言語別に文面を作り分けたい」という要件があるなら候補になります。シンプル領収書セルフ発行が標準デザインの自動多言語化で対応するのに対し、Vify は言語ごとにテンプレートを作る方式なので、文面まで言語別に作り込みたいかどうかで使い分けるとよいでしょう。一方で、購入者がその場で宛名や但し書きを入力する体験は主眼ではないため、日本特有の宛名の入れ替え依頼を減らす目的には向きません。
価格設定
Shopify の Order Printer 用テンプレートを買い切りで提供するアプリ。
特徴・機能
月額費用を一切かけたくないストア向けの選択肢です。Shopify 公式の Order Printer にテンプレートを追加する形なので、アプリを増やさずに書類の見た目だけ整えられます。シンプル領収書セルフ発行が「購入者が自分で出す」ための道具であるのに対し、F+2 は「ストア側が印刷するときの書式」を用意する道具です。 購入者向けの導線は含まれないため、問い合わせ対応をなくしたい場合は別の手段が必要になります。
価格設定
PDF 請求書の一括生成と ZIP ダウンロード、VAT 内訳や見積書に対応するアプリ。
特徴・機能
一括処理と輸出書類に強いアプリです。月末に全注文分の PDF をまとめて落として会計ソフトに渡す、といった運用に向きます。ケース4(越境 EC)のうち、実際に商品を海外へ発送していてコマーシャルインボイスが必要なストアでは、この機能が決め手になります。シンプル領収書セルフ発行は購入者向けの領収書・請求書に絞っているため、通関書類まで扱いたい場合は Fordeer のような輸出対応型と併用する形になります。
価格設定
TODO: 画像を入れる(Wizard Labs: Invoice Wizard のアプリストア画像)
ドラッグ&ドロップのデザイナーで請求書を組める、多通貨対応のアプリ。
特徴・機能
コードを書かずに書式を組みたい方向けのアプリです。項目の位置をマウスで動かせるため、Liquid の編集に抵抗がある場合の代替になります。シンプル領収書セルフ発行の Liquid 編集と目的は近いものの、操作方法が違うという関係です。細かく作り込みたいが HTML には触りたくない、という場合はこちらが向きます。ただし購入者セルフ発行の導線は持たないため、問い合わせ削減が主目的なら別途手当てが必要です。
価格設定

PDF 請求書を注文確認メールに自動添付し、一括印刷にも対応するアプリ。
特徴・機能
全注文に対して同じ書式の書類を機械的に配りたい場合に向きます。購入者が何もしなくても書類がメールで届くため、「聞かれる前に渡しておく」方針のストアと相性がよい構成です。シンプル領収書セルフ発行は「必要な人が、必要な宛名で、必要なときに出す」方式なので、思想が正反対です。 宛名を購入者に決めさせたいなら前者、全件自動配布で割り切るなら後者、という選び方になります。管理画面は英語のみなので、日本語運用が必須のチームは事前確認が必要です。
価格設定
アプリを使わずに、テーマ側で簡易的な印刷用ページを用意することもできます。ここでは「注文情報を読み込んで印刷用の HTML を組み立て、ブラウザの印刷機能で PDF 保存できるようにする」実装を見ていきます。今回は特に @page と改ページ制御 に重点を置きます。ここを押さえないと、A4 に収まらず 2 ページ目に 1 行だけはみ出す、という残念な出力になるためです。
まず、通常の画面とは別に印刷専用のレイアウトを作ります。テーマのヘッダー・フッター・ナビゲーションが混ざると、そのまま印刷したときに不要な要素が紙に出てしまうためです。
{% comment %} sections/print-receipt.liquid {% endcomment %}
<div class="print-doc" id="print-doc">
<header class="print-doc__band">
<h1 class="print-doc__title">領収書</h1>
</header>
<section class="print-doc__meta">
<p class="print-doc__recipient">
<span id="recipient-name"></span> 様
</p>
<p class="print-doc__amount">
金額 <strong>{{ order.total_price | money }}</strong>
</p>
<p class="print-doc__proviso">
但し <span id="proviso-text">お品代</span> として
</p>
</section>
<table class="print-doc__items">
<thead>
<tr><th>品名</th><th>数量</th><th>単価</th><th>税率</th><th>金額</th></tr>
</thead>
<tbody>
{% for line in order.line_items %}
<tr>
<td>{{ line.title }}</td>
<td>{{ line.quantity }}</td>
<td>{{ line.price | money }}</td>
<td>{{ line.tax_lines.first.rate | times: 100 }}%</td>
<td>{{ line.line_price | money }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<footer class="print-doc__issuer">
<p>{{ shop.name }}</p>
<p>{{ shop.address.zip }} {{ shop.address.summary }}</p>
<p>登録番号 T0000000000000</p>
</footer>
</div>
order.line_items をループして明細を出し、税率は line.tax_lines.first.rate から取り出しています。rate は 0.1 のような小数で入るので、times: 100 で百分率に直しています。ここで注意したいのは、1 つの明細に複数の税率が乗ることがあるという点です。first だけを見る実装は簡易版と割り切り、正確に出すなら tax_lines をすべて合算する必要があります。
ここが一番差が出る部分です。画面表示用の CSS のまま印刷すると、ブラウザ既定の余白が入り、A4 の枠から要素がはみ出します。@page で用紙と余白を明示します。
/* assets/print-receipt.css */
@page {
size: A4 portrait;
margin: 15mm 15mm 18mm 15mm;
}
@media print {
/* 印刷時はテーマの共通パーツを消す */
header.site-header,
footer.site-footer,
.announcement-bar,
.cart-drawer {
display: none !important;
}
body {
background: #fff;
margin: 0;
}
.print-doc {
width: 180mm; /* A4 幅 210mm − 左右余白 30mm */
font-size: 10.5pt; /* 印刷は pt で指定するとブラウザ差が出にくい */
color: #000;
}
/* 明細テーブルが途中で切れたとき、行の途中で割らない */
.print-doc__items tr {
break-inside: avoid;
page-break-inside: avoid; /* 旧仕様のブラウザ向け */
}
/* 発行者欄は必ず同じページに収める */
.print-doc__issuer {
break-inside: avoid;
}
/* 帯の背景色を印刷でも出す */
.print-doc__band {
background: #242424;
color: #fff;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
}
ポイントは 3 つあります。
1 つ目は size: A4 portrait と margin の明示です。指定しないとブラウザやプリンタドライバの既定値が使われ、環境によって余白が変わります。同じ書類が人によって 1 ページだったり 2 ページだったりするのは、ほぼこれが原因です。
2 つ目は break-inside: avoid です。明細の行が改ページ位置にかかると、1 行が上下に割れて読めなくなります。行単位で avoid を指定しておけば、行ごと次のページに送られます。発行者欄にも同じ指定を入れておくと、社名と住所が別ページに分かれる事故を防げます。
3 つ目は print-color-adjust: exact です。ブラウザは既定で背景色を印刷しないため、これを指定しないと帯が白く抜けます。ベンダープレフィックス付きの -webkit-print-color-adjust も併記しておくと、対応範囲が広がります。
購入者が宛名を入れられるようにします。サーバーに送らず、その場の DOM だけを書き換える実装にすれば、個人情報を保存せずに済みます。
<div class="print-doc__form no-print">
<label>
宛名
<input type="text" id="recipient-input" placeholder="株式会社〇〇" />
</label>
<label>
但し書き
<select id="proviso-select">
<option value="お品代">お品代</option>
<option value="商品代">商品代</option>
<option value="書籍代">書籍代</option>
<option value="__custom__">自由入力…</option>
</select>
</label>
<input type="text" id="proviso-custom" hidden placeholder="用途を入力" />
<button type="button" id="print-button">印刷 / PDF 保存</button>
</div>
// assets/print-receipt.js
(function () {
const recipientInput = document.getElementById('recipient-input');
const recipientName = document.getElementById('recipient-name');
const provisoSelect = document.getElementById('proviso-select');
const provisoCustom = document.getElementById('proviso-custom');
const provisoText = document.getElementById('proviso-text');
const printButton = document.getElementById('print-button');
// 宛名: 入力のたびに書類側へ反映する(送信はしない)
recipientInput.addEventListener('input', function () {
recipientName.textContent = recipientInput.value;
});
// 但し書き: 「自由入力」を選んだときだけテキスト欄を出す
provisoSelect.addEventListener('change', function () {
const isCustom = provisoSelect.value === '__custom__';
provisoCustom.hidden = !isCustom;
provisoText.textContent = isCustom ? provisoCustom.value : provisoSelect.value;
});
provisoCustom.addEventListener('input', function () {
provisoText.textContent = provisoCustom.value;
});
printButton.addEventListener('click', function () {
// 印刷ダイアログを開く。PDF 保存はダイアログの「送信先」から選んでもらう
window.print();
});
})();
window.print() はブラウザ標準の印刷ダイアログを開くだけで、PDF ファイルをサーバー側で生成しません。PDF 保存はダイアログの「送信先」で選んでもらうという考え方です。この方式にはサーバー負荷がかからないという利点がある一方、スマートフォンでは「送信先」の場所が分かりにくいため、画面上に「送信先から『PDF に保存』を選んでください」という案内を出しておく必要があります。
なお、no-print クラスを付けた入力フォームは印刷対象から外します。CSS に 1 行足しておきます。
@media print {
.no-print { display: none !important; }
}
動くものはできますが、実運用に載せるとなると次の課題が残ります。
税率の集計です。上のコードは tax_lines.first だけを見ているので、1 明細に複数税率が乗る場合や、送料の税率が商品と異なる場合に金額が合いません。適格請求書として出すなら、税率ごとに対象金額と消費税額を集計した区分表が必要になります。ここは Liquid のループとハッシュ操作で書けますが、税抜・税込の切り替えや返金の反映まで含めると、それなりの分量になります。
多言語化です。上のテンプレートは日本語の文言を直書きしているため、英語圏の購入者にもこのまま表示されます。ロケールファイルに切り出す方法もありますが、書類特有の言い回し(但し書き、収入印紙の注記など)を全言語分そろえる作業が発生します。
置き場所です。注文情報を Liquid から読めるのは注文状況ページなど限られたテンプレートで、そこに独自のセクションを差し込む方法はテーマや顧客アカウントの種類によって変わります。「実装したのに購入者側に出ない」という状態は、この置き場所の取り違えから起こります。
このあたりを自前で維持し続けるコストと、月額 $3.99 を比べたときにどちらを取るか、というのが現実的な判断になります。書式を完全に自社仕様にしたい、かつ日本語のみのストアであれば自作にも十分な合理性があります。一方、インボイス対応・多言語・返金の反映まで求めるなら、アプリに任せたほうが総コストは低くなるはずです。
BtoB 卸・法人取引が中心なら、宛名を購入者に入力させる方式と、入金前の請求書発行、振込先情報の表示が要件になります。シンプル領収書セルフ発行はこの 3 点を標準で満たします。
個人向け物販なら、発行できる書類タイプを「領収書のみ」に絞り、但し書きの候補リストを商材に合わせて整えるのが効きます。宛名を空欄にして手書きする運用も選べます。
サブスクリプションなら、月ごとに購入者が自分で発行する導線をメールで案内して、年末のまとめ依頼を減らします。
越境 EC なら、標準デザインのまま多言語の自動表示に任せるのが安全です。テンプレートを作り込むほど多言語対応から遠ざかります。
高額商材なら、収入印紙の注記と角印の画像で「正式な書類」としての体裁を整えます。
いずれのケースでも、共通する結論は同じです。発行の主語をストアから購入者に移すと、件数が増えても作業は増えません。 12 月 28 日の 17 時に受信箱を開いても、そこに領収書の依頼は届いていない、という状態を作れます。