diff --git a/stripe_checkout/stripe_checkout/generate_report.py b/stripe_checkout/stripe_checkout/generate_report.py
index 15aae80b4be27c52ff1f28bd7729a83ee7782354..dd6dbd56e38a664f92f09a28bbd5fbc91f7d096d 100644
--- a/stripe_checkout/stripe_checkout/generate_report.py
+++ b/stripe_checkout/stripe_checkout/generate_report.py
@@ -131,7 +131,7 @@ class ReportField:
     path: str
     transform: Optional[Callable] = None
 
-    def get_value(self, reader: InvoiceWrapper):
+    def get_value(self, reader: StripeWrapper):
         value = getattr_or_none(reader, self.path.split("."))
         if value is not None and self.transform:
             value = self.transform(value)
diff --git a/stripe_checkout/stripe_checkout/visit.py b/stripe_checkout/stripe_checkout/visit.py
index 1832d2144755a20753c3c4246d39919b2348f604..5ba5f06e5f9cc52dffc6cafbf93c106b237932ab 100644
--- a/stripe_checkout/stripe_checkout/visit.py
+++ b/stripe_checkout/stripe_checkout/visit.py
@@ -1,5 +1,5 @@
 from __future__ import annotations
-from typing import Optional, Union
+from typing import Callable, Optional, Union
 from django.http import Http404
 import requests
 from requests.auth import HTTPBasicAuth
@@ -24,18 +24,45 @@ class VisitorAPI:
         response.raise_for_status()
         return response.json()
 
-    def list_visitors(self):
-        all_visitors = self._request(
+    def _request_visitors(self, from_revision=None):
+        params = {"showDeleted": "false"}
+        if from_revision is not None:
+            params["fromRevision"] = from_revision
+        return self._request(
             "get",
             f"{BASE_URL}/visitors/{self.expo_id}",
-            params={"showDeleted": "false"},
+            params=params,
         )
+
+    def list_visitors(self):
+        all_visitors = self._request_visitors()
         return [
             Visitor.from_api(data)
             for data in filter(lambda v: not v["deleted"], all_visitors)
         ]
 
-    def get_visitor(self, visitor_id: str):
+    def list_all_visitors(self, log_progress: Callable[[str]]):
+        last_revision = 0
+        next_revision = None
+        visitors_by_id = {}
+        while True:
+            response = self._request_visitors(from_revision=next_revision)
+            if log_progress is not None:
+                log_progress(f"Retrieved {len(response)} visitors")
+
+            next_revision = response[-1]["revision"]
+            for visitor in response:
+                visitors_by_id[visitor["id"]] = visitor
+
+            if next_revision == last_revision:
+                break
+            last_revision = next_revision
+        return [
+            Visitor.from_api(data)
+            for data in filter(lambda v: not v["deleted"], visitors_by_id.values())
+        ]
+
+    def get_visitor(self, visitor_id: str, allow_deleted=False):
         result = self._request(
             "get", f"{BASE_URL}/visitors/{self.expo_id}/{visitor_id}"
         )
@@ -45,7 +72,8 @@ class VisitorAPI:
         # properly raise
         if not isinstance(result, dict):
             raise Http404()
-
+        if result['deleted'] and not allow_deleted:
+            raise Http404()
         return Visitor.from_api(result)
 
     def update_visitor(
diff --git a/test/test_visit_client.py b/test/test_visit_client.py
index 1e00118e0e9aacb66fa8ab460841b348b8d3ac0b..88a0e9a91f623672b648542b4c5302424b8b6ba0 100644
--- a/test/test_visit_client.py
+++ b/test/test_visit_client.py
@@ -29,3 +29,21 @@ def test_special_fake_visitor_id_that_return_list(api):
     )
     with pytest.raises(Http404):
         api.get_visitor("fakevisitor")
+
+
+@responses.activate
+def test_raises_on_deleted_visitor(api):
+    responses.reset()
+    responses.add(
+        responses.GET,
+        re.compile(r"https://api.visitcloud.com/create/v2/visitors/[^/]+/[^/]+$"),
+        json={
+            "deleted": True,
+            "expo": {"id": "18lm2fafttito", "name": "TNC25", "reference": ""},
+            "id": "0keoqgpagjw9e",
+            "reference": "",
+            "revision": 11539734023,
+        },
+    )
+    with pytest.raises(Http404):
+        api.get_visitor("0keoqgpagjw9e")