UPSIDER Tech Blog

複数の銀行データソースを1つに束ねる ― マルチブランド法人カードを支える銀行連携基盤

こんにちは!銀行連携基盤チームのPO/EMをしている terryです。
法人カード基盤の外部提供プロジェクトの tech blog リレー、銀行連携編です。

前回は、mitomi-san の Error Reportingに関する記事でした。コストとのトレードオフを考慮した異常検知機構の選定は非常に参考になりましたし、特にエラーログを JSON で出力するだけという手軽さは1歩目として踏み出しやすいと思いました。

さて、今回は、法人カード基盤の外部提供を進めるにあたり、どのように工夫して銀行連携を構築したのかについて、お話しできればと思います!

はじめに

まず、銀行連携について紹介します。
与信の算出方法として、ユーザーに法人口座を接続いただき、その口座の情報をもとに与信を計算します。この機能は元々 UPSIDER / PRESIDENT CARDにもありましたが、法人カード基盤の外部提供 では与信機能を含めて新規に作り替えました。

本プロジェクトは、自社ブランドの法人カードを次々と立ち上げていく構想です。ブランドが増えていっても破綻しない土台にするには、与信のもとになる銀行連携を場当たり的に増築するのではなく、最初から「増えること」を前提に作り替える必要があります。

もちろんブランドが増えても追加で対応できる作りにしていますが、それを足元で成り立たせているのは、「与信を止めない」ために複数の銀行データソースを1つに正規化する仕組みと、それを支える非同期基盤です。今回はこの2つに焦点を当ててお話しできればと思います。

複数のデータソースから銀行の連携ができるようにしている

そもそも、なぜ複数のデータソースから銀行連携できるようにしているのでしょうか? それは、UPSIDERにおいて与信が事業をまたいだ中心的な役割を担っているためです。カードを利用するためには、与信から算出された利用可能額が必須です。この与信が算出できないとカードが使えず、事業そのものに影響が出てしまいます。

この「止めない与信」を実現するために、銀行データの連携も止まるわけにはいきません。そのため、複数の銀行データ経路を用意し、片方が落ちても与信を止めない構成にしています。

また、複数の銀行データ経路を用意することで、銀行ごとの API 対応状況の差も埋めることができます。

ただし、複数の銀行データ経路があるということは、

  • 同じ1つの口座が、複数の経路から入ってくる
  • 各経路によってデータフォーマットが異なる

ことを意味します。この差分を吸収し、画一的なフォーマットで 与信基盤(与信計算を行うサービス) に渡す必要があります。

不揃いなデータを揃える 正規化の醍醐味

では、ここからどのように正規化を行っているのか、深掘りしてみていきます。

正規化の第一歩は、「複数の口座があったとき、それらが同じ口座か」を判定するところから始まります。では、同じ口座とはどのような状態でしょうか?

  • 金融機関コード
  • 支店番号
  • 口座番号

これらが一致していることで同じ口座と判定できますが、銀行データによってフォーマットは変わります。

例えば、ある経路では口座番号が7桁未満だと0埋めされ、別の経路では0埋めされない。すると同じ口座でも文字列として一致しなくなります。
また、経路によっては支店番号と口座番号がひとまとめで表現されることもあり、必要な部分を取り出して同じ粒度に揃える必要があります。
こうした表現のゆれは、経路や銀行ごとに少しずつ異なります。

これらを、既存の UPSIDERカードで蓄積したデータも参考にしながらパターンを洗い出し、1つ1つ揃えていきます。地味ですが、ここが正規化のいちばんの肝で、面白いところです。

次に、どの銀行データソースを primary(主)とするかの判定です。

どの口座も正常に連携できていれば問題ありませんが、ステータスが食い違っていた場合は、どちらを優先するかの判定が入ります。

例えば、

  • 口座A(経路1):連携成功
  • 口座A(経路2):連携成功

この場合は、連携成功として問題ありません。一方、

  • 口座A(経路1):連携成功
  • 口座A(経路2):連携失敗

この場合は、経路1を primary として口座を統合していきます。ステータスは、成功・失敗だけでなく、メンテナンス中や同期中などさまざまなパターンがあります。これらをシステム内部で優先度をつけ、1つ1つ判定していきます。

また、同じ取引(明細)が複数銀行データ経路から届くため、口座の明細も重複をはじき、1つの履歴となるように統合していきます。

そして、最後に、与信基盤 に向けたデータの統一です。ここまでで1つに統合された口座・明細を、与信基盤が読み取りやすい形に変換し、与信の計算へと渡します。

正規化を支えるPub/sub基盤

いまお話しした正規化処理を支えるのが、Pub/Sub を利用した非同期バッチ基盤です。

従来の UPSIDER の銀行連携は同期的・直列で、1社の遅延や失敗が全体に波及しやすい構造でした。これを非同期+並列で作り替えています。

導入企業数が増えるごとに対象データは増えていく一方で、最速で与信を出すために、企業ごとに並列で処理を行っています。

そこで Cron を起点として、対象企業をバッチサイズ単位で切り出してメッセージを発行します。1バッチ内の各社は goroutineで並列処理を行い、終わったら次のオフセットのメッセージを発行して、数珠つなぎに進んでいきます。

進捗もテーブルで管理し、メッセージのオフセットと突き合わせることで冪等性を担保しています(処理済みのオフセットはスキップ)。メッセージ発行が失敗してチェーンが切れても、タイムスタンプをもとに再発行する復旧の仕組みも備えています。

また、この Pub/Sub 基盤は銀行からデータを取得する処理にも展開しています。バッチサイズで切り出した企業・銀行を並列で取得・処理することで、従来の同期処理から大幅な速度改善ができるようになりました。

まとめ

いかがでしたでしょうか? 不揃いで、しかも止められない銀行データを、「正規化と非同期基盤で1つに束ねる」ことが今回の銀行連携のいちばんの面白みでした。そしてこの基盤は、法人カード基盤の外部提供を進め、パートナーが増えても柔軟に拡張できるように作ってあります。事業が拡大しても、銀行連携の基盤そのものを作り替える必要はありません。本プロジェクトだけでなく UPSIDER の事業基盤となる機能なので、これからも改善を重ね、安定した品質を出せるよう取り組んでいきます。

また、本記事で触れた「与信を止めないための銀行連携」をテーマに、Product Engineering Conference 2026で登壇します。ぜひ聞きに来てください。

法人カード基盤の外部提供の挑戦 技術ブログ バトンリレー

各エンジニア組織が法人カード基盤の外部提供の挑戦の中で得た知見を順次公開していきます!技術、開発設計や思想、Tipsなど、幅広くお伝えします。

▼公開予定表 (各記事公開後、リンク集になります)

タイトル チーム 執筆者
UPSIDERのカード基盤を「外部提供できる形」にするまで——マイクロサービス化とマルチブランドアーキテクチャ 法人カード基盤の外部提供 全体構想 Mitsui
Spanner Change Streams を自前で読む ― 決済データを欠損なく取り込む カード管理基盤チーム(Solaris) Ohsako
1年動き続けるワークフローを壊さずにデプロイする ― Temporal Worker Versioning 導入記 請求基盤チーム(Hermes) nishiwaki
GCP Error Reportingで「最低限の異常検知」を低コストに実現する 法人審査基盤チーム(Hestia) Mitomi
複数の銀行データソースを1つに束ねる ― マルチブランド法人カードを支える銀行連携基盤 銀行連携基盤 terry
仮説駆動で取り組む負荷試験計画 processor Kinsho
AIが実装しレビューする時代に、プロダクトエンジニアは何をするのか お客様向け管理画面チーム(Iris) Akari
法人カード基盤の外部提供にも耐えうる不正利用対策基盤の構築 Anti-fraudチーム Ryutaro
法人カード基盤の外部提供という挑戦 決済基盤を「他社にまるごと使ってもらう」QAの話 QAチーム Naoki

なぜUPSIDERが法人カード基盤の外部提供に取り組むのか、その背景を綴っている記事も合わせてぜひご覧ください。

note.com

We Are Hiring!!

UPSIDERでは現在積極採用をしています。 ぜひお気軽にご応募ください。 herp.careers

herp.careers

UPSIDER Engineering Deckはこちら📣

speakerdeck.com