中級向けn8n 公式テンプレート承認済み

外貨決済の為替チェック

海外の SaaS やホテルの支払いで、カードの請求額が、その日の市場レートより何%多かったのかを、計算で出すワークフローです。AI は使いません。

カード明細を Google スプレッドシートに貼ると、無料の為替 API(Frankfurter、キー不要)からレートを取り、上乗せの割合と金額を計算して、高すぎる行と、安すぎる(データの誤りを疑う)行に印を付けます。

上乗せを決めたダミーの明細10行で、すべて期待どおりに分かれました。n8n 公式テンプレートとして承認された JSON を配布します。

人の手間は、どう変わるか

Before(人が手でやっていたこと)

  • 外貨の決済ごとに、その日の為替レートを調べる
  • 外貨の額 × レートを計算して、請求額と比べる
  • 何%多かったかを出し、いつもと違う行がないかを目で探す

After(このワークフローを入れると)

  • 明細を貼るだけで、行ごとに、期待額・実際のレート・上乗せの割合と金額が出る
  • 土日は直前の営業日のレートを使い、そう書き添える
  • 上乗せが大きすぎる行、安すぎる行、レートが無い行に印が付き、Slack に要約が届く

それでも人に残ること

  • 印の付いた行を見て、カード会社の明細や入力を確かめる
  • 市場レートは物差しなので、印が付いても、手数料を取りすぎたとは限らないことを踏まえて読む

動作確認: — n8n 2.36.8 / Frankfurter API(v1) / Google スプレッドシート / Slack(無料プラン)

n8n 公式テンプレート: 英語版が n8n の審査を通過しました()。注記を読む

この記事で配っている JSON は、n8n に出した英語版と同じものです(審査のあとで n8n 側が手を入れていれば、公式のページの版のほうが新しい)。n8n が内容を保証するものではありません。 n8n 公式のページ(英語版)を見る

海外の SaaS、ホテル、カンファレンス。外貨でカードを使うと、明細には円の金額だけが載ります。その金額が、市場のレートと比べて、どれくらい多かったのかは、明細を見ても分かりません。

このワークフローは、それを計算で出します。AI は使いません。外貨の額に、その日の市場レートを掛けて「本来の額」を出し、請求額との差を、パーセントと金額で示します。

先に、一番大事な注意を書きます。市場レートは物差しであって、カード会社が使ったレートではありません。 出てくる「上乗せの割合」には、カード会社の手数料のほかに、カードの国際ブランドが使うレートとの差や、計上日のずれも含まれます(下の「数字の読み方」)。

約35秒で、仕組みの全体(音声あり。音声:VOICEVOX:雨晴はう)

fx-charge-check.json をダウンロード

n8n 公式のテンプレートとして承認されました(n8n の画面での公開の日付は、2026年10月15日)。配っているのは、n8n に出した英語版と同じファイルです。

FX statement日付・店・請求額外貨の額・通貨為替 APIFrankfurter(キー不要)通貨ごとに1回コードが計算する(AI なし)期待額=外貨 × その日のレート上乗せ%=請求額 ÷ 期待額 − 1土日は直前の営業日のレートFX check + SlackOK / High premiumBelow market など
市場レートは物差しであって、カード会社が使ったレートではない。上乗せの割合には、手数料のほかに、カード会社のレートとの差と、計上日のずれも含まれる。

使った為替 API(Frankfurter)

Frankfurter は、キーなしで使える、無料の為替レートの API です。公式のページには、キーが要らないこと、割り当て(上限の回数)がないこと(ただし、使いすぎを防ぐ制限はある)、商用でも無料で使えること、レートそのものは各提供元の規約に従うこと、が書かれています(2026年10月12日に読みました)。

このワークフローでは、期間をまとめて取る呼び出しを使います。通貨ごとに1回で、その期間の毎日のレートが返ります。

https://api.frankfurter.dev/v1/2026-09-10..2026-09-24?base=USD&symbols=JPY

試したときの返り方は、次のとおりでした。

  • 土日の日付には、レートがありません。直前の営業日のレートを使い、備考にそう書きます(2026-09-19(土)を問い合わせると、2026-09-18 のレートが返りました)
  • v1 の呼び出しで使える通貨は、30通貨でした。AED(UAE ディルハム)は 404 でした。v2 では、もっと多くの通貨が一覧に載っていますが、v2 のレートは試していないので、このワークフローは v1 を使っています

このワークフローがすること

  1. 毎月1日の9時か、Check now で、FX statement タブを読む。円(設定した基準の通貨)の行と、通貨の空の行は、国内の決済として飛ばす
  2. 外貨の行から、通貨ごとに、必要な期間を出し、為替 API を1回ずつ呼ぶ
  3. コードが計算する
    • 期待額 = 外貨の額 × その日の市場レート
    • 実際のレート = 請求額 ÷ 外貨の額
    • 上乗せの割合 = 請求額 ÷ 期待額 − 1
  4. 状態を付けて、FX check タブに書き、Slack に要約を送る
状態 意味
OK 上乗せが、決めた範囲の中
High premium 上乗せが上限(初期値4%)を超えた
Below market 市場より2%以上安い。金額か通貨の書き間違いを疑う
Rate unavailable API に、その通貨か日付のレートがない(推測では埋めない)
Check data 日付が読めない、金額が正の数でない

設定した列名が FX statement タブにないときは、見つかった列名を表示して、止まります。 黙って全行を「国内」として飛ばさないためです(領収書の突き合わせで、実際にこれが起きたので、同じ守りを入れました)。

ダミーの明細10行で試した結果

実際のカード明細は、手元にありませんでした。そこで、本物の市場レートから、上乗せの割合を決めて、ダミーの明細を作りました(2026年10月12日、本物の API で1回の実行)。

行 上乗せ(決めた値) 結果
USD 20(9/3) 2.5% OK(2.49%)
USD 45(9/10) 3.0% OK(3.0%)
USD 12.5(9/19 土曜) 2.0% OK。金曜のレートを使い、備考にそう出た
EUR 180(9/12 土曜) 4.5% High premium。金曜のレートを使った
GBP 32(9/14) 6.2% High premium
USD 30(9/21) −7% Below market
AED 100 − Rate unavailable
USD 0 − Check data
国内の3行 − 対象外として飛ばした

決めた上乗せのとおりに、すべて分かれました。Slack にも要約が届きました。コードの計算そのものは、28通りの単体テストで確かめています。

数字の読み方:市場レートは物差し

それでも、この計算が役に立つのは、ふだんと違う行を見つけるときです。いつも2〜3%の人に、7%の行があれば、何かが違います。−7%のような「安すぎる」行は、ほぼ確実に、金額か通貨の書き間違いです。

使うための設定

  1. スプレッドシート: 空のシートを作り、ID を Spreadsheet ID に貼って、Run once を1回実行する(FX statement と FX check のタブができる)。そのあと、Google スプレッドシートのノードで、そのシートを選ぶ
  2. 認証情報: Google スプレッドシートと Slack の2つだけ(為替 API にキーは要らない)
  3. 明細を貼る: 見出しの下に、日付、店名、円の請求額、外貨の額、通貨(USD などの3文字)を貼る。日付は年から(2026-09-05 など)。カード会社の CSV の列名が違えば、Config の列名を合わせる
  4. Config: 基準の通貨(初期値 JPY)、上乗せの上限と下限、さかのぼる日数を決める
  5. Check now で一度動かし、FX check タブを見てから、公開する

FX statement というタブ名は、領収書の突き合わせの Card タブと、ぶつからないように付けました。同じシートで両方を使えます。

使う前に知っておくこと

  • 明細に、外貨の額と通貨が載っている必要があります。 載っていないカード会社の明細では、使えません
  • 同じ考え方で、海外の取引先への支払い(請求書の日付、外貨の額、口座から引かれた円の額)も確かめられます
  • AI を使わないので、AI の費用はかかりません

確認していないこと

  • 実際のカード会社の CSV。 試したのは、ダミーの明細10行です
  • Frankfurter の v1 が、どの機関のレートを使っているか(公式のページには、「104の中央銀行と公的な情報源」とありますが、v1 の出典は確かめていません)
  • v2 の呼び出しでの、レートと通貨
  • 外貨の行が1行もないときの Slack の通知(計画のコードの単体テストだけで、実際には動かしていません)

次に読む

次に読む