diff --git a/Changelog.md b/Changelog.md
index 3042de4b1a1e44397841e642d2a056b1df463a82..f0d2343624349deb3c8e8a882e0f1a5ce0ee3b8f 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,6 +2,12 @@
 
 All notable changes to this project will be documented in this file.
 
+## [0.16] - 2025-02-12
+- Exclude void invoices from possbile error report
+- Limit max invoice due date and set maximum date for allowing bank transfers
+
+...
+
 ## [0.9] - 2025-02-12
 - added repeated confirm click prevention
 - added emails sent out when a payment is received with no associated order
diff --git a/config-example.json b/config-example.json
index 962a994f513251c346de38828238ce0ef96f3a1a..43e4b0d6d57a79828be2a28a8ce5f5f71ceb59de 100644
--- a/config-example.json
+++ b/config-example.json
@@ -5,5 +5,7 @@
   "STRIPE_TAX_RATE_ID": "txr_1QeddlDSpyjzuj5pPwUcMwTd",
   "VISIT_API_KEY": "<visit api key>",
   "VISIT_EXPO_ID": "18lm2fafttito",
-  "SEND_ERROR_EMAILS_TO": []
+  "SEND_ERROR_EMAILS_TO": [],
+  "MAX_INVOICE_DUE_DATE": "2025-05-23",
+  "MAX_BANK_TRANSFER_ALLOWED_DATE": "2025-05-12"
 }
\ No newline at end of file
diff --git a/setup.py b/setup.py
index b99e69646a587d86bc5cebe4622432d11e6fd15f..42f1c8e39df35575aec35bfb5f9c8436c0802b53 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
 
 setup(
     name="stripe-checkout",
-    version="0.15",
+    version="0.16",
     author="GEANT",
     author_email="swd@geant.org",
     description="Stripe custom checkout support service",
diff --git a/stripe_checkout/stripe_checkout/compare_visit_stripe.py b/stripe_checkout/stripe_checkout/compare_visit_stripe.py
index a6a0648e00a4d8e526a6cc552ab2023721a557c0..41163bb82c49097f4252721c246d80ee5e80085d 100644
--- a/stripe_checkout/stripe_checkout/compare_visit_stripe.py
+++ b/stripe_checkout/stripe_checkout/compare_visit_stripe.py
@@ -43,6 +43,8 @@ class PossibleErrorReporter(CSVReporter):
                 yield obj
         unseen_invoices: dict[str, list[dict]] = {}
         for obj_id, obj in data["stripe"].items():
+            if obj["status"] in ("draft", "void"):
+                continue
             email = obj["customer_email"]
             if obj_id.startswith("in_") and email not in seen:
                 unseen_invoices.setdefault(email, []).append(obj)
@@ -105,6 +107,13 @@ reporter = PossibleErrorReporter([VISITOR_SERIALIZER], get_data=get_all_data)
 def main():
     import logging
     import pathlib
+    import stripe
+
+    from django.conf import settings
+    from stripe_checkout.config import load_config
+
+    load_config("config.json", settings=settings)
+    stripe.api_key = settings.STRIPE_API_KEY
 
     logger = logging.getLogger()
     logging.basicConfig(level=logging.INFO)
diff --git a/stripe_checkout/stripe_checkout/stripe_.py b/stripe_checkout/stripe_checkout/stripe_.py
index 4b96623059d16fcfd4b780fe4ac64021468dfccf..38163e355f0a66bbb2f5d588ae6b3cfaea5e7d1b 100644
--- a/stripe_checkout/stripe_checkout/stripe_.py
+++ b/stripe_checkout/stripe_checkout/stripe_.py
@@ -1,5 +1,6 @@
 from __future__ import annotations
 
+import datetime
 import functools
 import logging
 import time
@@ -72,6 +73,33 @@ def parse_address(visit_address: dict, organization: str):
     }
 
 
+def get_invoice_days_until_due(max_days=30):
+    max_invoice_due_date = getattr(settings, "MAX_INVOICE_DUE_DATE", None)
+    if not max_invoice_due_date:
+        return max_days
+    days_until_max_due_date = (
+        datetime.date.fromisoformat(max_invoice_due_date) - datetime.date.today()
+    ).days
+    return max(min(days_until_max_due_date, max_days), 0)
+
+
+def _is_bank_transfer_allowed():
+    max_bank_transfer_allowed_date = getattr(
+        settings, "MAX_BANK_TRANSFER_ALLOWED_DATE", None
+    )
+    if not max_bank_transfer_allowed_date:
+        return True
+    return datetime.date.today() <= datetime.date.fromisoformat(
+        max_bank_transfer_allowed_date
+    )
+
+
+def get_allowed_payment_methods():
+    if _is_bank_transfer_allowed():
+        return ["card", "customer_balance"]
+    return ["card"]
+
+
 def create_invoice(
     shopping_cart: ShoppingCart,
     customer_id,
@@ -98,8 +126,8 @@ def create_invoice(
     invoice = stripe.Invoice.create(
         customer=customer_id,
         collection_method="send_invoice",
-        payment_settings={"payment_method_types": ["card", "customer_balance"]},
-        days_until_due=30,
+        payment_settings={"payment_method_types": get_allowed_payment_methods()},
+        days_until_due=get_invoice_days_until_due(),
         custom_fields=custom_fields,
         rendering={"template": settings.STRIPE_INVOICE_TEMPLATE_ID},
         metadata=metadata,
diff --git a/test/test_stripe.py b/test/test_stripe.py
index ed91385a1a028b25374c9076cc53189b54b4e274..ac82543ff254d28e434d9c1495e201850bc5db1d 100644
--- a/test/test_stripe.py
+++ b/test/test_stripe.py
@@ -1,6 +1,11 @@
+import datetime
 import pytest
 import stripe
-from stripe_checkout.stripe_checkout.stripe_ import get_or_create_customer
+from stripe_checkout.stripe_checkout.stripe_ import (
+    get_allowed_payment_methods,
+    get_invoice_days_until_due,
+    get_or_create_customer,
+)
 
 
 @pytest.mark.parametrize(
@@ -95,3 +100,44 @@ def test_updates_visitor_with_address(default_visitor, mock_stripe):
     new_address = stripe.Customer.modify.call_args.kwargs["address"]
     non_empty = {key: val for key, val in new_address.items() if val}
     assert non_empty == {"country": "BE"}
+
+
+@pytest.mark.parametrize(
+    "max_due_date_in_days, expected_days_until_due",
+    [
+        (None, 30),
+        (31, 30),
+        (30, 30),
+        (29, 29),
+        (1, 1),
+        (0, 0),
+        (-1, 0),
+    ],
+)
+def test_invoice_due_date(max_due_date_in_days, expected_days_until_due, settings):
+    if max_due_date_in_days is not None:
+        max_due_date = datetime.date.today() + datetime.timedelta(
+            days=max_due_date_in_days
+        )
+        settings.MAX_INVOICE_DUE_DATE = max_due_date.isoformat()
+    assert get_invoice_days_until_due() == expected_days_until_due
+
+
+@pytest.mark.parametrize(
+    "days_until_max_bank_transfer_date, expected_payment_methods",
+    [
+        (None, ["card", "customer_balance"]),
+        (1, ["card", "customer_balance"]),
+        (0, ["card", "customer_balance"]),
+        (-1, ["card"]),
+    ],
+)
+def test_get_allowed_payment_methods(
+    days_until_max_bank_transfer_date, expected_payment_methods, settings
+):
+    if days_until_max_bank_transfer_date is not None:
+        max_bank_transfer_date = datetime.date.today() + datetime.timedelta(
+            days=days_until_max_bank_transfer_date
+        )
+        settings.MAX_BANK_TRANSFER_ALLOWED_DATE = max_bank_transfer_date.isoformat()
+    assert get_allowed_payment_methods() == expected_payment_methods