How Stripe Prevents Double Payment Using Idempotent API
#45: A Simple Introduction to Idempotent API (4 minutes)
Get my system design playbook for FREE on newsletter signup:
This post outlines how Stripe implements idempotent API. If you want to learn more, scroll to the bottom and find the references.
Share this post & I'll send you some rewards for the referrals.
Note: This post is based on my research and may differ from real-world implementation.
2010 - California, United States.
Two brothers want to run a business.
Yet they found it difficult to set up an online payment for it.
So they pivoted to create an online payment service and called it Stripe.
As number of users grew, double payment became an issue for them.
That means, mistakenly charging a user twice for the same transaction.
Here are some reasons for this:
1. Server Error
The request fails while the server processes it.
But the client doesn’t know whether the request was successful or not.
So it isn’t safe to retry.
Otherwise, there might be a double payment.
2. Network Error
The server processed the request successfully.
But the network connection failed before returning a response to the client.
So the client doesn’t know if the request was successful.
Hence it isn’t safe to retry.
Otherwise, there might be a double payment.
Hungry Minds (Featured)
Learning system design is about staying hungry.
Hungry Minds scans 100+ sources for the best deep dives, trends, and tools for software engineers to stay ahead.
Join 9,001+ engineers from big tech to startups for 1 free digest every Monday.
Idempotent API
They wanted to solve the double payment problem in the best possible way.
And as in most cases, the simplest solution is the best solution.
So they created an idempotent API.
It guarantees that a specific request can be retried many times without side effects.
That means a specific request gets processed exactly once even after many retries.
Here’s how Stripe implements idempotent API:
1. Idempotency Keys
They should process a request only if it wasn't processed earlier.
This means they must track requests processed by the server.
So they create a unique string (UUID) to use as the idempotency key.
And send it with each request’s HTTP header.
Also they generate a new UUID whenever the request payload changes.
Imagine the idempotency key as a fingerprint to find whether a request has already been processed.
They store the idempotency keys with an in-memory database on the server side.
And cache the server response after a request gets processed successfully.
So the in-memory database gets queried to check whether a request has been processed.
They process a request only if it's new and then store its idempotency key in the database.
Otherwise, the cached response gets returned. This means the request was processed earlier.
Also they roll back a transaction using the ACID database when a server error occurs.
Besides they remove the idempotency keys from the in-memory database after 24 hours.
It helps to reduce storage costs and gives enough time to retry failed requests.
Put another way, an idempotency key could be reused after that period.
2. Retrying Failed Requests
Although it’s safe to retry using an idempotency key, there’s a risk of server overload with many requests.






