Disclaimer: Writing this post for my own practice. Read it at your own discretion
We have to design an OTP service for an E-Commerce website like amazon. It could have multiple places of generating OTPs like e-commerce portal, Amazon Pay, primevideo, etc. Each service that requests for the OTP should get an OTP each OTP should be unique for User and service.
**Functional Requirements: **
Each service should be able to generate an OTP and each tuple order_id tuple should be unique for a specified time period -- say a week
User should be able to validate himself against that OTP
User should not be able to enter the OTP for any other user.
**Non-functional requirements: **
Delivery latency should be low.
Service should be consistent
Service should be as available as possible
Durability the generated OTPs should be available till the time user
**Some questions to ask the interviewer: **
Do we have different portals for different countries?
No.
Do we have 2-factor authentication enabled for users and will this use our service? (As this can increase the calls to our service by a lot)
No.
Is the OTP alphanumeric or just numeric?
It is just numeric
Does it matter from a security point of view if 2 users have the same OTP?
It might matter.
**Capacity estimation: **
Lets say we have 100 million users of which 50 million are DAUs
Lets each DAU views 10 items on the website and 1% of all views gets converted into OTP generation
So number of OTP generated in a day 50 million100.01 = 5 million;
Number of OTPs in a week = 75 = 35 million;
Number of digits in our OTP = 8
Number of OTPs per hour ~ 200K
Number of OTPs per sec = 200/(6060) < 1K
**APIs for our service: **
generateOTPForOrder(service_id, user_id, order_id, channel);
Generates OTP for the particular service, user and order ids and sends it via the specified channel.
validateOTPForOrder(service_id, user_id, order_id, OTP)
Checks if the OTP provided is for that particular user and service and for that particular order.
**Basic Design: **

**Flow of control: **
**Generation: **
Client service queries Service discovery to find the OTP service’s LB
LB leads client to the appropriate instance of OTP service.
OTP service calls the generator service to get an unique OTP for the order_id
The otp service saves the OTP against order_id, user_id, service_id, number_of_attempts
And returns the OTP to the OTP service.
The OTP service sends it to the sender service which passes it down to the message queue from there respective message consumers can consume this message.
**Validation: **
Client service asks the OTP service to validate the service_id, user_id, order_id and tuple and the OTP service tells if it is valid or not.
**Re-generate OTP: **
If the user is somehow unable to receive the OTP or if there is latency in the OTP delivery she/he can ask for a re-generation.
In this case, the flow will be same as generation with the number_of_attempts increased if retries cross a particular pre-defined number then we could throw an error as max allowed retries exceeded.
**Other questions: **
What will our partition strategy?
On our database side we could partition our databases on order_id as it will prevent hotspot for users and services.
On the Kafka side we can have a partition strategy based on service_id so that on service does not slow down other service and the OTPs generated by a service always arrive in sequence.
Can our service benefit from cache?
Since our read-write ratio is 1:1 mostly cache would be an overkill but still we plan to have cache, we can have cache on the generator service side which will store a OTP on the cache once it generates.
Please suggest improvements if you have something in mind