diff --git a/aleksis/apps/tezor/menus.py b/aleksis/apps/tezor/menus.py
index 1355051be6de23342f18e317f4382aa68a96452e..30701d462d46ad2f20aeffb60e0e3b5c01a7f05f 100644
--- a/aleksis/apps/tezor/menus.py
+++ b/aleksis/apps/tezor/menus.py
@@ -6,7 +6,7 @@ MENUS = {
             "name": _("Payments and Money"),
             "url": "#",
             "root": True,
-            "svg_icon": "mdi:piggy_bank",
+            "svg_icon": "mdi:piggy-bank",
             "validators": [
                 "menu_generator.validators.is_authenticated",
                 "aleksis.core.util.core_helpers.has_person",
diff --git a/aleksis/apps/tezor/migrations/0004_client_email.py b/aleksis/apps/tezor/migrations/0004_client_email.py
new file mode 100644
index 0000000000000000000000000000000000000000..c6f4a5c7b5106d312538dc16b9a94e5950044be1
--- /dev/null
+++ b/aleksis/apps/tezor/migrations/0004_client_email.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.2.12 on 2022-03-09 20:36
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('tezor', '0003_manual_invoicing'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='client',
+            name='email',
+            field=models.EmailField(default='', max_length=254, verbose_name='Email'),
+            preserve_default=False,
+        ),
+    ]
diff --git a/aleksis/apps/tezor/models/base.py b/aleksis/apps/tezor/models/base.py
index 459f9b22b924289f33a4f192e28b2794973184e0..85f85ccf9f3d67cc362c6704852c81602f958101 100644
--- a/aleksis/apps/tezor/models/base.py
+++ b/aleksis/apps/tezor/models/base.py
@@ -6,6 +6,7 @@ from aleksis.core.mixins import ExtensibleModel
 
 class Client(ExtensibleModel):
     name = models.CharField(verbose_name=_("Name"), max_length=255)
+    email = models.EmailField(verbose_name=_("Email"))
 
     class Meta:
         constraints = [
diff --git a/aleksis/apps/tezor/models/invoice.py b/aleksis/apps/tezor/models/invoice.py
index af5cb872fd1dfa856522c9a7da269d596f586d3c..33a3791f8cb838a9b4431cb7b8b6f47c0c3f11aa 100644
--- a/aleksis/apps/tezor/models/invoice.py
+++ b/aleksis/apps/tezor/models/invoice.py
@@ -81,6 +81,11 @@ class Invoice(BasePayment, PureDjangoModel):
     )
     items = models.ManyToManyField("InvoiceItem", verbose_name=_("Invoice items"))
 
+    class Meta:
+        permissions = (
+            ("send_invoice_email", _("Can send invoice by email")),
+        )
+
     @classmethod
     def get_variant_choices(cls):
         choices = []
@@ -98,10 +103,12 @@ class Invoice(BasePayment, PureDjangoModel):
         return self.__class__.STATUS_ICONS[self.status]
 
     def get_purchased_items(self):
-        for item in self.items.all():
-            yield item.as_purchased_item()
+        if self.items.count():
+            for item in self.items.all():
+                yield item.as_purchased_item()
         else:
-            return self.for_object.get_purchased_items()
+            for item in self.for_object.get_purchased_items():
+                yield item
 
     def get_person(self):
         if self.person:
@@ -122,6 +129,12 @@ class Invoice(BasePayment, PureDjangoModel):
             ),
         ]
 
+    def get_billing_email_recipients(self):
+        if hasattr(self.for_object, "get_billing_email_recipients"):
+            return self.for_object.get_billing_email_recipients()
+        else:
+            return [self.billing_email]
+
     @property
     def purchased_items_table(self):
         items = [i._asdict() for i in self.get_purchased_items()]
@@ -154,11 +167,14 @@ class Invoice(BasePayment, PureDjangoModel):
 
         return TotalsTable(values)
 
-    def get_success_url(self):
+    def get_absolute_url(self):
         return reverse("invoice_by_token", kwargs={"slug": self.token})
 
+    def get_success_url(self):
+        return self.get_absolute_url()
+
     def get_failure_url(self):
-        return reverse("invoice_by_token", kwargs={"slug": self.token})
+        return self.get_absolute_url()
 
 
 class InvoiceItem(ExtensibleModel):
diff --git a/aleksis/apps/tezor/rules.py b/aleksis/apps/tezor/rules.py
index 8f2e4f8916673689f8e773e9d03b04d7660d5ccc..3adb6f722d00cc0090dcb10683f185df73a87ba4 100644
--- a/aleksis/apps/tezor/rules.py
+++ b/aleksis/apps/tezor/rules.py
@@ -134,3 +134,11 @@ print_invoice_predicate = (
     view_invoice_predicate & display_billing_predicate & display_purchased_items_predicate
 )
 rules.add_perm("tezor.print_invoice_rule", print_invoice_predicate)
+
+# Send invoice email
+send_invoice_email_predicate = (
+    has_person & is_own_invoice
+    | has_global_perm("tezor.send_invoice_email")
+    | has_object_perm("tezor.send_invoice_email")
+)
+rules.add_perm("tezor.send_invoice_email_rule", send_invoice_email_predicate)
diff --git a/aleksis/apps/tezor/tasks.py b/aleksis/apps/tezor/tasks.py
new file mode 100644
index 0000000000000000000000000000000000000000..3e0569dc58ea178ccd7328a7483ed45b56ff5186
--- /dev/null
+++ b/aleksis/apps/tezor/tasks.py
@@ -0,0 +1,23 @@
+from aleksis.core.celery import app
+from aleksis.core.util.email import send_email
+from aleksis.core.util.pdf import generate_pdf_from_template
+
+from .models.invoice import Invoice
+
+@app.task
+def email_invoice(invoice_token):
+    context = {}
+    invoice = Invoice.objects.get(token=invoice_token)
+    context["invoice"] = invoice
+
+    invoice_pdf, result = generate_pdf_from_template(invoice.group.template_name, context)
+    result.wait(timeout=30, disable_sync_subtasks=False)
+    invoice_pdf.refresh_from_db()
+
+    send_email(
+        template_name="invoice",
+        from_email=invoice.group.client.email,
+        recipient_list=invoice.get_billing_email_recipients(),
+        context=context,
+        attachments=[(invoice_pdf.file.name, invoice_pdf.file.read(), "application/pdf")],
+    )
diff --git a/aleksis/apps/tezor/templates/templated_email/invoice.email b/aleksis/apps/tezor/templates/templated_email/invoice.email
new file mode 100644
index 0000000000000000000000000000000000000000..8fe6d0572efd6ff1786a71ce771e23e758818b3e
--- /dev/null
+++ b/aleksis/apps/tezor/templates/templated_email/invoice.email
@@ -0,0 +1,21 @@
+{% extends "templated_email/base.email" %}
+{% load i18n %}
+
+{% block subject_content %}{% trans "Invoice" %} {{ invoice.number }}{% endblock %}
+
+{% block html_content %}
+<p>
+    {% blocktrans with number=invoice.number description=invoice.description %}
+    Please find attached invoice number {{ number }} for {{ description }}.
+    Please carefully read the PDF file concerning all payment details.
+    {% endblocktrans %}
+</p>
+{% if invoice.status == "waiting" %}
+<p>
+    {% blocktrans %}
+    Please visit the following link to view and make the payment:
+    {% endblocktrans %}
+</p>
+<a href="{{ BASE_URL }}{{ invoice.get_absolute_url }}">{{ BASE_URL }}{{ invoice.get_absolute_url}}</a>
+{% endif %}
+{% endblock %}
diff --git a/aleksis/apps/tezor/templates/tezor/invoice/full.html b/aleksis/apps/tezor/templates/tezor/invoice/full.html
index 345aed939f0ef2ad1e2e8a15b58d18286c0c9eae..01576f32b22e02007bb7c4232c0079eb669c8645 100644
--- a/aleksis/apps/tezor/templates/tezor/invoice/full.html
+++ b/aleksis/apps/tezor/templates/tezor/invoice/full.html
@@ -12,6 +12,7 @@
     {% has_perm 'tezor.display_purchased_items_rule' user object as can_view_purchased_items %}
     {% has_perm 'tezor.display_billing_rule' user object as can_view_billing_information %}
     {% has_perm 'tezor.print_invoice_rule' user object as can_print_invoice %}
+    {% has_perm 'tezor.send_invoice_email_rule' user object as can_send_invoice_email %}
 
     <h1>{% trans "Invoice" %} {{ object.number }} — {{ object.created.date }}</h1>
 
@@ -21,6 +22,9 @@
     {% if can_print_invoice %}
       <a class="btn colour-primary waves-effect waves-light" href="{% url 'print_invoice' object.token %}">{% trans "Print" %}</a>
     {% endif %}
+    {% if can_send_invoice_email %}
+      <a class="btn colour-primary waves-effect waves-light" href="{% url 'send_invoice_by_token' object.token %}">{% trans "Send Email" %}</a>
+    {% endif %}
 
     <div class="row">
     {% if can_view_billing_information %}
diff --git a/aleksis/apps/tezor/urls.py b/aleksis/apps/tezor/urls.py
index 57b92ac76fc5e533d3f2e4ca8dd7a160a9e3a41f..2bd72955560338d91b87cd4af72f82feeaefb2ea 100644
--- a/aleksis/apps/tezor/urls.py
+++ b/aleksis/apps/tezor/urls.py
@@ -56,4 +56,9 @@ urlpatterns = [
         views.InvoiceDetailView.as_view(),
         name="invoice_by_token",
     ),
+    path(
+        "invoice/<str:token>/send/",
+        views.SendInvoiceEmail.as_view(),
+        name="send_invoice_by_token",
+    ),
 ]
diff --git a/aleksis/apps/tezor/views.py b/aleksis/apps/tezor/views.py
index 33b49a80feb15daf0e18fff683b7bae8f2c8b7f6..2b27b63e1b72145ed7c7f57a1f71a309f719af37 100644
--- a/aleksis/apps/tezor/views.py
+++ b/aleksis/apps/tezor/views.py
@@ -9,14 +9,18 @@ from django.views.generic.detail import DetailView
 from django_tables2.views import RequestConfig, SingleTableView
 from payments import PaymentStatus, RedirectNeeded, get_payment_model
 from rules.contrib.views import PermissionRequiredMixin
+from django_tables2.views import SingleTableView, RequestConfig
+from templated_email import InlineImage, send_templated_mail
 
 from aleksis.core.mixins import AdvancedCreateView, AdvancedDeleteView, AdvancedEditView
+from aleksis.core.util.pdf import generate_pdf_from_template
 from aleksis.core.views import RenderPDFView
 
 from .forms import EditClientForm, EditInvoiceGroupForm
 from .models.base import Client
 from .models.invoice import Invoice, InvoiceGroup
 from .tables import ClientsTable, InvoiceGroupsTable, InvoicesTable
+from .tasks import email_invoice
 
 
 class GetInvoicePDF(PermissionRequiredMixin, RenderPDFView):
@@ -29,7 +33,6 @@ class GetInvoicePDF(PermissionRequiredMixin, RenderPDFView):
         self.template_name = invoice.group.template_name
         context["invoice"] = invoice
 
-        print(invoice.group.__dict__)
         return context
 
 
@@ -189,3 +192,17 @@ class InvoiceDetailView(PermissionRequiredMixin, DetailView):
     slug_field = "token"
     permission_required = "tezor.view_invoice_rule"
     template_name = "tezor/invoice/full.html"
+
+
+class SendInvoiceEmail(PermissionRequiredMixin, View):
+
+    permission_required = "tezor.send_invoice_email_rule"
+
+    def get(self, request, token):
+        email_invoice.delay(token)
+
+        url = request.META.get("HTTP_REFERRER")
+        if not url:
+            url = Invoice.objects.get(token=token).get_absolute_url()
+
+        return redirect(url)