What Makes Payment Applications Different?
The Quest for Involving Payment Specialists in Software Design
There are at least two ways of thinking about the functions of banks. One is financial: banks borrow short term to lend long term, pooling risk-averse savings into risky investments. Another one is technological: banks track who has money, moving it around when someone wants to part ways with it and send it to another person.
Although conceptually different, these two functions have been historically combined in banks. However, most bankers think of themselves as part of the financial function. The technological aspects of banking are seen as cost-centers, their strategical importance in board meetings is downplayed, and technical projects’ execution is outsourced to consulting companies like Accenture.
Using this lenses, fintech history can be explained as tech savvy founders realizing that, if banking started from scratch today, you might prefer having well-run tech companies in charge of the databases of money, much like they do with your emails or your tweets, and leave the finance people build all the borrowing-short-to-lend-long infra on top.
Of course, some of that has happened, but for the most part, we still rely on brick and mortar banks to do our banking. The world of payment providers couldn’t be more fragmented, and that exerts a powerful influence in the way payment applications get built.
The Prestige
Payment applications are one of those pieces of software that appear easy on the surface—who hasn’t paid with credit card?—but that is deceiving. For that reason, when confronting such systems for the first time, software engineers tend to run into an inverse of the John Scully’s disease, and make false assumptions that end up causing a lot of harm, and losing a lot of money.
Two big resounding mistakes come to mind: one is that of scale, other is correctness. Because payments happen all the time, we assume that tech companies who implement their own payment solutions need to operate at a scale similar to other services they provide. In reality, that’s never the case. Even if you were to handle the lion’s share of all credit card transactions in the entire planet, bear in mind that Visa currently serves around 8'500 transactions per second1. Not bad, but the industry has been talking about how to handle 10’000 connections per second on a single server since 1999. Naive developers, nevertheless, build payment applications for a bigger user base than the one they end up serving, creating unnecessary complexity.
In fact, such thinking ends up being the actual problem when building payment applications. The complexity of payments isn’t the result of scale, but the high levels of accuracy. The problem isn’t to serve many users, but to serve them well; the serenity to authorize legit transactions, the courage to reject what is fraudulent, and the insight to know the one from the other.
Developers building for scale end up creating payment applications that are difficult to understand and modify, ignoring the fact that what matters is simplicity and clarity.
In this regard, payment applications are riding the same trend than most other software, and that is the diminishing importance of CPU performance on the overall value of the system in favor of Data. When building payment applications, the amount, the complexity and the speed of change of persistent data drives the selection of tools and approaches. Focusing on the particulars of that data means that you must understand the particulars of the payment domain to be effective.
Design Documents As Medium For Thought
Domain knowledge, for payment applications, trumps computer science acumen. However, most technical teams have rejected the idea of software design, planning, and writing things down. All sacrificed in the altar of Agile methodologies.
Nonsense! A design document is inextricably linked to its domain, as it is software. But unlike JIRA tickets, designing an architecture takes a holistic approach to software, sitting on a higher level of abstraction, and points the way in which those JIRA tickets serve a higher purpose.
Pull requests are chunks of work; design documents are their context.
Why is that useful? Because the emergent properties of software are only made apparent at particular levels of abstraction. Design documents allow for the creation of a pseudo-programming language, one that compiles in code and in the domain, that bridge the inherent gap between conversations among engineers and among payment specialists.
By engaging in the creation of this Ubiquitous Language, design documents encourage the development of a medium for thought, were payment terminology manifests clearly in the code and their elementary objects and properties are corollaries to the software application.
Software architecture design keeps the conversation going in the face of changes in the domain.
Payment Applications Are Enterprise Software
Payment applications are built with the needs of an organization in mind. Unlike commercial software, they need to fit the specific needs of multiple and misaligned teams within a broader context. Therefore, engineering payment applications tends to require greater care and politics than most B2C software.
Two-Pizza Teams
Take, for instance, why you could even develop payment applications in the first place, separated from the rest of the company’s software. The adoption of AJAX and REST in the early 2000s allowed Web applications to have some of the dynamic logic living in the end user’s web browser, but it also permitted engineers to decouple front-end software from back-end software meaningfully for the first time. Previously, you had no option but to mix it into a template file, and serve each request as a full reload of the whole site.
But if front-end could be its own separate thing, engineers are no longer required to combine all software capabilities into the same application. They could break it down into smaller components and assign ownership of those components to different teams. Thus starts the tale of Service Oriented Architecture.
Something like that would allow the philosophy of doing one thing well to bleed into software systems as a whole. And that’s how you get specialized applications for payments.
Risks and Debuggable Software
When you write a program for a hobby project, you write understandable code. Enterprise software, though, is built under the assumption that most code will inevitably change, and therefore it’s maintainable. This is one of the biggest reasons driving the widespread adoption of Python as the lingua franca of enterprise software: most engineers have had some exposure to it, and can be reshuffled into a team that uses it while mitigating some of the on-boarding risks.
Also, reliable code is paramount in enterprise applications. As important as competitors’ presence is in today’s lightning speed software market, mature companies are also exposed to reputational damage. Consider how patient you would be if you paid for something and the company could not tell you where your money went.
The Data Intensity Trend
A few years ago, books like Hands-On Enterprise Application Development with Python would start by recommending a “basic understanding of fundamental operating system concepts”, while knowledge of database systems was “beneficial, although not mandatory”.
The trend has completely reversed: data dominates every single decision in enterprise software, while tools like containers have virtually abstracted away all operating system’s concerns. Payments expertise, either from a group of specialists or directly in the heads of the engineers that develop the software, is the single most important factor in building effective payment applications.
Software architecture is having a renaissance in the wake of this trend. Because domain knowledge is so important, writing things down for others to chime in becomes a critical factor in developing enterprise software. A bunch of JIRA tickets without a deliberate architectural goal is, in the age of data intensive applications, a recipe for disaster.
Almost 270 billion transactions for the 12 months ended June 30, 2023. Sounds like a lot until you realize that a year has roughly 31.5 million seconds.