Introduction
In a significant move toward physical retail expansion, Revolut is opening its first physical store in Barcelona. This development represents a shift from purely digital banking to a hybrid model that combines online services with physical presence. In this tutorial, you'll learn how to build a simple point-of-sale (POS) system using Python and a simulated payment processing API that mirrors the technology Revolut might be using for its physical stores.
This tutorial will teach you how to create a basic POS system that can process payments, track transactions, and maintain inventory - all core components of a physical retail store like Revolut's new Barcelona location.
Prerequisites
- Python 3.7 or higher installed on your system
- Basic understanding of Python programming concepts
- Knowledge of REST APIs and HTTP requests
- Basic understanding of database concepts (SQLite is used in this tutorial)
Step-by-Step Instructions
1. Set Up Your Development Environment
First, create a new directory for your POS system project and set up a virtual environment to keep dependencies isolated.
mkdir revolut-pos-system
cd revolut-pos-system
python -m venv pos_env
source pos_env/bin/activate # On Windows: pos_env\Scripts\activate
This step ensures you have a clean environment for your project, preventing conflicts with other Python packages on your system.
2. Install Required Dependencies
Install the necessary Python packages for our POS system:
pip install requests
pip install sqlite3
The requests library will help us make HTTP calls to simulate payment processing, while SQLite will handle our local database storage.
3. Create the Database Structure
Create a file called database.py to set up your SQLite database:
import sqlite3
def init_db():
conn = sqlite3.connect('pos_system.db')
c = conn.cursor()
# Create products table
c.execute('''
CREATE TABLE IF NOT EXISTS products (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
price REAL NOT NULL,
stock INTEGER NOT NULL
)
''')
# Create transactions table
c.execute('''
CREATE TABLE IF NOT EXISTS transactions (
id INTEGER PRIMARY KEY,
product_id INTEGER,
quantity INTEGER,
total_amount REAL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (product_id) REFERENCES products (id)
)
''')
conn.commit()
conn.close()
# Initialize the database
init_db()
This database structure allows us to track products and their inventory, as well as record transaction history. The design mirrors the kind of backend systems that would support a physical store like Revolut's.
4. Implement Product Management
Create a products.py file to manage product inventory:
import sqlite3
class ProductManager:
def __init__(self, db_path='pos_system.db'):
self.db_path = db_path
def add_product(self, name, price, stock):
conn = sqlite3.connect(self.db_path)
c = conn.cursor()
c.execute("INSERT INTO products (name, price, stock) VALUES (?, ?, ?)", (name, price, stock))
conn.commit()
conn.close()
def get_product(self, product_id):
conn = sqlite3.connect(self.db_path)
c = conn.cursor()
c.execute("SELECT * FROM products WHERE id = ?", (product_id,))
product = c.fetchone()
conn.close()
return product
def update_stock(self, product_id, quantity):
conn = sqlite3.connect(self.db_path)
c = conn.cursor()
c.execute("UPDATE products SET stock = stock - ? WHERE id = ?", (quantity, product_id))
conn.commit()
conn.close()
def list_products(self):
conn = sqlite3.connect(self.db_path)
c = conn.cursor()
c.execute("SELECT * FROM products")
products = c.fetchall()
conn.close()
return products
This class allows you to add, retrieve, and update product information - essential functionality for managing inventory in a physical store.
5. Create Payment Processing Simulation
Create a payment_processor.py file to simulate payment processing:
import requests
import json
class PaymentProcessor:
def __init__(self):
self.base_url = "https://api.revolut.com/" # Simulated endpoint
def process_payment(self, amount, card_details):
# Simulate payment processing
payment_data = {
"amount": amount,
"currency": "EUR",
"card": card_details,
"status": "approved"
}
# In a real system, this would make an actual HTTP request
# response = requests.post(f"{self.base_url}payments", json=payment_data)
# For simulation purposes, we'll return a mock response
return {
"status": "success",
"transaction_id": "txn_123456789",
"amount": amount,
"timestamp": "2023-01-01T12:00:00Z"
}
This simulates how Revolut might process payments in their physical stores, handling card details and transaction processing.
6. Build the Main POS System
Create a pos_system.py file to tie everything together:
from database import init_db
from products import ProductManager
from payment_processor import PaymentProcessor
init_db()
product_manager = ProductManager()
payment_processor = PaymentProcessor()
class POSSystem:
def __init__(self):
self.cart = []
def display_products(self):
products = product_manager.list_products()
print("\nAvailable Products:")
for product in products:
print(f"ID: {product[0]}, Name: {product[1]}, Price: €{product[2]}, Stock: {product[3]}")
def add_to_cart(self, product_id, quantity):
product = product_manager.get_product(product_id)
if product and product[3] >= quantity:
self.cart.append({
"product_id": product[0],
"name": product[1],
"price": product[2],
"quantity": quantity
})
print(f"Added {quantity} x {product[1]} to cart")
else:
print("Insufficient stock or product not found")
def calculate_total(self):
total = sum(item["price"] * item["quantity"] for item in self.cart)
return total
def checkout(self):
if not self.cart:
print("Cart is empty")
return
total = self.calculate_total()
print(f"\nTotal amount: €{total}")
# Process payment
card_details = {
"number": "4242424242424242",
"expiry_month": "12",
"expiry_year": "2025",
"cvc": "123"
}
payment_result = payment_processor.process_payment(total, card_details)
if payment_result["status"] == "success":
print("Payment successful!")
# Update inventory
for item in self.cart:
product_manager.update_stock(item["product_id"], item["quantity"])
# Record transaction
self.record_transaction()
self.cart = []
else:
print("Payment failed")
def record_transaction(self):
conn = sqlite3.connect('pos_system.db')
c = conn.cursor()
for item in self.cart:
c.execute("INSERT INTO transactions (product_id, quantity, total_amount) VALUES (?, ?, ?)",
(item["product_id"], item["quantity"], item["price"] * item["quantity"]))
conn.commit()
conn.close()
This main system integrates all components and simulates the complete checkout process that customers would experience in a physical store.
7. Create a Simple User Interface
Create a main.py file to run the POS system:
from pos_system import POSSystem
# Initialize POS system
pos = POSSystem()
# Add some sample products
from products import ProductManager
pm = ProductManager()
pm.add_product("Revolut Card", 10.0, 100)
pm.add_product("Digital Wallet", 5.0, 50)
pm.add_product("Premium Subscription", 20.0, 25)
# Main menu loop
while True:
print("\n=== Revolut POS System ===")
print("1. View Products")
print("2. Add to Cart")
print("3. Checkout")
print("4. Exit")
choice = input("Enter your choice: ")
if choice == "1":
pos.display_products()
elif choice == "2":
try:
product_id = int(input("Enter product ID: "))
quantity = int(input("Enter quantity: "))
pos.add_to_cart(product_id, quantity)
except ValueError:
print("Invalid input")
elif choice == "3":
pos.checkout()
elif choice == "4":
break
else:
print("Invalid choice")
print("Thank you for using Revolut POS System!")
This interface provides a user-friendly way to interact with the POS system, mimicking the experience of a customer in a physical store.
Summary
In this tutorial, you've built a simplified point-of-sale system that demonstrates core concepts behind physical retail operations like those at Revolut's Barcelona store. You've created a database to manage products and transactions, implemented product management functionality, simulated payment processing, and built a user interface for customer interaction.
This system represents the kind of technology stack that would support physical retail expansion, combining inventory management, transaction processing, and customer interaction in a single integrated system. While this is a simplified version, it demonstrates the foundational elements that would be expanded upon in a real-world implementation for a company like Revolut.



