Managing Changing Hardware/Peripherals in a Robust Point of Sale System
This analysis discusses my thoughts on implementing a secure, scalable architecture to manage changing peripherals through programming to interface.
Join the DZone community and get the full member experience.
Join For FreeRetail point-of-sale systems today offer a wide range of options for peripherals and hardware. Their technical specifications play a major role in selection, and big retailers often choose multiple vendors to reduce a single point of failure. This gives them an advantage to negotiate price or support as well. Technically, these peripherals also require updating with new models and may have new feature sets. This necessitates the redevelopment of point-of-sale applications, increasing development costs.
Another problem with managing hardware interactions is that rapid scanning would generate a burst of requests, and we need a mechanism to handle them all. Failure to do so would result in lost messages, eventually causing poor customer experience or loss to retailers as they would sell items not scanned properly.
Security is also an important aspect. We want messages through a secure channel to ensure that when we are handling payment card data, we do it securely. Otherwise, we would not meet PCI compliance rules for the payment industry.
The following architecture outlines a way to remediate these problems.
Architecture Overview
To mitigate this challenge, we adapted programming to an interface model and added a layer for transformations. This approach gave us a seamless transition when using new hardware and its libraries. It encapsulates the application's complexity and ensures interoperability.
Key components of this architecture are:
- Application: This is a point-of-sale application that encapsulates all business logic and interactions with backend APIs hosted in the cloud or on an in-house server.
- Listeners/Emitters: This is code packaged as a library that securely exchanges messages from the message bus.
- Message Bus: A queue library like Apache MQ, which stores messages temporarily until they are read.
- WebSocket Secure: WebSocket is a real-time bidirectional communication protocol. This provides a communication channel between peripherals and listeners/emitters.
- Peripherals Interface layer: Interface layers that have basic definitions of function, for example, readUniversalProductCode(). This encapsulates complexity from the application layer as the application only cares on the value of UniversalProductCode and not how its read from the barcode on the product.
- Peripherals Implementation layer: This layer contains the implementation aspect of the function with respect to the peripheral type and the library. For example, readUniversalProductCode() can be implemented in two ways: one for a Honeywell hand scanner and another for a Zebra hand scanner. Based on the hardware of the point of sale, we can choose the implementation at runtime.
Architecture Diagram:

Architecture Details:
- Decoupled Application Layer: Point-of-sale applications can be developed and maintained independently. Since we have used programming to interface, applications do not see changes or regressions with evolving peripheral changes.
- Listeners/Emitters: The code to listen to messages and send messages to prompt hardware to take action can be abstracted from the Application Layer. Listeners and Emitters contain custom logic to open web WebSocket connection with the Message bus securely and send/receive messages. For example, let's say a customer has finished building a cart and wants to initiate payment. The application can use the emitter library to emit an event to the payment pinpad that shows UX: "Please insert your card" to the customer.
- Handling bursts of messages via a message bus: Often, one notices that customers or associates scan items super fast. They want to build the cart quickly and help customers walk out the store without spending unnecessary time at the checkout line. This creates a burst of messages for the application to read. A message queue enables storing these messages, which listeners can read, and applications can take action based on them. This provides a way to throttle messages without overwhelming the application.
- Fast and secure exchange of messages via WebSocket secure:
- In this event-driven model, we ensured that messages are transferred without delay. Standard protocols like HTTP require a handshake between the client and the producer, introducing latency in operations. We used a web socket in this architecture, which does setup only once, and all the following interactions happen over a low-latency topic, enabling fast exchange of messages.
- Since a customer uses their payment details at the point of sale, managing messages securely is of paramount importance. We also need to be PCI compliant. We set up a secure web socket where we added certificates to the reader and writer to the message queue and ensured we read and write messages securely.
- Seamless swapping of peripherals via programming to the Interface: Since we have programmed via the interface model, we have decoupled application logic from the hardware implementation layer. The application becomes immune to changing hardware. This saves a lot of development and regression effort when we upgrade hardware or switch to a different vendor.
Other Advantages of this architecture:
- One common approach I have usually seen is running a hardware library as a server and exchanging messages via APIs over HTTPS. While this saves time in setup and reduces the overall components in the architecture, it has its downsides. HTTP protocol requires opening a new connection for every message exchange. This increases the overall time spent between events created and events consumed. If we need a fast exchange of messages, this approach is suggested. Popular messaging apps like WhatsApp also prefer web WebSocket persistent connection.
- Durability of messages using message queues. Another advantage of using a messaging queue is that messages stay in the queue unless they are read. We can set the quorum to a config that ensures messages are read once, and then they are tagged for deletion. Hence, this architecture outlines that messages are not lost and appropriate applications can read them.
Conclusion:
This architectural approach offers a robust and adaptable solution for managing the complexities of point-of-sale systems that rely on diverse and evolving hardware/peripherals. By embracing an interface-driven design, incorporating a secure message bus, and leveraging the speed of WebSockets, we can ensure seamless integration of new peripherals, maintain high performance even during peak demand, and uphold the critical security standards required for payment transactions. This strategy not only mitigates development costs and regression issues but also significantly enhances the overall customer experience by providing a reliable and efficient checkout process.
Opinions expressed by DZone contributors are their own.
Comments