OTP-less payment system


One of my friends needed a project, the final project for his bachelor's degree. Since he already worked in the financial sector, his idea was to create something related to it, be it a banking system, payment system, or the like. The project requirements were clear: it must solve a problem in the sector. That's all.

Problem with OTP

Given his familiarity with issues in his field, we decided to develop a payment system without a One-Time Password (OTP). I don't know about other countries, but in my country, OTP is mandatory for fraud protection. However, the problem persisted because, despite OTP being designed to protect users from fraud, some attackers still managed to bypass the system by deceiving users. Most users were unaware of OTPs or frauds, viewing the OTP process as troublesome. Almost all OTPs were sent to their phone number or email address. If a phone number isn't used for more than 6 months, service providers may cancel it without notification, potentially allowing unknown individuals to access OTPs, constituting a significant security breach. Additionally, network coverage issues caused delays and unresponsiveness. From my perspective, the actual solution was to educate people and service providers rather than building a new payment system.

Given his daily interactions with such customers, my friend was well aware of this issue. Hence, we decided to create a payment system, specifically a payment process without OTPs. So, I designed the architecture.


Enindu Alahapperuma otp-less payment system

Let me break this down.

This system has four components. The fourth component, the core component, is managed by the bank. Although not directly depicted in this architecture, it's included to avoid any confusion.

  1. Client component: The monolithic web application acts as a client, communicating only with authentication and middleware components.
  2. Authentication component: It acts as both client and server, communicating only with the client and middleware components.
  3. Middleware component: It acts as both client and server, communicating with the client, authentication, and core components.
  4. Core component: This belongs to the bank and communicates only with the middleware component.

Every component communicates with each other via Hypertext Transfer Protocol (HTTP) with Transport Layer Security (TLS) v1.2 or v1.3 and basic authentication. All requests are passed as JavaScript Object Notation (JSON).

Create transaction flow

Let me break down how the "Create transaction" method would work step-by-step, as demonstrated in the above diagram.

  1. If a user wants to use the system, they need to register by invoking the "Register" method. Note that the "Register" method is not demonstrated in the diagram. When the "Register" method is invoked, a "Device ID" will be created and stored in the client. The "Device ID" is a unique ID created only for the current device the user uses to register.
  2. The client sends a request to the authentication with the "Device ID".
  3. The authentication creates an "Authentication key".
  4. The authentication sends a request to the middleware with "Device ID" and "Authentication key".
  5. The middleware creates a "Middleware key" and stores "Device ID", "Authentication key", and "Middleware key" in its database.
  6. The middleware sends a response to the authentication with "Middleware key".
  7. The authentication sends a response to the client with the "Middleware key".
  8. The client sends a request to the middleware with "Device ID", "Middleware key", and "Transaction".
  9. The middleware validates "Device ID", "Authentication key", and "Middleware key".
  10. If the above validation was successful, the middleware sends a request to the core with "Transaction". If unsuccessful, the middleware sends a response to the client with an error message.
  11. The core processes "Transaction", managed by the bank.
  12. If the above process was either successful or unsuccessful, the core sends a response to the middleware with "Transaction details" and "Account details".
  13. The middleware sends a response to the client with "Transaction details" and "Account details".
  14. The client stores "Account details" in its database.

That's the overview of the "Create transaction" method. The authentication component serves as an alternative to the OTP system, working similarly to the OTP system but without requiring users to type OTP manually; the system validates it during the process.


I also created a demonstrative system in Go and PHP languages, which you can find in the link below. Note that back in the day, I had a homemade MVC framework written on top of the Slim framework. I used it to build the client component. Don't get confused with it.

Link: https://github.com/enindu/otp-less-payment-system

You will need to create required SSL certificates manually to run this code. Read the README.md file for more details.

Note that this is just a demonstration. Basic authentication is done in plain text. This system is not secure at all.

How will this solve the OTP issue?

The combination of the authentication and middleware components does the job. The Authentication component creates the "Authentication key", and the middleware component creates the "Middleware key." Both keys are stored in the middleware component. Only the "Middleware key" goes through the client component, specifically, the "Middleware key" process in the back-end of the client component, making it inaccessible for users but still functioning as an OTP system.


That system was built a long time ago. As I see it today, I would like to change the system like this.

  1. Both "Authentication key" and "Middleware key" should be created in the authentication component. The middleware component must only handle validation.
  2. The "Device ID" should be dynamic for each request to enhance the security of the system.
  3. Perhaps, add password-less authentication for the client component, like using email. This would enhance security and pass liability to the customer, similar to an OTP system. However, this might introduce more difficulties; let's consider it.


I didn't conduct any case studies to create this system. So, this might already be created somewhere. Also, I don't claim that this is the best system. At least, this was the best system I could think of back in the day. Finally, this idea is purely mine. I have no intention of revealing someone else's ideas, as I don't know if they had the same idea.