Design a payment API
I was shopping on an ecommerce site and I got that page while doing payment — which page? that page where it says “please wait, payment is currently in process”.
This blogpost is inspired from above situation. I thought let’s try to understand and try to design similar one.
Problem Statement: Understand and design a payment API for ecommerce.
Firstly, payment API is critical for any business. Proper error handling and edge cases needs to be covered — otherwise customers will be furious. I think pretty much from message we get from this API— we can clearly say that this API takes few extra milliseconds since it has to talk to multiple internal APIs and then give response to the client. Hence pure request response is not answer here. we cannot hold connection so long till everything is processed — definitely will face scaling issues.
Let’s take a real life example to understand the nature of the system.
You are super hungry. You entered any famous food outlet and gave the order. Person who has taken your order doesn’t go back and start making your order, other colleagues of his/her start making your order. Person on counter hands you bill, inform you that your order number with status will be displayed on their customer facing monitor and you can accordingly come to collect the order. Now what you do? Every 2 mins, you check the status of the order on the monitor and if it is shown as completed — you go ahead and pick the order from the counter. This is exactly what happens when we do payment on sites.
Let’s see high level architecture
- Payment Request arrives(with transaction details, amount etc)
- Backend sends the same request to queue.
- Backend sends 202 http status code to client and status check url where client can poll to check status of the transaction ( Few things here — why 202? 202 says we have accepted your request but we are still processing it. I think status check url is super cool concept ( very similar to counter guy telling us you should see status of our order on monitor) and why separate that responsibility? to scale.
- Worker process which has subscribed to the queue picks up the new payment request
- Core payment logic is executed. Worker process calls the core payment service( where it might be checking balance and all etc).
- Just like when you were hungry, you kept checking monitor periodically for your order status, similarly client uses the status check url (obtained from step 3) and check the status of the payment request ( if your request is not finished, that’s why you see that process is happening please don’t refresh the page)
Careful Reader will think — why check periodically, can we do better here? My answer is Yes, we can do better. How? Websockets or dedicated connection between client and server. Subscribe to the event and update the status on client.
Architecture we saw above is fundamental — there are N ways to implement it. I chose azure durable functions. They come with queues, orchestration functions, status check webhook/url and storage to store the state of the execution.
Below is azure durable function code.
I won’t go deep in this code — but will gist of code. There is a gateway function which is like endpoint for client/frontend to call upon. After that there is an orchestration function, which handles coordination across different activity functions — activity function is basically is like core payment service which is actually doing the logic execution.
Below is demo video.
Hope you guys enjoyed reading this one. Now we all know what happens when we get that screen(“please wait, payment is currently in process”)
Happy Learning ☺
P.S This solution is according to my thought process while looking at problem statement. If you think there is better solution, definitely drop it in comment ✌🏻