diff --git a/aleksis/apps/tezor/forms.py b/aleksis/apps/tezor/forms.py
new file mode 100644
index 0000000000000000000000000000000000000000..8c01843050ab1268311701fc5186950a5bff1841
--- /dev/null
+++ b/aleksis/apps/tezor/forms.py
@@ -0,0 +1,10 @@
+from aleksis.core.mixins import ExtensibleForm
+
+from .models.base import Client
+
+class EditEventForm(ExtensibleForm):
+    """Form to create or edit clients."""
+
+    class Meta:
+        model = Client
+        exclude = []
diff --git a/aleksis/apps/tezor/menus.py b/aleksis/apps/tezor/menus.py
new file mode 100644
index 0000000000000000000000000000000000000000..49c9644d489921913cd07a84aeaf217008bfa661
--- /dev/null
+++ b/aleksis/apps/tezor/menus.py
@@ -0,0 +1,29 @@
+from django.utils.translation import gettext_lazy as _
+
+MENUS = {
+    "NAV_MENU_CORE": [
+        {
+            "name": _("Payments"),
+            "url": "#",
+            "root": True,
+            "icon": "price_check",
+            "validators": [
+                "menu_generator.validators.is_authenticated",
+                "aleksis.core.util.core_helpers.has_person",
+            ],
+            "submenu": [
+                {
+                    "name": _("Clients"),
+                    "url": "clients",
+                    "icon": "account_balance",
+                    "validators": [
+                        (
+                            "aleksis.core.util.predicates.permission_validator",
+                            "tezor.can_view_clients",
+                        )
+                    ],
+                },
+            ],
+        }
+    ]
+}
diff --git a/aleksis/apps/tezor/tables.py b/aleksis/apps/tezor/tables.py
index 3cf48132ba0ceab99588815c898defa8b69ce2ee..f240d17d783f427f4b49398747eb3f3b687b438a 100644
--- a/aleksis/apps/tezor/tables.py
+++ b/aleksis/apps/tezor/tables.py
@@ -32,3 +32,17 @@ class TotalsTable(tables.Table):
     class Meta:
         show_header = False
         orderable = False
+
+
+class ClientsTable(tables.Table):
+    class Meta:
+        attrs = {"class": "responsive-table highlight"}
+
+    name = tables.Column()
+
+    edit = tables.LinkColumn(
+        "edit_client_by_pk",
+        args=[A("id")],
+        verbose_name=_("Edit"),
+        text=_("Edit"),
+    )
diff --git a/aleksis/apps/tezor/templates/tezor/client/create.html b/aleksis/apps/tezor/templates/tezor/client/create.html
new file mode 100644
index 0000000000000000000000000000000000000000..634500f5ff3e0352f07a46cc073f19ad382c14e4
--- /dev/null
+++ b/aleksis/apps/tezor/templates/tezor/client/create.html
@@ -0,0 +1,19 @@
+{% extends "core/base.html" %}
+{% load material_form i18n %}
+
+{% block page_title %}{% blocktrans %}Create client{% endblocktrans %}{% endblock %}
+{% block browser_title %}{% blocktrans %}Create client{% endblocktrans %}{% endblock %}
+
+{% block extra_head %}
+    {{ form.media.css }}
+{% endblock %}
+
+{% block content %}
+  <form method="post">
+    {% csrf_token %}
+    {% form form=form %}{% endform %}
+    {% include "core/partials/save_button.html" %}
+  </form>
+
+  {{ form.media.js }}
+{% endblock %}
diff --git a/aleksis/apps/tezor/templates/tezor/client/edit.html b/aleksis/apps/tezor/templates/tezor/client/edit.html
new file mode 100644
index 0000000000000000000000000000000000000000..3c193950bc685dc5224f9f2248fbbd60a8639827
--- /dev/null
+++ b/aleksis/apps/tezor/templates/tezor/client/edit.html
@@ -0,0 +1,18 @@
+{% extends "core/base.html" %}
+{% load material_form i18n %}
+
+{% block page_title %}{% blocktrans %}Edit client{% endblocktrans %}{% endblock %}
+{% block browser_title %}{% blocktrans %}Edit client{% endblocktrans %}{% endblock %}
+
+{% block extra_head %}
+    {{ form.media.css }}
+{% endblock %}
+
+{% block content %}
+  <form method="post">
+    {% csrf_token %}
+    {% form form=form %}{% endform %}
+    {% include "core/partials/save_button.html" %}
+  </form>
+  {{ form.media.js }}
+{% endblock %}
diff --git a/aleksis/apps/tezor/templates/tezor/client/list.html b/aleksis/apps/tezor/templates/tezor/client/list.html
new file mode 100644
index 0000000000000000000000000000000000000000..e8b32263958ec250023248fcb08b75022ca05c79
--- /dev/null
+++ b/aleksis/apps/tezor/templates/tezor/client/list.html
@@ -0,0 +1,14 @@
+{% extends "core/base.html" %}
+{% load material_form i18n %}
+
+{% load render_table from django_tables2 %}
+
+{% block page_title %}{% blocktrans %}Clients{% endblocktrans %}{% endblock %}
+{% block browser_title %}{% blocktrans %}Clients{% endblocktrans %}{% endblock %}
+
+{% block content %}
+
+    <a class="btn colour-primary waves-effect waves-light" href="{% url 'create_client' %}">{% trans "Create client" %}</a>
+    {% render_table table %}
+
+{% endblock %}
diff --git a/aleksis/apps/tezor/templates/tezor/empty.html b/aleksis/apps/tezor/templates/tezor/empty.html
deleted file mode 100644
index 2fb4415f4772cd40a8eb40e290d50f912c4f219f..0000000000000000000000000000000000000000
--- a/aleksis/apps/tezor/templates/tezor/empty.html
+++ /dev/null
@@ -1,8 +0,0 @@
-{% extends 'core/base.html' %}
-{% load i18n %}
-
-{% block content %}
-  <p class="flow-text">
-   {% blocktrans %}Tezor (account and payment system){% endblocktrans %}
-  </p>
-{% endblock %}
diff --git a/aleksis/apps/tezor/urls.py b/aleksis/apps/tezor/urls.py
index 571809cf71d6d08182a261b2aa26cde2155b6844..441f5815649370b863df0aab8e2b2ae754ba682f 100644
--- a/aleksis/apps/tezor/urls.py
+++ b/aleksis/apps/tezor/urls.py
@@ -5,4 +5,19 @@ from . import views
 urlpatterns = [
     path("payments/", include("payments.urls")),
     path("invoice/<int:pk>/print", views.GetInvoicePDF.as_view(), name="get_invoice_by_pk")
+    path(
+        "clients/list",
+        views.ClientListView.as_view(),
+        name="clients",
+    ),
+    path(
+        "clients/create",
+        views.ClientCreateView.as_view(),
+        name="create_client",
+    ),
+    path(
+        "clients/<int:pk>/edit",
+        views.ClientEditView.as_view(),
+        name="edit_client_by_pk",
+    ),
 ]
diff --git a/aleksis/apps/tezor/views.py b/aleksis/apps/tezor/views.py
index 22fe10830ab05dd5688ae8bf2a498a4e406ec45b..1723edc3d99411a2d1ca72827ddc695897af4a19 100644
--- a/aleksis/apps/tezor/views.py
+++ b/aleksis/apps/tezor/views.py
@@ -5,6 +5,9 @@ from rules.contrib.views import PermissionRequiredMixin
 
 from aleksis.core.views import RenderPDFView
 
+from .tables import ClientsTable
+from .forms import EditClientForm
+from .models.base import Client
 from .models.invoice import Invoice
 
 
@@ -20,3 +23,35 @@ class GetInvoicePDF(PermissionRequiredMixin, RenderPDFView):
 
         print(invoice.group.__dict__)
         return context
+
+class ClientListView(PermissionRequiredMixin, SingleTableView):
+    """Table of all clients."""
+
+    model = Client
+    table_class = ClientsTable
+    permission_required = "teor.view_clients"
+    template_name = "teor/client/list.html"
+
+
+@method_decorator(never_cache, name="dispatch")
+class ClientCreateView(PermissionRequiredMixin, AdvancedCreateView):
+    """Create view for clients."""
+
+    model = Client
+    form_class = EditClientForm
+    permission_required = "teor.add_clients"
+    template_name = "teor/client/create.html"
+    success_url = reverse_lazy("clients")
+    success_message = _("The client has been created.")
+
+
+@method_decorator(never_cache, name="dispatch")
+class ClientEditView(PermissionRequiredMixin, AdvancedEditView):
+    """Edit view for clients."""
+
+    model = Client
+    form_class = EditClientForm
+    permission_required = "teor.edit_clients"
+    template_name = "teor/client/edit.html"
+    success_url = reverse_lazy("clients")
+    success_message = _("The client has been saved.")