0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Codeで銀行APIを実行する(実践編ー基礎ー)

0
Last updated at Posted at 2026-08-30

この記事でできること

前回の記事「Claude Codeで銀行APIを実行する(準備編)」で、GMOあおぞらネット銀行のAPI実験場 sunabar(スナバー)の残高照会を、curl と Claude Code の両方から実行しました。今回はその続きです。仮想の口座に10,000円を入金し、振込APIで1,000円を別の仮想口座へ動かして、承認から完了確認までを通します。

読み終えると、銀行の振込が「受付 → 承認 → 実行」の3つのステップで動くことと、それぞれのステップでAPIが何を返すかが、実行結果つきで分かります。

  • 対象読者:銀行の振込APIの「受付 → 承認 → 実行」の流れを動かしてみたい方/Claude Code に銀行操作を任せるとどこで止まるか見てみたい方
  • 前提:前回の記事のとおり、sunabar のアクセストークンが手元にあること
  • かかるお金:0円。動かすのは仮想のお金で、振込手数料も0円でした
  • 試した日と環境:2026年8月29日〜30日・Claude Code 2.1.226

先に3つだけ

# 押さえること 中身
1 HTTP 201 は「受け付けた」であって「振り込んだ」ではない 振込依頼APIが201を返しても、残高はまだ1円も動いていません。承認して初めてお金が動きます(3章・6章)
2 承認しないまま指定日を過ぎると、振込依頼は消える 照会APIにもヒットしなくなりました。実測です(4章)
3 Claude Code は振込の送信を実行しない 振込コマンドの実行前に止まりました。リクエストのJSONとcurlコマンドは Claude Code が作り、送信は私がターミナルで実行しました(3章)

使用する仮想口座

# 口座 役割
1 個人の仮想口座 振込元。入出金シミュレーターで10,000円を入れます
2 法人の仮想口座 振込先。sunabar は法人の仮想口座も一緒に配ってくれます

2つの口座の支店・口座番号・名義は、sunabarポータルの「sunabarサービスサイトで使える銀行口座」の画面にまとまって載っています。この記事ではあとで振込先の情報として使います。値そのものは仮想のものですが、銀行の公式ページが伏せているのに合わせて、この記事でも伏せます。

この記事の流れ

1. 仮想のお金を入金する

sunabarポータルのメニューにある「入出金シミュレーター」を開き、対象の口座(今回は個人の仮想口座)を選んで、ATM入金で10,000円を入れました。画面で金額を入れて実行するだけです。

残高照会で映ったかを確かめます(APIは前回と同じです)。

curl -X GET "https://api.sunabar.gmo-aozora.com/personal/v1/accounts/balances?accountId=<口座のID>" \
  -H "accept: application/json;charset=UTF-8" \
  -H "x-access-token: $TOKEN"
# 項目 入金前 入金後
1 balance 0 10000
2 withdrawableAmount 0 10000
3 previousDayBalance 0 0

入れた10,000円がそのまま映りました。previousDayBalance(前日残高)が0のままなのは、入金したのが当日だからです。

2. 入出金明細を見る

その入金が明細にどう記録されるかを見ます。入出金明細照会は今回初めて実行するAPIです。

curl -X GET "https://api.sunabar.gmo-aozora.com/personal/v1/accounts/transactions?accountId=<口座のID>&dateFrom=2026-08-28&dateTo=2026-08-29" \
  -H "accept: application/json;charset=UTF-8" \
  -H "x-access-token: $TOKEN"

返ってきた明細は1件でした。

# 項目
1 transactionDate 2026-08-29
2 amount "10000"
3 remarks ATM セブン
4 balance(取引後残高) "10000"

気づいたことが2つあります。

  1. remarks が「ATM セブン」。シミュレーターのATM入金は、明細の上ではセブン銀行のATMから入金した体で記録されます。仮想でも、明細の見た目は本物と同じ形です
  2. 金額や残高が、数値ではなく文字列で返ります"10000")。残高照会の balance も同じでした。プログラムで金額を計算するときは、数値への変換が要ります

3. 振込依頼を送る

リクエストの形

個人の口座から法人の口座へ、1,000円を送ります。振込依頼API(POST /personal/v1/transfer/request)に渡すJSONはこの形です。

{
  "accountId": "<振込元の口座ID>",
  "remitterName": "<振込元の名義(カナ)>",
  "transferDesignatedDate": "2026-08-30",
  "transfers": [
    {
      "itemId": "1",
      "transferAmount": "1000",
      "beneficiaryBankCode": "0310",
      "beneficiaryBranchCode": "<振込先の支店コード>",
      "accountTypeCode": "1",
      "accountNumber": "<振込先の口座番号>",
      "beneficiaryName": "<振込先の名義(カナ)>"
    }
  ]
}

埋める値はこう集めました。

# どこから取るか
1 accountId(振込元) 前回の口座一覧照会の返り値
2 remitterName(振込元の名義カナ) 口座一覧照会の accountNameKana。ポータルの「sunabarサービスサイトで使える銀行口座」画面にも載っています
3 振込先の支店コード・口座番号・名義カナ 同じくポータルの「sunabarサービスサイトで使える銀行口座」画面。法人の仮想口座の分もここにあります
4 beneficiaryBankCode 0310 = GMOあおぞらネット銀行の銀行コード。今回は同じ銀行あての振込です
5 accountTypeCode 口座種別。普通預金の 1 を入れました
6 itemId transfers 配列の中の連番。1件目なので "1"

金額はここでも文字列で渡します。transferDesignatedDate は振込の指定日で、当日を指定できました(実測)。あとで書く理由(4章)から、当日を指定して当日中に承認まで進めるのがよいです。

Claude Code が送信を止めた

ここで想定していなかったことが起きました。Claude Code に「このJSONで振込依頼を送って」と頼んだところ、curl を実行する手前で止まりました。

止まり方には特徴がありました。ふだん Claude Code がコマンドを実行する前に出す「実行してよいですか」という許可の確認は出ませんでした。許可を押せば通る、という形ではなく、確認より手前で実行そのものが拒否される止まり方です。残高照会や明細照会(読み取りのAPI)は、いつもどおり許可の確認を経てそのまま実行できていたので、振込だけ扱いが違いました。仮想のお金でも、振込の形をしたAPIの送信は実行しない、という線が引かれているようです。

一方で、リクエストのJSONを書くところまでは止まりませんでした。口座IDや名義入りのJSONも、実行するcurlコマンドも、Claude Code は普通に作ります。止まるのは送信の瞬間だけです。分担の形も Claude Code のほうから出てきました。「コマンドは用意するので、実行はご自身でお願いします」という形です。

そこで、リクエストのJSONと実行するcurlコマンドは Claude Code が作り、送信は私がターミナルで実行しました。送信は結局2回ありましたが(2回目の事情は4章)、2回とも同じ分担です。

対象読者の2行目に書いた「どこで止まるか」の答えがこれです。私が実測できたのは振込APIについてだけなので、書き込み系がすべて止まるのかまでは分かりませんが、少なくとも振込は、確認を求めるのではなく実行しない、という止まり方でした。試す前は「仮想口座なら全部やってくれるだろう」と思っていたので、この線の引かれ方は発見でした。

なお2つ、切り分けておきます。今回の送信はエージェント(MCP)経由ではなく、アクセストークンをヘッダに載せた curl の直接実行です。そして止めたのは Claude Code 側で、前回の記事で登録した銀行側のエージェントのポリシー(150文字の日本語)が振込を止めるかどうかは別の話です。そちらは次回試します。

curl -X POST "https://api.sunabar.gmo-aozora.com/personal/v1/transfer/request" \
  -H "accept: application/json;charset=UTF-8" \
  -H "Content-Type: application/json" \
  -H "x-access-token: $TOKEN" \
  -d @振込依頼リクエスト.json

返ってきたもの

# 項目
1 HTTP 201
2 applyNo(受付番号) 2026083000000001

**201は「受け付けた」であって「振り込んだ」ではありません。**この時点で残高は1円も動いていません。applyNo は「日付+その日の連番」の形で採番されていました。

4. 振込依頼が消えていた

実は3章の前に、1回失敗しています。前日の夜(8月29日)に指定日8月29日で振込依頼を出して201をもらい、「承認は翌朝でいいだろう」と寝ました。

翌朝、承認しようとしたら、どこにもありませんでした。照会(読み取り)はいつもどおり Claude Code に実行してもらっています。振込状況照会APIのcurlは6章に載せています。

# 確かめた場所 結果
1 サービスサイトの「引落し・振込予定」 表示対象がありません
2 振込状況照会API(受付番号で照会) count 0
3 振込状況照会API(日付範囲で照会) count 0

指定日のうちに承認しなかった振込依頼は、期限切れで消えるようです(実測でそうなった、という話です。公式の記述は見つけていません)。エラーも通知も見当たらず、照会にもヒットしないので、「出したはずの振込が無い」状態になります。

教訓はひとつです。**振込依頼は、出した日のうちに承認まで済ませる。**3章に載せた実行結果は、指定日を8月30日に直して出し直した2回目のものです。

5. 承認する

承認する場所は「4つ目のサイト」

前回の記事で「ログインするサイトは3つあります」と書きましたが、振込の承認で4つ目が登場します。sunabarサービスサイト sso.sunabar.gmo-aozora.com です。

# サイト 何をするところ
1 銀行のサービスサイト sso.gmo-aozora.com いつも使う本物の銀行のサイト
2 sunabarポータル portal.sunabar.gmo-aozora.com トークン・エージェント登録・入出金シミュレーター
3 開発者ポータル APIの詳しい仕様書
4 sunabarサービスサイト sso.sunabar.gmo-aozora.com 仮想口座の名義人としてログインし、振込を承認する

言ってみれば「仮想世界の銀行窓口」で、振込元(個人の仮想口座)の名義人、つまり架空の人としてログインします。IDとパスワードは、sunabarポータルの「sunabarサービスサイトで使える銀行口座」の画面に載っています。3章で振込先の口座情報を拾ったのと同じ画面です。

私は最初、1番の本物の銀行のサイトへお知らせを見に行き、何も届いていなくて途方に暮れました。承認の入口は4番です。ここはブラウザの操作なので、Claude Code に任せることは試さず、最初から自分でやると決めていました。銀行のログインを伴うためです。

メールトークンの期限は約6分

sunabarサービスサイトにログインすると、ベルのアイコンの「お知らせ」に「メールトークンを発行しました(オープンAPI連携-振込)」という通知が入っています。振込依頼APIを送ったことが引き金で届く通知です。通知の詳細を開くと、承認ページへのリンクと6桁のメールトークンが載っています。

承認ページでは、このメールトークンと取引パスワード(承認の本人確認に入れる文字列)の2つを入れます。ここで少し急ぐ必要があります。メールトークンの有効期限は発行から約6分でした(画面に期限の時刻が出ます)。2つを入れて承認すると、「振込を受け付けました。(受付番号 : <受付番号>)」と表示されました。

FAQにはメールトークンは任意の文字列でよいという趣旨の記述がありますが、私の画面では実物の6桁が発行されていたので、それを入れました。取引パスワードのほうは任意の文字列で通りました。期限が切れた場合の再発行は試していません。私の場合は依頼そのものを出し直したら、新しい通知が届きました。

6. 完了を確認する

振込状況照会

承認の直後に、振込状況照会APIで状態を見ます。

curl -X GET "https://api.sunabar.gmo-aozora.com/personal/v1/transfer/status?accountId=<口座のID>&queryKeyClass=1&applyNo=<受付番号>" \
  -H "accept: application/json;charset=UTF-8" \
  -H "x-access-token: $TOKEN"

queryKeyClass は必須で、1(受付番号で引く)か2(日付範囲で引く)を指定します。2のときに applyNo を一緒に渡すと「受付番号(振込申請番号)は指定できません」と弾かれました。

transferStatus は 20(手続済) になっていました。承認前はこの照会が count 0 だったので、承認するまでは照会に出ない期間があることも分かりました。

残高が動いた

# 口座 承認前 承認後
1 個人(振込元) 10,000 9,000
2 法人(振込先) 0 1,000

1,000円が動きました。同じ銀行あてなので、振込手数料は0円です(transferFee "0")。

法人口座の残高を見るには、もうひと手間ありました。個人用のトークンでは法人の口座は見えません。実測では HTTP 404 で「ご指定のお取引は、お取り扱いできません。」が返ります。sunabarポータルのトークン発行画面で対象に法人口座を選んで法人用のアクセストークンをもう1本発行し、法人用の口座一覧照会(GET /corporation/v1/accounts)で法人側の accountId を取ってから、/corporation/v1/accounts/balances で確認しました。

まとめ

# 分かったこと
1 振込は「受付(201)→ 承認 → 実行」の3つのステップ。承認して初めて残高が動く
2 承認しないまま指定日を過ぎると、振込依頼は照会にも出ない形で消える(実測)
3 承認の入口は4つ目のサイト(sunabarサービスサイト)のお知らせ。メールトークンの期限は約6分
4 Claude Code は読み取りのAPIは実行するが、振込の送信は許可の確認も出さずに実行しない。JSONとコマンドの用意まではやってくれるので、送信の1回だけ人間の手が要る
5 金額・残高・件数は文字列で返る

次回は、前回登録した参照専用ポリシーのエージェントに振込を頼むとどう断られるか、金額上限つきのエージェントを作るとどこまで通るか、を試します。

出典

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?