System Design Nuggets

System Design Nuggets

System Design Interview: Designing a Payment Gateway

Master payment system design for interviews. Learn how to prevent double charges using Idempotency Keys, ensure data integrity with ACID transactions, & handle asynchronous banking delays via Webhooks

Arslan Ahmad's avatar
Arslan Ahmad
Jan 30, 2026
∙ Paid

Digital payments are the invisible engine of the modern internet.

Every second, millions of transactions occur across the globe, moving funds from one account to another with seemingly instant speed.

While the user experience is designed to be a simple tap or click, the engineering reality behind that action is a complex orchestration of distributed systems.

For a developer, understanding this process is about more than just knowing how to integrate a payment API. It requires a deep appreciation for reliability, data integrity, and the chaotic nature of networks. When money is on the line, “good enough” is not an option. A lost packet or a crashed server cannot result in a user losing money or a merchant not getting paid.

This post explores the technical architecture of a payment transaction. We will look at how engineers design systems that can withstand failure, focusing on three critical concepts: Idempotency Keys, ACID Compliance, and Third-Party Webhooks.

The Inevitability of Network Failure

The fundamental challenge in any distributed system is that networks are unreliable. In a perfect world, a client would send a request to a server, the server would process it, and then send a confirmation back. The client would always know exactly what happened.

In the real world, connections drop. Servers time out. Latency spikes.

When a user initiates a payment, their device sends a request to a payment service. If the internet connection flickers just after that request is sent, the user’s device never receives a response. This leaves the system in an indeterminate state.

Did the server receive the request and charge the card? Or did the request never reach the server at all?

If the user assumes it failed and tries again, they risk being charged twice. If the user assumes it succeeded but it actually failed, the merchant never gets paid. Solving this ambiguity is the first major hurdle in payment system design.

The Solution: Idempotency Keys

To prevent double charges in an unreliable network, engineers implement a pattern called idempotency.

An idempotent operation is one that can be applied multiple times without changing the result beyond the initial application. In the context of an API, this means that making the same request ten times has the exact same effect as making it once.

This is achieved using an Idempotency Key.

When the client (the frontend application or mobile app) initiates a transaction, it generates a unique string of characters. This is the Idempotency Key. This key is often a UUID (Universally Unique Identifier). The client sends this key along with the payment details in the API header.

Keep reading with a 7-day free trial

Subscribe to System Design Nuggets to keep reading this post and get 7 days of free access to the full post archives.

Already a paid subscriber? Sign in
© 2026 Arslan Ahmad · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture