The team at 37signals are notorious for their catalog of ideas (what they call, signals), of which one in particular is pretty interesting (and almost polarizing) when it comes to API design: context > consistency.
To quote 37signals: “Following a formula can be comforting, but when it comes to design, we think designing around the current context is better than designing to satisfy prior consistency.”
In the world of finance, as standards and interoperability become more important (ISO20022, anyone?) Designing payment APIs for basic stuff such as transactions and payouts is both an art and a skill. The question is, how do we get our API design right, in terms of the data schema?
It has been over twelve years since ISO20022 formally went live in banks in Europe in the avatar of SEPA, so I thought it makes sense for us to compile a list of pointers/gotchas when it comes to designing APIs for payments and payments orchestration, accumulated with over a decade of creative thinking and production failures, but above all, learning.
Payment APIs - the basics
– Simply put, a payment API suite is expected to be able to facilitate all kinds of movement of money, including domestic and cross-border.
– Payment APIs, like payment products, need to be thought through for several scenarios over and above the movement of money – for instance, beneficiary registration, human scrutiny, fraud checks, etc.
– For the purpose of this blog, REST over HTTP(S) is considered as the core transport mechanism, with JSON as a format
Key principles of API design
- ISO20022 is verbose: at first, ISO20022 is overwhelming, particularly for those who have grown up on the smaller data footprint of ISO8583 (still in use by most ATM switches). It almost feels like the consortium who designed ISO20022 said: “okay, we need about 5 mandatory fields to execute a payment, let’s go nuts and think of 23 fields, and make most of them mandatory”. When designing APIs, always overthink, but make the bare minimum mandatory to reduce the entry barrier of adoption, and document multiple variants.
- Schema validations are overrated, yet necessary: most meaningful rules in today’s day and age are so nuanced, that they almost always are better expressed as semantic validations as opposed to syntactical validations. Implementing just schema validations isn’t enough.
- Enable configurability: within our product, we introduced a concept of DIY, which is, every install can configure their own API sub-substructure schema to suit their payment needs. This allows you to have one API signature, but nested schemas to support all kinds of payments (merchant payouts, invoices, shipments, rideshare, etc) and have rules per payment type.
- Draw inspiration from ISO20022’s hierarchy and vocabulary: if there’s one thing that ISO20022 got absolutely bang on, it’s the hierarchy (group -> debit legs -> credit legs, for credit transfers, and group -> credit legs -> debit legs for direct debits). It’s also got the vocabulary spot on (InstructedAmount vs EquivalentAmount, LocalInstrument), and – in some cases – the enumerations for things like a payment status: ACTC (accepted, technically) vs ACSP (accepted, settlement in progress) vs ACSC (accepted, settlement complete)
- Stick to intuitive JSON keys: there’s no need to go miserly with a few bytes on JSON keys like ISO did, with the kind of network bandwidth and gzip compression possible. If bandwidth is still a concern (edge/IOT payments), then I would argue, go without metadata (bitmap ISO8583 works best).
- Design for analytics, not just processing: when coming up with the attributes to design the APIs, don’t just design the data points that are required to capture, store and clear – but – also capture data points that will be useful in terms of analytics. For instance, you don’t really need a start/end geo-coded data point of a shipment to process a payment for the shipment, but can you imagine the power of a visual dashboard that plots payouts on a map, the size of the circle as the amount, the colour of the circle indicating risk? Humans (and AI) can instantly make decisions when rich metadata is associated with a payment. Encouraging the ability to express it is always a good idea
- Lastly, every API needs to be imagined as a product – which means, it must be versioned, it must have documentation against it, it must have samples, and above all, it must focus as much on processing (i.e. what the API does) as on consumption (how will customers consume this). An example of paying attention to consumption patterns is: if the API has “configurable rules” that help customize validations, splits, etc. – do you really want to have one API endpoint that does it all – or – have separate endpoints? The advantage of a single API – easier to manage, describe, and consume. The disadvantage is, it’s difficult to guarantee SLAs on throughput/latency when there’s such a higher degree of configurability.
REST APIs are a way for two systems to communicate with each other using the HTTP protocol. They are lightweight and easy to use, and are often used to build web applications and other distributed systems.
ISO20022 is an international standard for the communication of financial information. It defines a set of XML message formats that can be used to exchange financial data between different systems.
HTTP 3.0 is the next major version of the HTTP protocol. It is designed to improve the performance of web applications by using a new transport protocol called QUIC. QUIC is more efficient than TCP, which is the current default transport protocol for HTTP.
APIs can be secured using a variety of methods, including:
– **Authentication:** This involves verifying the identity of the user or system that is accessing the API.
– **Authorization:** This involves determining what resources the user or system is allowed to access.
– **Encryption:** This involves encrypting the data that is sent between the client and the server.