欧州の銀行APIを使った開発を試みたことがあるなら、おそらく同じ壁にぶつかったことでしょう:証明書要件です。PSD2では、銀行と直接通信するためにeIDAS QWAC証明書が必要と定められており、それらは安価でもなく、取得も迅速ではありません。

しかし、証明書を完全にスキップできる方法があります。今日すぐに実行できる実際のコードを使って、その仕組みを紹介します。

短いバージョン

自分でeIDAS証明書を取得して、すべての銀行にサードパーティプロバイダーとして登録する代わりに、すでに証明書を持っているAccount Information Service Provider (AISP)を利用します。あなたのアプリはAISPのAPIと通信し、AISPが銀行と通信します。あなたは証明書に一切触れません。

トレードオフ:仲介者に依存することです。しかし、ほとんどの個人プロジェクト、小規模ビジネス、パーソナルファイナンスツールにとっては、完全に合理的な選択です。相互TLSや銀行ごとの登録と戦う代わりに、クリーンなREST API経由で銀行データを利用できます。

必要なもの

  • Python 3.8以上(基本部分はpipインストール不要の標準ライブラリのみ)
  • AISPプロバイダーからのAPIキー
  • 対応するEU諸国の銀行口座

私はopen-banking.ioのメンテナーなので、例として当社のAPIを使用しますが、パターンは他のPSD2 AISP(Enable Banking、Salt Edge、Tinkなど)でも同じです。カバレッジと予算に合ったものを選んでください。

ステップ1:APIキーを取得する

サインアップしてAPIキーを取得します。環境変数として保存してください:

export OBI_API_KEY="***"

Enter fullscreen mode Exit fullscreen mode

ハードコードしないでください。gitにコミットしてしまった場合は、すぐにローテーションしてください。

ステップ2:銀行接続を開始する

ユーザーは自分のデータを共有することに同意する必要があります。これにより、ユーザーは銀行のログインページにリダイレクトされます:

import os
import json
import urllib.request

API_BASE = "https://api.open-banking.io/v1"
API_KEY=os.env...EY"]

def create_session(bank_id: str, return_url: str) -> dict:
    """Start a bank connection. Returns a consent URL for the user."""
    payload = json.dumps({
        "bank_id": bank_id,
        "return_url": return_url,
    }).encode()

    req = urllib.request.Request(
        f"{API_BASE}/sessions",
        data=payload,
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json",
        },
        method="POST",
    )

    with urllib.request.urlopen(req) as resp:
        return json.loads(resp.read())

# Example: connect to a Danish bank
result = create_session("nordea-dk", "https://yourapp.com/callback")
print(f"Send the user to: {result['consent_url']}")

Enter fullscreen mode Exit fullscreen mode

ユーザーはconsent_urlにアクセスして銀行にログインし、承認します。その後、セッショントークンとともにあなたのreturn_urlにリダイレクトされます。

ステップ3:口座と残高を取得する

セッションが承認されたら:

def get_accounts(session_id: str) -> list:
    req = urllib.request.Request(
        f"{API_BASE}/sessions/{session_id}/accounts",
        headers={"Authorization": f"Bearer {API_KEY}"},
    )
    with urllib.request.urlopen(req) as resp:
        return json.loads(resp.read())["accounts"]

def get_balance(session_id: str, account_id: str) -> dict:
    req = urllib.request.Request(
        f"{API_BASE}/sessions/{session_id}/accounts/{account_id}/balance",
        headers={"Authorization": f"Bearer {API_KEY}"},
    )
    with urllib.request.urlopen(req) as resp:
        return json.loads(resp.read())

accounts = get_accounts(result["session_id"])
for acct in accounts:
    bal = get_balance(result["session_id"], acct["id"])
    print(f"{acct['name']}: {bal['amount']} {bal['currency']}")

Enter fullscreen mode Exit fullscreen mode

ステップ4:取引を取得する

def get_transactions(session_id: str, account_id: str) -> list:
    req = urllib.request.Request(
        f"{API_BASE}/sessions/{session_id}/accounts/{account_id}/transactions",
        headers={"Authorization": f"Bearer {API_KEY}"},
    )
    with urllib.request.urlopen(req) as resp:
        return json.loads(resp.read())["transactions"]

for txn in get_transactions(result["session_id"], accounts[0]["id"]):
    print(f"{txn['date']} | {txn['amount']:>8} | {txn['description'][:50]}")

Enter fullscreen mode Exit fullscreen mode

これで完了です。証明書に一切触れることなく、ライブの銀行データを読み取れます。

知っておくべき注意点

同意の有効期限。 PSD2の同意には有効期限があります(通常90日、銀行により異なります)。定期的に再認証が必要です。セッションが永遠に続くとは考えず、アプリのフローに組み込んでください。

記帳済みと保留中。 取引には2種類あります。booked取引は確定済みで、pending取引は仮のものであり、変更または消滅する可能性があります。予算管理ツールを構築する場合は、bookedを信頼できる情報源として追跡し、重複排除を慎重に行ってください。決済期間中は同じ取引が両方のリストに表示されることがあります。

銀行カバレッジのギャップ。 どのAISPもすべてのEU銀行をカバーしているわけではありません。コミットする前に、ユーザーが実際に必要とする銀行に対するプロバイダーのカバレッジリストを確認してください。地域の小規模銀行がギャップになることがよくあります。

レート制限。 PSD2 APIは、同意ごとのアクセス頻度制限を強制します(通常、取引は1日4回まで)。積極的にキャッシュしてください。ループ内でポーリングしないでください。

プライバシーモデル。 一部のプロバイダーは取引データをサーバー側に保存します。他のプロバイダー(当社など)は、クライアントが保持する暗号化キーを使用するため、プロバイダーは文字通りユーザーデータを読み取れません。GDPRを意識したユーザーを対象とする場合は、どのモデルを採用しているかを確認してください。

証明書を取得すべき場合

大規模な規制対象の金融商品(支払い処理(PIS)、信用調査、多数の銀行にまたがる数千人のユーザー向けサービス)を構築している場合は、独自のeIDAS証明書を取得して直接接続してください。仲介者は遅延、呼び出しごとのコスト、規模拡大時に望まない依存関係をもたらします。

しかし、個人プロジェクト、小規模SaaSツール、内部ダッシュボード、企業オーバーヘッドなしに口座データを読み取るだけが必要な場合には、AISPの方法が現実的な選択です。


開示:私はJohnで、open-banking.ioのメンテナーです — EU銀行向けの証明書不要のPSD2口座情報サービスです。上記のコードは当社のAPIで動作しますが、パターンは準拠するAISPに適用されます。ご質問はコメント欄でお待ちしています。