2026/03/26

請求書PDFをAPIで自動生成する方法|JavaScript・Python・PHPコード付き

請求書自動化REST APIチュートリアルPDF生成

「毎月の請求書作成に何時間もかかっている」「Excelで手作業してミスが発生した」――こんな経験はありませんか?

PDF生成APIを使えば、請求データを渡すだけで請求書PDFの生成からメール送信まで自動化できます。この記事では、JavaScript・Python・PHPの実際のコード例を交えて、FUNBREW PDFのAPIを使った実装方法をステップバイステップで解説します。

HTMLテンプレートの作成から、単件のAPI呼び出し、月次の一括バッチ処理、Webhookによる完了通知まで、請求書自動化に必要なすべてを網羅しています。

なぜAPIで自動化するのか

手作業の問題点

  • 時間がかかる: 1件ずつExcelやWordで作成 → PDF変換 → メール添付
  • ミスが起きやすい: 金額の転記ミス、宛名の間違い
  • スケールしない: 顧客が増えると作業量が線形に増える

API自動化のメリット

  • 数秒で完了: データベースの値からPDFを自動生成
  • ミスゼロ: プログラムが計算・レイアウトするので転記ミスなし
  • スケーラブル: 100件でも10,000件でも同じコードで処理
  • 一貫したデザイン: テンプレートエンジンで統一されたフォーマット
  • 即時配信: PDF生成とメール送信をワンステップで完了

実装の全体像

注文データ → HTMLテンプレートに流し込み → PDF生成API → メール送信

必要な要素は3つだけです:

  1. HTMLテンプレート — 請求書のレイアウト
  2. データ — 顧客名、明細、金額
  3. API呼び出し — PDFの生成とメール送信

Step 1: HTMLテンプレートを作る

まず、請求書のHTMLテンプレートを用意します。FUNBREW PDFのテンプレートエンジンを使えば、{{変数名}}で動的な値を埋め込めます。

<div style="font-family: 'Hiragino Sans', sans-serif; max-width: 800px; margin: 0 auto; padding: 40px;">
  <div style="display: flex; justify-content: space-between; margin-bottom: 40px;">
    <div>
      <h1 style="font-size: 28px; margin: 0;">請求書</h1>
      <p style="color: #6b7280;">請求番号: {{invoice_number}}</p>
      <p style="color: #6b7280;">発行日: {{issue_date}}</p>
    </div>
    <div style="text-align: right;">
      <p style="font-weight: 700;">株式会社サンプル</p>
      <p style="color: #6b7280; font-size: 13px;">東京都渋谷区...</p>
    </div>
  </div>

  <div style="margin-bottom: 32px;">
    <p style="font-size: 18px; font-weight: 700;">{{customer_name}} 御中</p>
  </div>

  <table style="width: 100%; border-collapse: collapse; margin-bottom: 32px;">
    <thead>
      <tr style="background: #f8fafc;">
        <th style="text-align: left; padding: 12px; border-bottom: 2px solid #e5e7eb;">品目</th>
        <th style="text-align: right; padding: 12px; border-bottom: 2px solid #e5e7eb;">数量</th>
        <th style="text-align: right; padding: 12px; border-bottom: 2px solid #e5e7eb;">単価</th>
        <th style="text-align: right; padding: 12px; border-bottom: 2px solid #e5e7eb;">小計</th>
      </tr>
    </thead>
    <tbody>{{line_items}}</tbody>
  </table>

  <div style="text-align: right; margin-bottom: 32px;">
    <p>小計: ¥{{subtotal}}</p>
    <p>消費税 (10%): ¥{{tax}}</p>
    <p style="font-size: 20px; font-weight: 700;">合計: ¥{{total}}</p>
  </div>

  <div style="border-top: 1px solid #e5e7eb; padding-top: 16px; color: #9ca3af; font-size: 12px;">
    <p>お支払い期限: {{due_date}}</p>
    <p>振込先: サンプル銀行 渋谷支店 普通 1234567</p>
  </div>
</div>

このテンプレートをFUNBREW PDFのダッシュボードで登録しておきます。

Step 2: APIで請求書PDFを生成する

JavaScript (Node.js)

const response = await fetch("https://pdf.funbrew.cloud/api/pdf/generate-from-template", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk-your-api-key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    template: "invoice",
    variables: {
      invoice_number: "INV-2026-0042",
      issue_date: "2026/03/26",
      customer_name: "株式会社テスト",
      line_items: buildLineItemsHtml(items),
      subtotal: "150,000",
      tax: "15,000",
      total: "165,000",
      due_date: "2026/04/30",
    },
    email: {
      to: "customer@example.com",
      subject: "【請求書】2026年3月分のご請求",
    },
    options: { engine: "quality" },
  }),
});

const result = await response.json();
console.log("PDF URL:", result.data.download_url);

Python

import requests

response = requests.post(
    "https://pdf.funbrew.cloud/api/pdf/generate-from-template",
    headers={"Authorization": "Bearer sk-your-api-key"},
    json={
        "template": "invoice",
        "variables": {
            "invoice_number": "INV-2026-0042",
            "issue_date": "2026/03/26",
            "customer_name": "株式会社テスト",
            "line_items": build_line_items_html(items),
            "subtotal": "150,000",
            "tax": "15,000",
            "total": "165,000",
            "due_date": "2026/04/30",
        },
        "email": {
            "to": "customer@example.com",
            "subject": "【請求書】2026年3月分のご請求",
        },
        "options": {"engine": "quality"},
    },
)

print("PDF URL:", response.json()["data"]["download_url"])

PHP (Laravel)

$response = Http::withToken('sk-your-api-key')
    ->post('https://pdf.funbrew.cloud/api/pdf/generate-from-template', [
        'template' => 'invoice',
        'variables' => [
            'invoice_number' => 'INV-2026-0042',
            'issue_date' => '2026/03/26',
            'customer_name' => '株式会社テスト',
            'line_items' => $this->buildLineItemsHtml($items),
            'subtotal' => '150,000',
            'tax' => '15,000',
            'total' => '165,000',
            'due_date' => '2026/04/30',
        ],
        'email' => [
            'to' => 'customer@example.com',
            'subject' => '【請求書】2026年3月分のご請求',
        ],
        'options' => ['engine' => 'quality'],
    ]);

$downloadUrl = $response->json('data.download_url');

Step 3: 消費税・インボイス制度に対応する

2023年10月に開始されたインボイス制度(適格請求書等保存方式)に対応した請求書を自動生成するには、テンプレートに必要な項目を含める必要があります。

インボイス制度の必須記載項目

適格請求書には以下の6項目が必要です:

  1. 適格請求書発行事業者の氏名・名称と登録番号
  2. 取引年月日
  3. 取引内容(軽減税率対象品目の区分)
  4. 税率ごとに区分した対価の額と適用税率
  5. 税率ごとに区分した消費税額
  6. 書類の交付を受ける事業者の氏名・名称

消費税計算ロジックの実装

function calculateInvoice(items) {
  // 税率ごとにグループ化
  const standard = items.filter(i => i.taxRate === 10);
  const reduced = items.filter(i => i.taxRate === 8);

  const standardSubtotal = standard.reduce((sum, i) => sum + i.price * i.qty, 0);
  const reducedSubtotal = reduced.reduce((sum, i) => sum + i.price * i.qty, 0);

  // 端数処理は1請求書あたり税率ごとに1回(切り捨て)
  const standardTax = Math.floor(standardSubtotal * 0.10);
  const reducedTax = Math.floor(reducedSubtotal * 0.08);

  return {
    standardSubtotal,
    reducedSubtotal,
    standardTax,
    reducedTax,
    total: standardSubtotal + reducedSubtotal + standardTax + reducedTax,
  };
}

テンプレートへの反映

<!-- 税率ごとの内訳セクション -->
<div style="margin-top: 24px; border-top: 1px solid #e5e7eb; padding-top: 16px;">
  <p>登録番号: T1234567890123</p>
  <table style="width: 100%; margin-top: 8px;">
    <tr>
      <td>10%対象 小計</td>
      <td style="text-align: right;">¥{{standard_subtotal}}</td>
    </tr>
    <tr>
      <td>10%対象 消費税</td>
      <td style="text-align: right;">¥{{standard_tax}}</td>
    </tr>
    <tr>
      <td>8%対象(※軽減税率) 小計</td>
      <td style="text-align: right;">¥{{reduced_subtotal}}</td>
    </tr>
    <tr>
      <td>8%対象 消費税</td>
      <td style="text-align: right;">¥{{reduced_tax}}</td>
    </tr>
  </table>
</div>

消費税計算の端数処理は「1つの適格請求書あたり、税率ごとに1回」というルールがあります。明細行ごとに端数処理を行うと合計額が変わるため、必ず合計後に切り捨て処理を行いましょう。

Step 4: バッチ処理で月次請求を一括生成

月末に全顧客分の請求書を一括生成するなら、バッチAPIが便利です。詳しくはPDF APIバッチ処理ガイドを参照してください。

// 全顧客の請求データを配列で渡す
const response = await fetch("https://pdf.funbrew.cloud/api/pdf/batch", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk-your-api-key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    items: customers.map(c => ({
      type: "template",
      template: "invoice",
      variables: buildInvoiceVars(c),
      filename: `invoice-${c.id}-202603.pdf`,
      email: {
        to: c.email,
        subject: `【請求書】${c.name}様 2026年3月分`,
      },
    })),
  }),
});

// 結果: 全件の生成結果が返る
const { data } = await response.json();
console.log(`${data.results.length}件の請求書を生成しました`);

Webhookで生成完了を通知

PDF生成が完了したらSlackやシステムに通知したい場合は、Webhookを設定できます。

ダッシュボードの「Webhook」設定でURLを登録すると、PDF生成完了時に以下のようなPOSTリクエストが届きます:

{
  "event": "pdf.generated",
  "data": {
    "filename": "invoice-42-202603.pdf",
    "file_size": 48210,
    "download_url": "https://pdf.funbrew.cloud/dl/abc123..."
  }
}

月次スケジュール実行の自動化

月末に手動でバッチ処理を実行するのではなく、cronやタスクスケジューラで完全自動化しましょう。

Node.js(node-cron)

const cron = require('node-cron');

// 毎月末日の午前9時に実行
cron.schedule('0 9 28-31 * *', async () => {
  const today = new Date();
  const lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 0).getDate();

  if (today.getDate() !== lastDay) return; // 末日でなければスキップ

  console.log(`[${today.toISOString()}] 月次請求書バッチ開始`);

  const customers = await fetchBillableCustomers();
  const result = await generateInvoiceBatch(customers);

  console.log(`完了: ${result.success}件成功, ${result.failed}件失敗`);

  if (result.failed > 0) {
    await notifySlack(`⚠️ ${result.failed}件の請求書生成に失敗しました`);
  }
});

Laravel(タスクスケジューラ)

// app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
    $schedule->command('invoices:generate-monthly')
        ->monthlyOn(28, '09:00')
        ->timezone('Asia/Tokyo')
        ->onFailure(function () {
            // Slack通知やメール通知
        });
}

CI/CD連携(GitHub Actions)

name: Monthly Invoice Generation
on:
  schedule:
    - cron: '0 0 28 * *'  # 毎月28日 UTC 0:00
jobs:
  generate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: node scripts/generate-invoices.js
        env:
          FUNBREW_PDF_API_KEY: ${{ secrets.FUNBREW_PDF_API_KEY }}

スケジュール実行の設計パターンについてはPDF APIバッチ処理ガイドで詳しく解説しています。

本番運用のポイント

請求書PDFの自動生成を本番環境で安定運用するためのポイントをまとめます。詳細はPDF API本番運用チェックリストを参照してください。

エラーハンドリングとリトライ

月末のバッチ処理では、一部の請求書生成が失敗する可能性があります。エラーハンドリングを実装して、失敗した請求書を自動リトライしましょう。

async function generateWithRetry(customer, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await generateInvoice(customer);
    } catch (error) {
      if (attempt === maxRetries) throw error;

      // 429(レート制限)の場合は長めに待つ
      const delay = error.status === 429 ? 5000 * attempt : 1000 * attempt;
      await new Promise(r => setTimeout(r, delay));
    }
  }
}

// バッチ処理での使用
const results = { success: [], failed: [] };

for (const customer of customers) {
  try {
    const result = await generateWithRetry(customer);
    results.success.push({ customer: customer.id, url: result.download_url });
  } catch (error) {
    results.failed.push({ customer: customer.id, error: error.message });
  }
}

// 結果レポートを生成
console.log(`成功: ${results.success.length}件, 失敗: ${results.failed.length}件`);

if (results.failed.length > 0) {
  // Slackやメールで失敗リストを通知
  await notifySlack({
    text: `請求書生成結果: ${results.success.length}件成功、${results.failed.length}件失敗`,
    attachments: results.failed.map(f => ({
      text: `顧客ID: ${f.customer} - ${f.error}`,
      color: 'danger',
    })),
  });
}

セキュリティ

請求書には顧客の機密情報が含まれます。PDF APIセキュリティガイドに従い、以下を徹底してください:

  • APIキーは環境変数で管理し、本番と開発で分離
  • ダウンロードURLに有効期限を設定
  • 顧客名・金額はHTMLエスケープしてからテンプレートに渡す

レポート生成との組み合わせ

月次請求書と合わせて、月次レポートのPDF生成も自動化すると、月末業務を大幅に効率化できます。

よくある質問

テンプレートはどうやって管理する?

FUNBREW PDFのダッシュボードで作成・編集できます。HTMLとCSSで自由にデザインでき、{{変数名}}で動的な値を埋め込めます。詳しくはPDFテンプレートエンジン入門をご覧ください。

日本語フォントは対応している?

はい。Noto Sans JPをはじめとする日本語フォントがプリインストールされているため、追加の設定なしで日本語の請求書を生成できます。他のツールとの比較はHTML to PDF API比較を参考にしてください。

セキュリティは大丈夫?

請求書には企業の機密情報が含まれます。FUNBREW PDFではSSL/TLS暗号化通信、APIキーによる認証、生成ファイルの自動削除など、セキュリティ対策を実施しています。

請求書PDFのファイルサイズはどのくらい?

一般的な請求書(テキストと表のみ、画像なし)の場合、1ファイルあたり30〜80KB程度です。ロゴ画像を含む場合は100〜200KB程度になります。メール添付にも問題ないサイズです。

既存の会計ソフトと連携できる?

APIベースなので、freee・マネーフォワード・弥生会計などの会計ソフトからエクスポートしたデータを入力として使えます。CSVやJSON形式のデータを読み込み、テンプレートに流し込むだけです。

まとめ

PDF生成APIを使えば、請求書の作成・送付を完全に自動化できます。

  1. テンプレートを一度作れば再利用可能 — デザインの変更もテンプレート修正だけ
  2. APIを呼ぶだけで生成 + メール送信 — JavaScript・Python・PHPどの言語からでも
  3. バッチAPIで月次処理も一括 — 数百件の請求書も数分で処理
  4. Webhookで完了通知 — Slackや社内システムとの連携も簡単

手作業で請求書を作成している時間を、コア業務に充てましょう。まずは無料プラン(月30件)で試してみてください。テンプレートエディタで請求書テンプレートを作成し、Playgroundで動作を確認できます。

関連リンク

Powered by FUNBREW PDF