Claude Media
入金消込をClaude Codeで自動化 — 手数料差引と名義ゆれの仕分け

入金消込をClaude Codeで自動化 — 手数料差引と名義ゆれの仕分け

銀行の入金CSVと請求一覧CSVをClaude Codeで突合し、手数料差引・名義ゆれ・合算入金を仕分けて未消込リストを残すスクリプトの作り方と、月次の無人実行までの手順です。

銀行の入金CSVと請求書の一覧を突き合わせる入金消込は、Claude Codeに「照合ルールを実装したスクリプトを書かせ、実行結果を読ませる」形で任せると安定します。モデルに1行ずつ金額を見比べさせるより、ルールをコードに固定したほうが、毎月同じ基準で同じ結果が出ます。

この記事では、振込手数料の差引、名義の表記ゆれ、複数請求の合算入金という3つのずれを仕分け、判定できなかった入金を未消込リストに残す流れを作ります。サンプルデータで動かした出力も載せます。

消込でClaude Codeに任せる範囲

入金消込とは、入金データの1行ごとに「どの請求書に対する入金か」を決めて、請求側を消し込む作業です。金額が請求どおりなら機械的に終わります。手間がかかるのは、金額か名義のどちらかがずれている行です。

Claude Codeに任せるのは次の3つです。

  • 照合ルールを実装したスクリプトを書く
  • 実際のCSVでスクリプトを動かし、エラーや想定外の列を直す
  • 未消込に残った行を読み、人が確認する順に並べる

最終的に「この入金はこの請求の入金である」と確定する判断は、人が持ちます。スクリプトが付けるのは確度の違う区分で、名義違い候補のように推測を含む区分は確定扱いにしません。

銀行明細から勘定科目の仕訳案を作る作業は、Claudeで取引照合し経理を自動化する手順の領分です。Stripeなどカード決済側の入金はClaude Stripe経理のTipsにまとめています。ここで扱うのは、銀行振込の入金と請求書一覧の消込だけです。

入金の仕分け区分と判定順

先に区分を決めておくと、スクリプトの指示が短くなります。次の5区分で組みます。

区分判定の条件人が見る度合い
完全一致判定の条件請求先が合い、請求額と入金額が同じ人が見る度合い抜き取りで十分
手数料差引判定の条件請求額から振込手数料候補を引くと入金額に合う人が見る度合い差額の金額だけ確認
合算入金判定の条件同じ請求先の複数請求の合計(手数料差引を含む)が入金額に合う人が見る度合い組み合わせを確認
名義違い候補判定の条件請求先は合わないが、金額が1件の請求にだけ合う人が見る度合い必ず確認
未消込判定の条件上のどれにも当てはまらない人が見る度合い必ず確認

判定は上から順に当て、最初に当たった区分で止めます。名義違い候補は金額だけを根拠にしているので、確定扱いにしない区分です。金額が偶然一致しただけの別会社の入金を拾いかねません。

差額として許す手数料は、固定の候補リストにします。「差額が1,000円以下なら手数料」のような幅の持たせ方は、値引き交渉の残りや入金漏れまで消し込むため避けます。候補リストは自社の取引銀行の料金表から作り、スクリプトの定数に置きます。

準備: CSVとCLAUDE.mdに決めておくこと

作業フォルダに請求一覧と入金データを置きます。列は最小限で足ります。

invoices.csv : invoice_id, customer, amount, due
deposits.csv : date, payer, amount

銀行からのダウンロードCSVは、文字コードや列名が銀行ごとに違います。そのまま使えないときは、Claude Codeに列名の対応表を作らせ、変換スクリプトを別に書かせます。照合スクリプトの入力は上の形に揃えると、ルールの変更と入力形式の変更を切り離せます。

変換スクリプトの一例です。銀行CSVがShift_JIS系(cp932)だったとして、UTF-8への変換と、金額からカンマと「円」を取り除く処理を1か所にまとめています。列名は銀行ごとに違うので、取引日 などの部分は実際のCSVに合わせて直します。

import csv, sys
 
# 銀行CSV(cp932) -> deposits.csv(UTF-8)。列名は実物に合わせる
with open(sys.argv[1], encoding="cp932", newline="") as f:
    rows = list(csv.DictReader(f))
 
w = csv.writer(sys.stdout, lineterminator="\n")
w.writerow(["date", "payer", "amount"])
for r in rows:
    amount = r["入金金額"].replace(",", "").replace("円", "").strip()
    w.writerow([r["取引日"], r["摘要"], amount])

CLAUDE.mdには、毎回の指示で繰り返すことになる規約を置きます。

# 入金消込の規約
- 照合ルールは reconcile.py に実装し、モデルが金額を目視で突き合わせない
- 区分は 完全一致 / 手数料差引 / 合算入金 / 名義違い候補 / 未消込 の5つ
- 手数料の候補額は FEES 定数に置く。差額の幅で判定しない
- 名義違い候補は確定扱いにしない
- 実データの行をそのまま回答に貼らず、件数と区分で報告する

最後の1行は、請求先名や金額が出力に残る範囲を抑えるためです。入金データをClaude Codeに読ませたときの送信範囲と学習への扱いは、プランによって違います。扱いの確認は、Claude Codeのデータは学習に使われるかで先に済ませておくと安心です。

消込スクリプトを書かせる指示

指示は、区分と判定順をそのまま渡します。

invoices.csv と deposits.csv を突合する reconcile.py を書いてください。
- 名義はNFKC正規化し、株式会社などの法人格と空白を除いて比較する
- 振込名義と請求先名が違う取引先は、ALIASES 辞書で対応付ける
- 請求額から FEES のいずれかを引いた額が入金額と合えば、手数料差引とする
- 同じ請求先の未消込請求を最大4件まで組み合わせ、合算入金を探す
- 請求先が合わなくても金額が1件の請求にだけ合えば、名義違い候補とする
- 結果を区分・請求ID・備考つきのCSVで標準出力に出す

「ルールを守れ」と言うだけでなく、判定の入力と出力を具体的に書くのがコツです。Claude Codeは書いたスクリプトを実行して、型エラーや想定外の列で止まれば自分で直します。そのため、実行まで任せるには、Bashの許可を先に決めておきます。

{
  "permissions": {
    "allow": [
      "Read",
      "Bash(python3 reconcile.py *)"
    ]
  }
}

Bash(python3 reconcile.py *) のように末尾に空白と * を付けた規則は、その接頭辞で始まるコマンドに一致します。この規則は python3 reconcile.py invoices.csv deposits.csv のような呼び出しを許可します。> out.csv のような出力リダイレクトは、コマンドの許可とは別に、書き出し先が Edit の許可規則と作業ディレクトリの範囲で確認されます。コマンドの規則は、書き出し先までは許可しません。

生成されるスクリプトの一例

次のスクリプトは、上の指示で書かせる実装の一例です。ライブラリなしで動き、FEES と ALIASES が自社ごとに変える部分です。

import csv, itertools, re, sys, unicodedata
 
# 差し引かれる可能性のある振込手数料(取引銀行の料金表に合わせて直す)
FEES = (0, 220, 330, 440, 550)
# 振込名義 -> 請求先名
ALIASES = {
    "アオバシヨウジ": "青葉商事",
    "ミドリコウボウ": "みどり工房",
    "ホクトセイサクシヨ": "北斗製作所",
}
CORP = r"株式会社|有限会社|\(株\)|\(有\)|\(カ\)|\(ユ\)|カ\)|ユ\)"
 
 
def norm(s):
    s = unicodedata.normalize("NFKC", s)  # 半角カナ・全角英数を統一
    s = re.sub(CORP + r"|\(カ$|\(ユ$", "", s)
    return re.sub(r"[\s・.,]", "", s)
 
 
def load(path):
    with open(path, encoding="utf-8-sig", newline="") as f:
        return list(csv.DictReader(f))
 
 
invoices, deposits = load(sys.argv[1]), load(sys.argv[2])
for inv in invoices:
    inv["amount"] = int(inv["amount"])
    inv["key"] = norm(inv["customer"])
    inv["used"] = False
alias = {norm(k): norm(v) for k, v in ALIASES.items()}
 
out = []
for d in deposits:
    amt = int(d["amount"])
    key = alias.get(norm(d["payer"]), norm(d["payer"]))
    cands = [i for i in invoices if i["key"] == key and not i["used"]]
    result, ids, note, found = "未消込", [], "", None
    for n in range(1, min(len(cands), 4) + 1):
        for combo in itertools.combinations(cands, n):
            diff = sum(i["amount"] for i in combo) - amt
            if diff in FEES:
                found = (combo, diff)
                break
        if found:
            break
    if found:
        combo, diff = found
        ids = [i["invoice_id"] for i in combo]
        for i in combo:
            i["used"] = True
        if len(combo) > 1:
            result = "合算入金"
        else:
            result = "完全一致" if diff == 0 else "手数料差引"
        note = f"差額{diff}円" if diff else ""
    else:
        hit = [i for i in invoices if not i["used"]
               and i["amount"] in [amt + f for f in FEES]]
        if len(hit) == 1:  # 名義は違うが金額が1件にだけ合う
            result, ids = "名義違い候補", [hit[0]["invoice_id"]]
            note = f"請求先: {hit[0]['customer']}"
    out.append({**d, "result": result,
                "invoice_ids": "+".join(ids), "note": note})
 
w = csv.DictWriter(sys.stdout, fieldnames=list(out[0]), lineterminator="\n")
w.writeheader()
w.writerows(out)

名義の正規化では、半角カナの振込名義を全角に揃えるためにNFKC正規化を使っています。銀行の振込名義には「カ)」「ユ)」のような略記が付くことがあるので、法人格の略記も除いてから比較します。略記のパターンは銀行ごとに違うため、実データで外れた行が出たら CORP に足します。

実行結果の読み方

請求6件・入金6件のサンプルデータ(架空の取引先)で実行します。

python3 reconcile.py invoices.csv deposits.csv > out.csv

出力は次のとおりです。

date,payer,amount,result,invoice_ids,note
2026-10-01,株式会社ひかり堂,77000,完全一致,INV-105,
2026-10-02,ユ)ミドリコウボウ,32670,手数料差引,INV-103,差額330円
2026-10-02,カ)アオバシヨウジ,164670,合算入金,INV-101+INV-102,差額330円
2026-10-03,ホクト セイサクシヨ(カ,219780,手数料差引,INV-104,差額220円
2026-10-03,ヤマダ タロウ,88000,名義違い候補,INV-106,請求先: 株式会社さくら企画
2026-10-04,株式会社ツキノ,48000,未消込,,

3行目は、青葉商事の請求110,000円と55,000円の合計165,000円から手数料330円を引いた164,670円の入金です。1件ずつ見ると請求のどれとも合わないので、合算の組み合わせを探すロジックがないと未消込に残ります。

5行目の振込名義は個人名で、金額だけが請求106と合います。名義違い候補はこの種の行です。確定にはせず、入金元に確認する行として残します。

最後の「株式会社ツキノ」は請求一覧に該当する請求先がなく、未消込のままです。前受金なのか、請求書の発行漏れなのかは、このスクリプトからは分かりません。分からない行を無理に当てない設計にしておくと、人が見る行が減りすぎず、見落としを減らせます。

区分ごとに起きるずれと直し方

先に処理した入金が請求を取りすぎる

入金を上から順に処理し、一致した請求を「使用済み」にする作りは、順序に依存します。同じ請求先に同額の請求が2件あると、どちらの請求にも合う入金が、先の請求を取ってしまいます。請求の期日が古いものから充てるには、スクリプトの cands を作る行を、期日で並べ替える形にします。

cands = sorted((i for i in invoices if i["key"] == key and not i["used"]),
               key=lambda i: i["due"])

due は YYYY-MM-DD 形式なら、文字列のままで古い順に並びます。並べ替えても決まらない、同額かつ同じ期日の請求が複数ある行は、未消込に回して人が決めます。

手数料の候補が合わない

手数料の候補額は、振込元の銀行や送金方法で変わります。差引後の額が候補に合わない入金は、手数料差引にならず未消込に落ちます。未消込リストの差額を集計させ、頻出する差額が見つかったら FEES に足します。

差額の内訳を確かめずに、幅で一律に許す方法は、少額の入金漏れまで消し込むので避けます。

名義が辞書に無い

ALIASES は、未消込と名義違い候補に出た名義から育てます。Claude Codeに「未消込と名義違い候補の振込名義を、請求先名の候補と並べて表にして」と頼めば、辞書に足す案を作れます。足す前に、請求先名との対応を人が確かめます。

合算の組み合わせが多すぎる

請求先の未消込が多いと、組み合わせの数が急に増えます。サンプルでは最大4件までの合算にしています。件数の上限は、実際の請求の出し方に合わせて決めます。

月次の消込をヘッドレスで回す

月初に決まった手順で回すなら、照合はスクリプトに任せ、未消込の読み取りだけをClaude Codeの非対話実行(claude -p)に渡す形が扱いやすくなります。照合そのものをモデルに任せないので、結果が月ごとにぶれません。

python3 reconcile.py invoices.csv deposits.csv > out.csv
grep -v ",完全一致," out.csv | claude -p \
  "未消込と名義違い候補を、確認の優先順に並べ、理由を1行ずつ付けて" \
  --permission-mode dontAsk --output-format json | jq -r '.result'

claude -p は標準入力を読めるので、確認が必要な行だけをパイプで渡せます。標準入力には10MBの上限があり、超えるとエラーで止まります。上限を超えるデータは、ファイルに書いてパスをプロンプトで指定します。

--permission-mode dontAsk は、許可の確認で止まる呼び出しを全部拒否するモードです。人がいない定期実行で、確認待ちのまま止まるのを避けられます。ここでは標準入力の行を読むだけなので、ツールの許可は要りません。

--output-format json を付けると、本文は result フィールドに入り、実行コストの total_cost_usd も得られます。このコストはクライアント側の推定値で、実際の請求額とは差が出ることがあります。

起動時にCLAUDE.mdやフックを読み込ませたくないCI向けには --bare があります。ただしAPIキー(ANTHROPIC_API_KEY)が必要で、サブスクリプションのログインは使われません。

よくあるつまずき

  • 文字化けで列が読めない: 銀行のCSVの文字コードがUTF-8でないときは、UTF-8に変換する処理を、照合スクリプトの前に置きます
  • 金額にカンマや「円」が入る: int() で落ちるので、変換スクリプトで数字だけにします
  • 同じ入金が翌月のCSVにも載る: 消込済みの入金IDを別ファイルに残し、次回の入力から除きます
  • 部分入金になる: 請求額に満たない入金は、このスクリプトでは未消込に落ちます。残額管理が必要なら、invoices.csv に入金累計の列を足し、請求額との差が0になった請求だけを消込済みにします。たとえば110,000円の請求に60,000円が入った時点では、残額50,000円として請求を残し、次の入金を残額と照合します

まとめ

入金消込をClaude Codeに任せるときの要点は、照合のルールをスクリプトに固定することです。区分は5つに絞り、確度の低い区分は確定扱いにしません。手数料の候補と名義の辞書は、未消込の行を見ながら少しずつ育てます。月次の実行は、照合をスクリプトに、未消込の整理だけをclaude -pに渡すと、結果がぶれません。

三点照合のように、請求書とほかの帳票を突き合わせる作業はClaudeで発注書・納品書・請求書を三点照合する手順、CSVの結合や検証ループの組み方はClaude Codeでpandasのデータ処理を書く実践手順に詳しくあります。

この記事を共有:XはてブLinkedIn