ブログに戻る

為替レート API で多通貨の経費管理を構築する

V
Vlado Grigirov
June 11, 2026
Currency API Exchange Rates Expense Management Multi-Currency Finexly Tutorial

経費管理ソフトウェアの成否は、たった一つの数字にかかっています。それは、財務チームが会社の基準通貨で目にする換算後の合計額です。経費管理のための為替レートを 1 パーセントポイントのほんの一部でも間違えれば、外貨建てのレシートは一枚残らず会計帳簿と同期がずれ、払い戻しは従業員に過払いまたは過少払いを起こし、月次の照合は端数を手作業で追い回す作業になります。本ガイドでは、為替レート API を使って多通貨の経費レイヤーを正しく構築する方法を解説します。おもちゃのようなコンバーターと、監査人が実際に受け入れるシステムとを分ける、たった一つのルールも含めて。

経費ツール、コーポレートカードのプラットフォーム、出張・経費(T&E)機能を構築する場合でも、既存の製品にレシート取り込みを追加するだけの場合でも、通貨換算のロジックは見かけによらず厄介です。素朴なアプローチ——「最新レート」エンドポイントを呼び出して掛け算する——は、デモでは正しく見えても本番では崩壊する数字を生み出します。正しくやりましょう。

なぜ経費管理に為替レート API が必要なのか

現代の経費ワークフローは、ある通貨で支出する従業員、別の通貨で報告する会社、そして時には第三の通貨で支払われる払い戻しを追跡します。ベルリンを拠点とするコンサルタントが東京へ飛び、ホテルを JPY で支払い、USD で報告する会社に勤め、払い戻しを EUR の銀行口座で受け取ります。三つの通貨、一枚のレシート。

レートをハードコードしたり、従業員に手作業で換算させたりするのは論外です。手作業の換算はミスが起きやすく、「レートの選り好み」を通じた経費不正を招き、レートが動いた瞬間に照合のずれを生みます。Expensify、Ramp、Zoho Expense といったツールが自動で為替レートを取得するのは、まさに古いレートや手作業のレートが照合を複雑にする不正確さをもたらすからです。

為替レート API は、任意の日付・任意の通貨ペアの正確なレートにプログラムからアクセスできるようにすることでこれを解決します。換算はレシートが取り込まれた瞬間に自動で行われ、その後は永遠に一貫性が保たれます。

すべての経費システムが追跡すべき三つの通貨

コードを一行書く前に、三つの異なる通貨の役割を中心にデータをモデル化してください。

  1. 取引通貨:従業員が実際に支払った通貨(レシートに印字された、またはカードに請求された通貨)。常に元の金額とともに、手を加えずに保存します。
  2. 基準通貨/報告通貨:会社の機能通貨で、総勘定元帳、レポート、予算に使用します。すべての経費は集計のためこれに換算されます。
  3. 払い戻し通貨:従業員が受け取る通貨。多くの場合は取引通貨と同じ(従業員が為替損を負わないためのベストプラクティス)ですが、時には従業員のローカルな給与通貨です。

最大の罪は元データを破壊することです。取引金額を換算後の値で上書きしては絶対にいけません。元の金額と通貨を恒久的に保存し、換算は派生値として計算します。これにより監査証跡が保たれ、レートが訂正された場合にもレポートを再実行できます。

重要なルール:今日のレートではなく、取引日のレートを使う

これが、ほとんどの「通貨コンバーター」チュートリアルが誤っており、監査で不合格になる原因となるルールです。各レシートは、取引の日付に有効だった為替レートを使って換算しなければなりません——今日のレートではありません。

これは様式の好みではありません。二大会計フレームワークの双方の要件です。IAS 21(IFRS)では、外貨建取引は当初、取引日の直物為替レートを適用して記録されます。ASC 830(US GAAP)では、各資産・負債・収益・費用は、その日に有効な為替レートを使って機能通貨で記録されます。いずれの基準でも、レートを決めるのは取引日であり——後の計上日ではなく、ましてや「レポートが提出されたとき」では決してありません。

ライブレートが帳簿を壊す理由

ある従業員が 3 月 15 日に 500 ユーロの夕食代を支払い、4 月 20 日に経費レポートを提出し、システムが 4 月 20 日のレートで換算するとします。その五週間で EUR/USD が 2% 動いていれば、報告された経費はコーポレートカードの明細に実際に計上された額に対して 10 ドルずれます。これを数千枚のレシートに掛ければ、経費補助元帳はもはや銀行フィードと一致しません。照合は悪夢となり、監査人はそれを指摘します。

解決策は単純です。レシートの取引日を指定してヒストリカルレートエンドポイントを呼び出します。Finexly ではこう書きます。

curl "https://api.finexly.com/v1/historical?date=2026-03-15&base=JPY&symbols=USD&apikey=YOUR_KEY"
{
  "success": true,
  "base": "JPY",
  "date": "2026-03-15",
  "rates": {
    "USD": 0.006712
  }
}

2026-03-15 のレートでレシートを換算し、そのレートを経費レコードに保存すれば、数字は二度と変わりません——まさに会計担当者が必要とするものです。日付の扱いや時系列クエリの詳しい解説は、ヒストリカル為替レート API ガイドをご覧ください。

換算レイヤーを構築する

中核となる換算関数を作りましょう。主な入力は、元の金額、取引通貨、基準通貨、そして決定的に重要な取引日です。

Python:取引日のレートでレシートを換算する

import requests
from datetime import date

FINEXLY_KEY = "YOUR_KEY"

def convert_receipt(amount, from_currency, to_currency, txn_date):
    """Convert a receipt amount using the rate on the transaction date."""
    if from_currency == to_currency:
        return round(amount, 2), 1.0

    url = "https://api.finexly.com/v1/historical"
    params = {
        "date": txn_date.isoformat(),
        "base": from_currency,
        "symbols": to_currency,
        "apikey": FINEXLY_KEY,
    }
    resp = requests.get(url, params=params, timeout=5)
    resp.raise_for_status()
    rate = resp.json()["rates"][to_currency]

    converted = round(amount * rate, 2)
    return converted, rate

# A ¥48,000 hotel in Tokyo on March 15, reported in USD
converted, rate = convert_receipt(48000, "JPY", "USD", date(2026, 3, 15))
print(f"Converted: ${converted} at rate {rate}")
# Store BOTH the converted value AND the rate on the expense record

この関数が換算後の金額に加えてレートも返している点に注目してください。レートを経費とともに永続化することこそ、数か月後でも換算を再現でき、監査可能にするものです。

JavaScript:Node.js での同じロジック

async function convertReceipt(amount, from, to, txnDate) {
  if (from === to) return { converted: Number(amount.toFixed(2)), rate: 1 };

  const url = new URL("https://api.finexly.com/v1/historical");
  url.search = new URLSearchParams({
    date: txnDate,          // "2026-03-15"
    base: from,
    symbols: to,
    apikey: process.env.FINEXLY_KEY,
  });

  const res = await fetch(url);
  if (!res.ok) throw new Error(`Finexly ${res.status}`);
  const data = await res.json();
  const rate = data.rates[to];

  return { converted: Number((amount * rate).toFixed(2)), rate };
}

高速かつ低コストを保つために日次レートをキャッシュする

ある日付のヒストリカルレートは決して変わらないため、キャッシュに非常に適しています。レシートをまとめてインポートする際は、日付と通貨ペアでグループ化し、レシートごとではなく各レートを一度だけ取得します。シンプルな (日付, 基準, シンボル) -> レート のキャッシュ——Redis、あるいはデータベーステーブルでも——は冗長な呼び出しを排除し、プランの上限内に余裕をもって収めます。本番品質のキャッシュと障害処理のパターンについては、API キャッシュとエラー処理のベストプラクティスのガイドをご覧ください。

rate_cache = {}

def get_cached_rate(from_currency, to_currency, txn_date):
    key = (txn_date.isoformat(), from_currency, to_currency)
    if key not in rate_cache:
        _, rate = convert_receipt(1, from_currency, to_currency, txn_date)
        rate_cache[key] = rate
    return rate_cache[key]

コーポレートカードの上乗せと海外取引手数料への対処

カード連携の経費を照合するチームをつまずかせる微妙な点があります。コーポレートカードの明細上のレートは、仲値(ミッドマーケットレート)ではありません。カードネットワークは独自の為替レートに加えて海外取引手数料を適用し、しばしば 1〜3% の範囲です。したがって Visa や Mastercard が計上する数字は、API が返す仲値とわずかに異なります。

確かな選択肢は二つあります。

  • カード連携の取引については、カードネットワークが基準通貨で実際に請求した金額を信頼してください。カード明細は、すでに動いた資金についての真実の出所です——再換算しないでください。API レートは、従業員に情報目的の仲値比較を示すためだけに使います。
  • 従業員に払い戻す自己負担(現金)のレシートについては、取引日における API の仲値が、払い戻しの公正かつ説明可能な基準となります。

どのレートがどの経費種別に適用されるかを明確にすることで、素朴な実装を悩ませる「なぜこれがカードの請求と合わないのか?」というサポート問い合わせを防げます。仲値は正直な中間点であり、なぜそれが重要なのかについては会計ソフト連携ガイドで詳しく読めます。

多通貨レポートと照合

各経費が保存済みの基準通貨額と使用レートを持つようになれば、レポート作成は単純になります。集計、予算追跡、部門別サマリーはすべて、事前計算された基準通貨の列の上で動作します——レポート時にライブ換算を行わないため、レポートは高速で、レートが動いてもずれることは決してありません。

きれいな経費レコードは次のようになります。

{
  "expense_id": "exp_8842",
  "original_amount": 48000,
  "original_currency": "JPY",
  "base_amount": 322.18,
  "base_currency": "USD",
  "rate_used": 0.006712,
  "rate_date": "2026-03-15",
  "rate_source": "finexly:historical"
}

監査人が尋ねうるあらゆる項目——何が支払われたか、どの通貨で、いくらに換算されたか、どのレートで、どの日付で、どの出所から——が記録されています。これこそ、国際的にスケールする経費システムと、月末に火消しを生むシステムとの違いです。

多通貨経費のためのアーキテクチャ・チェックリスト

リリース前に、この一覧と照らして実装を検証してください。

  • 元の金額と通貨を不変に保存する——換算値で上書きしないこと。
  • 取引日のレートで換算する——今日のレートではなく、ヒストリカルエンドポイントから取得する。
  • レートとレート日付を永続化する——監査可能性のため各経費レコードに保存する。
  • レートを (日付, ペア) でキャッシュする——高速さとプラン上限内を保つため。
  • カード連携の金額と自己負担の払い戻しを区別する——それぞれに正しいレート出所を適用する。
  • 同一通貨のケースを処理する——API 呼び出しなしで(レート = 1)。
  • 優雅に失敗する——レート取得に失敗したら、提出をブロックせずレシートをキューに入れ、後でレートを補填する。
  • 従業員が支出しうるあらゆる通貨をカバーする API を選ぶ——グローバルな従業員はエキゾチックな通貨であなたを驚かせます。

Finexly はリアルタイムとヒストリカルの双方のデータで 170 以上の通貨をカバーしており、これはまさにグローバルな経費ツールが必要とするカバレッジです。取引量が増えるにつれて、料金プランはアーキテクチャの書き直しを強いることなくあなたとともにスケールします。

よくある質問

経費レポートはどのレートを使うべきか——取引日か、提出日か? 常に取引日です。IFRS(IAS 21)も US GAAP(ASC 830)も、外貨建取引を取引が発生した日に有効な直物レートで記録するよう求めています。提出日や承認日を使うと経費を誤表示し、カード明細との照合を壊します。

なぜ換算後の金額がコーポレートカードの明細と完全には一致しないのか? カードネットワークは独自の為替レートに加えて海外取引手数料(多くは 1〜3%)を適用するため、API が返す仲値とは異なります。カード連携の経費では、カードが実際に請求した金額を真実の出所として扱い、API レートは情報目的の仲値比較にのみ使ってください。

従業員が為替で損をしないよう払い戻しをどう扱えばよいか? 可能な限り、従業員が支出したのと同じ通貨で払い戻し、換算損を負わせないようにします。ローカルな給与通貨で払い戻す必要がある場合は、取引日の仲値で換算し、使用したレートを払い戻し明細に開示してください。

数千枚のヒストリカルなレシートを効率的に換算できるか? できます。過去日付のヒストリカルレートは固定でキャッシュ可能です。レシートを日付と通貨ペアでグループ化し、各ユニークなレートを一度だけ取得して保存します。これにより、大量バッチをインポートする際でも高速さと API 上限内の余裕を保てます。

経費管理にリアルタイムレートは必要か? 中核の換算には通常不要です——ヒストリカル(日次クローズ)レートが正しく監査可能な基準です。リアルタイムレートは、取り込みの瞬間に従業員へ即時の概算を示すのに有用ですが、公式の記録は確定した取引日のレートを使うべきです。

さあ始めましょう

経費ツールに正確で監査対応の多通貨サポートを追加する準備はできましたか?無料の Finexly API キーを取得——クレジットカードは不要です。月 1,000 回の無料リクエストから始め、170 以上の通貨のリアルタイムとヒストリカルのレートを取得し、取引量の増加に合わせてスケールしてください。あなたの財務チーム——そして監査人——がきっと感謝するはずです。

Vlado Grigirov

Senior Currency Markets Analyst & Financial Strategist

Vlado Grigirov is a senior currency markets analyst and financial strategist with over 14 years of experience in foreign exchange markets, cross-border finance, and currency risk management. He has wo...

View full profile →

この記事を共有する