Context
Introduction¶
The Transfers subcomponent within the Payment Gateway Component plays a pivotal role in managing the flow of funds between different entities and accounts. This subcomponent is intricately designed to handle various types of transfers, ensuring seamless financial transactions through our external Payment Service Providers (PSPs).
Key Concepts¶
Transfer History¶
At the core of the Transfers subcomponent is the Transfer History, which aggregates all types of transfers under a unified framework. This allows for a comprehensive view of financial movements, akin to monitoring transactions in a bank account. It supports a diverse range of transactions, including card payments and wire transfers, providing a robust API for balance computation and historical access.
A good analogy would be to see this as your own bank account from which you can attach card payments but also wire transfers.
Rules¶
- Rule 1: One transfer (money flow) can be attached to one and only one Transfer History
Transfers¶
Transfers within this subcomponent can vary in nature but adhere to a set of universal rules. Each Transfer is uniquely associated with a single Transfer History, ensuring clarity and accountability in financial flows. The subcomponent accommodates both positive and negative amounts through Transfer Events, adhering to bitemporal history principles. This means every transfer has an effective date marking the actual change and a creation timestamp indicating when the change was recorded.
Rules¶
Transfers can be of different kinds but they all follow those rules:
-
Rule 1: They can only be associated to a single Transfer History. If an operation impacts 2 Transfer History there will be 2 transfers: one for each impacted Transfer History
-
Rule 2: They all can have a positive or a negative amounts associated (through Transfer Events)
-
Rule 3: They follow bitemporal history β§ principles. They have both an effective date (date at which the change occurred) and a creation timestamp (date at which we knew about it).
-
Rule 4: They are immutable but stateful through additional Transfer Events (with the exception of Internal Transfer, see below). Card payments can fail if a limit is crossed or there is no money left
The Different Kinds of Transfers¶
- Card Payments [Origin: Adyen]: payments with Adyen issued cards that can be routed to impact a Transfer History upon webhook reception
- Bank Transfers [Origin: Adyen]: externally incoming or outgoing money flows from Adyen Balance Accounts that can be routed to impact a Transfer History upon webhook reception
- Account Transfers [Origin: Adyen]: fund movements between Adyen Balance Accounts that can be routed to impact a Transfer History upon webhook reception
- Internal Transfers [Origin: Internal]: fund movements between two Transfer History
Info
There is no validation or states for Internal Transfers. They are internal to our Payment Gateway. As such, they donβt have events associated with them and an amount to represent the value instead.
Transfer events¶
Transfer Events is a concept transposed from Adyenβs Payment Stages β§ (must-read) into the Payment Gateway to reflect the stateful nature of transfers: they can succeed, they can fail, they can be changed. You can read more about the authorization flow here β§ (optional).
We use event sourcing to store all those incremental changes as immutable data in our database, each incremental change is a Transfer Event
Each event will come with 3 different balances except for Internal Transfer which has amount directly associated with it and no events:
receivedthis is the balance of received funds, typically when a transfer is initiated, this is the first balance to be impactedreservedis when funds have been put aside but not yet transferred to the other party. Itβs pending finalization. This is typically what occurs when an authorization is given. The money is virtually βgoneβ from your account for all accounting purposes (e.g. limits).balanceis the final outcome of the transfer, from an accounting perspective the money is gone and the state is usually final at this point
At any point in time, if for a given Transfer you sum all the associated Transfer Eventβs balances, you will have the state of the payment:
Example
Illustration of how the money flows from one balance to another in time with Transfer Event of a given Card Payment β§

Routing a Transfer¶
Our Payment Service Provider sends us events occurring on their platform through webhooks. The Payment Gateway exposes routers which responsibility is to return a TransferHistoryId to link the transfer to it.
Itβs up to the business logic to decide what to do.
Balances¶
The Payment Gateway offers a basic API to query transfers that occurred between certain dates and the actual balances at a point in time.
Time travelers beware!
Transfers will be returned in their final state with all their Transfer Events associated even though you requested them as-in the past (i.e. with the effective date filtering). This behavior can be changed but the query is not obvious to write.