You are checking out of an online store. Below the familiar “Visa” and “Apple Pay” buttons is a new option: “Pay with Bank.”
You click it. You are redirected away from the merchant and into a secure portal hosted by your bank. You authenticate, approve the exact amount, and are instantly routed back to the store. The checkout is complete.
To the consumer, this feels like a simple OAuth login flow. To a distributed systems architect, it is a radical re-architecture of the Left Side API.
For decades, online payments required routing through card network intermediaries (Visa/Mastercard) using synchronous ISO 8583 protocols. Account-to-Account (A2A) payments, powered by Open Banking, bypass the intermediaries entirely. They allow a third-party application to directly instruct your bank’s Core Ledger Kernel to move money via domestic rails.
But allowing external aggregators (like Plaid, Trustly, or Tink) to initiate payments against your ledger introduces a massive attack surface. The engineering challenge is not moving the money; it is building an API Gateway capable of cryptographically verifying identity and enforcing consent at scale.
1. The FAPI Gateway: Transport and Identity Layer
Standard REST APIs use OAuth2 for authentication. Financial-grade APIs require FAPI (Financial Grade API), a highly restrictive security profile built on top of OAuth 2.0.
Before an aggregator can even send a JSON payload, the connection must pass through mutual TLS (mTLS). The bank’s edge gateway validates the X.509 certificate provided by the aggregator. If the certificate isn’t signed by a private Certificate Authority pre-registered with the bank, the TLS handshake fails and the connection is dropped. There is no HTTP layer to exploit.
Once inside the TLS tunnel, the gateway must verify the JWT (JSON Web Token) carrying the payment consent. It cannot just validate the signature; it must fetch the aggregator’s public keys from a JWKS (JSON Web Key Set) endpoint and verify the exact asymmetric signing algorithm. If the token claims to be signed with RSA, but the aggregator’s JWKS specifies an Elliptic Curve key, the gateway rejects it.
In a high-throughput system, fetching JWKS over the network on every request is a latency killer. The Left Side JVM must maintain an in-memory cache of aggregator public keys, refreshed asynchronously via a background scheduled executor, ensuring zero latency penalty for cryptographic verification.
2. The OAuth State Machine: Preventing CSRF in Financial Flows
The “redirect to bank” flow is a state machine that must be managed across two distinct JVMs (the merchant’s and the bank’s) without shared memory.
When the user clicks “Pay with Bank,” the bank’s gateway generates a cryptographically random stateparameter. This is not just a session ID; it is a CSRF (Cross-Site Request Forgery) defense mechanism.
The gateway writes this state string to a distributed, highly available cache (like Redis) with a strict Time-To-Live (TTL) of roughly 5 to 10 minutes. It then redirects the user.
When the user authenticates and the bank redirects back to the merchant, the merchant includes the stateparameter in the callback. The gateway reads the callback, queries Redis for the state, and ensures they match. If an attacker tries to inject their own callback URL, they will not have the valid state string, and the transaction is aborted.
Because this is a payment rail, the state cache entry is often bound to a temporary database row in the Outbox table that pre-allocates the expected payment amount and destination, ensuring the OAuth flow cannot be hijacked to change the payment payload mid-flight.
3. The Aggregator Topology: The Strategy Pattern
The global Open Banking ecosystem is highly fragmented.
In Europe, PSD2 regulations mandate a standard payload format. In the US, private aggregators like Plaid use proprietary JSON schemas. A bank’s Left Side API cannot be a monolithic if/else block checking if (aggregator == "PLAID") on every request.
The gateway architecture requires an implementation of the Strategy Pattern via a polymorphic AggregatorAdapterinterface:
PlaidAdapter implements AggregatorAdapterPSD2Adapter implements AggregatorAdapter
When the mTLS certificate is validated, the gateway extracts the Client ID, uses it as a routing key to look up the corresponding Adapter bean in the Spring Application Context, and delegates the payload parsing. This allows the bank to onboard a new aggregator by writing a single new Adapter class, without touching the core payment execution logic.
4. The Consent Token: Scope Enforcement
Once the OAuth flow completes, the merchant receives an Access Token. But this token is fundamentally different from a standard API token.
In Open Banking, the token represents a Payment Consent Resource. Embedded within the JWT claims is a strict scope definition: "scope": "payment:initiate", alongside the exact authorized amount ("amount": 45.00) and the destination ("creditor_account": "12345").
When the merchant submits the final POST /payments request using this token, the Left Side API Gateway must intercept the request before it hits the Outbox table. It decodes the JWT, extracts the authorized amount, and compares it to the JSON payload.
If the merchant attempts to submit a payment for $50.00 using a token authorized for $45.00, the gateway silently drops the request with a 403 Forbidden. The Core Ledger Kernel never sees the request. The database is never touched.
5. Bridging to the Kernel
Once the gateway validates the mTLS, the JWT signature, the state parameter, and the consent scopes, the payment instruction is considered legally verified.
The Left Side API maps the standardized Open Banking payload into the internal DebitAccountCommandPOJO, writes it to the local Outbox table in a synchronous database transaction, and returns 202 Accepted to the aggregator.
The asynchronous Debezium thread picks it up, pushes it to Kafka, and the Right Side Actor processes it exactly like a standard domestic rail transfer.
The Architecture Revealed
Open Banking A2A payments do not require a new ledger architecture. They require a heavily fortified Left Side API Gateway. By enforcing mTLS at the transport layer, strict JWKS validation at the identity layer, and polymorphic payload adapters at the application layer, the gateway ensures that by the time a third-party payment instruction reaches the Core Kernel, it has been cryptographically proven to be authentic and mathematically bound to the user’s explicit consent.