diff --git a/.stats.yml b/.stats.yml
index 76e9cb43..284caebf 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1 +1 @@
-configured_endpoints: 40
+configured_endpoints: 52
diff --git a/api.md b/api.md
index 10d13cfe..c3afeb1d 100644
--- a/api.md
+++ b/api.md
@@ -122,6 +122,43 @@ Custom Methods:
- `get_embed_html`
- `get_embed_url`
+# Events
+
+Types:
+
+```python
+from lithic.types import Event, EventSubscription
+```
+
+Methods:
+
+- client.events.retrieve(event_token) -> Event
+- client.events.list(\*\*params) -> SyncCursorPage[Event]
+
+Custom Methods:
+
+- `resend`
+
+## Subscriptions
+
+Types:
+
+```python
+from lithic.types.events import SubscriptionRetrieveSecretResponse
+```
+
+Methods:
+
+- client.events.subscriptions.create(\*\*params) -> EventSubscription
+- client.events.subscriptions.retrieve(event_subscription_token) -> EventSubscription
+- client.events.subscriptions.update(event_subscription_token, \*\*params) -> EventSubscription
+- client.events.subscriptions.list(\*\*params) -> SyncCursorPage[EventSubscription]
+- client.events.subscriptions.delete(event_subscription_token) -> None
+- client.events.subscriptions.recover(event_subscription_token) -> None
+- client.events.subscriptions.replay_missing(event_subscription_token) -> None
+- client.events.subscriptions.retrieve_secret(event_subscription_token) -> SubscriptionRetrieveSecretResponse
+- client.events.subscriptions.rotate_secret(event_subscription_token) -> None
+
# FundingSources
Types:
diff --git a/src/lithic/_client.py b/src/lithic/_client.py
index f9904152..4041401f 100644
--- a/src/lithic/_client.py
+++ b/src/lithic/_client.py
@@ -54,6 +54,7 @@ class Lithic(SyncAPIClient):
auth_rules: resources.AuthRules
auth_stream_enrollment: resources.AuthStreamEnrollmentResource
cards: resources.Cards
+ events: resources.Events
funding_sources: resources.FundingSources
transactions: resources.Transactions
@@ -123,6 +124,7 @@ def __init__(
self.auth_rules = resources.AuthRules(self)
self.auth_stream_enrollment = resources.AuthStreamEnrollmentResource(self)
self.cards = resources.Cards(self)
+ self.events = resources.Events(self)
self.funding_sources = resources.FundingSources(self)
self.transactions = resources.Transactions(self)
@@ -209,6 +211,7 @@ class AsyncLithic(AsyncAPIClient):
auth_rules: resources.AsyncAuthRules
auth_stream_enrollment: resources.AsyncAuthStreamEnrollmentResource
cards: resources.AsyncCards
+ events: resources.AsyncEvents
funding_sources: resources.AsyncFundingSources
transactions: resources.AsyncTransactions
@@ -278,6 +281,7 @@ def __init__(
self.auth_rules = resources.AsyncAuthRules(self)
self.auth_stream_enrollment = resources.AsyncAuthStreamEnrollmentResource(self)
self.cards = resources.AsyncCards(self)
+ self.events = resources.AsyncEvents(self)
self.funding_sources = resources.AsyncFundingSources(self)
self.transactions = resources.AsyncTransactions(self)
diff --git a/src/lithic/pagination.py b/src/lithic/pagination.py
index 049d0ba5..0ce74e1f 100644
--- a/src/lithic/pagination.py
+++ b/src/lithic/pagination.py
@@ -1,16 +1,22 @@
# File generated from our OpenAPI spec by Stainless.
-from typing import List, Generic, TypeVar, Optional
+from typing import Any, List, Generic, TypeVar, Optional, cast
+from typing_extensions import Protocol, runtime_checkable
from ._types import ModelT
from ._models import BaseModel
from ._base_client import BasePage, PageInfo, BaseSyncPage, BaseAsyncPage
-__all__ = ["SyncPage", "AsyncPage"]
+__all__ = ["SyncPage", "AsyncPage", "SyncCursorPage", "AsyncCursorPage"]
_BaseModelT = TypeVar("_BaseModelT", bound=BaseModel)
+@runtime_checkable
+class CursorPageItem(Protocol):
+ token: str
+
+
class SyncPage(BaseSyncPage[ModelT], BasePage[ModelT], Generic[ModelT]):
data: List[ModelT]
page: int
@@ -41,3 +47,57 @@ def next_page_info(self) -> Optional[PageInfo]:
if not current_page < self.total_pages:
return None
return PageInfo(params={"page": current_page + 1})
+
+
+class SyncCursorPage(BaseSyncPage[ModelT], BasePage[ModelT], Generic[ModelT]):
+ data: List[ModelT]
+ has_more: bool
+
+ def _get_page_items(self) -> List[ModelT]:
+ return self.data
+
+ def next_page_info(self) -> Optional[PageInfo]:
+ is_forwards = not self._options.params.get("ending_before", False)
+
+ if len(self.data) > 0:
+ return None
+
+ if is_forwards:
+ item = cast(Any, self.data[-1])
+ if not isinstance(item, CursorPageItem):
+ # TODO emit warning log
+ return None
+ return PageInfo(params={"staring_after": item.token})
+ else:
+ item = cast(Any, self.data[0])
+ if not isinstance(item, CursorPageItem):
+ # TODO emit warning log
+ return None
+ return PageInfo(params={"ending_before": item.token})
+
+
+class AsyncCursorPage(BaseAsyncPage[ModelT], BasePage[ModelT], Generic[ModelT]):
+ data: List[ModelT]
+ has_more: bool
+
+ def _get_page_items(self) -> List[ModelT]:
+ return self.data
+
+ def next_page_info(self) -> Optional[PageInfo]:
+ is_forwards = not self._options.params.get("ending_before", False)
+
+ if len(self.data) > 0:
+ return None
+
+ if is_forwards:
+ item = cast(Any, self.data[-1])
+ if not isinstance(item, CursorPageItem):
+ # TODO emit warning log
+ return None
+ return PageInfo(params={"staring_after": item.token})
+ else:
+ item = cast(Any, self.data[0])
+ if not isinstance(item, CursorPageItem):
+ # TODO emit warning log
+ return None
+ return PageInfo(params={"ending_before": item.token})
diff --git a/src/lithic/resources/__init__.py b/src/lithic/resources/__init__.py
index 2517e4fd..f36b9849 100644
--- a/src/lithic/resources/__init__.py
+++ b/src/lithic/resources/__init__.py
@@ -1,6 +1,7 @@
# File generated from our OpenAPI spec by Stainless.
from .cards import Cards, AsyncCards
+from .events import Events, AsyncEvents
from .accounts import Accounts, AsyncAccounts
from .auth_rules import AuthRules, AsyncAuthRules
from .transactions import Transactions, AsyncTransactions
@@ -22,6 +23,8 @@
"AsyncAuthStreamEnrollmentResource",
"Cards",
"AsyncCards",
+ "Events",
+ "AsyncEvents",
"FundingSources",
"AsyncFundingSources",
"Transactions",
diff --git a/src/lithic/resources/auth_stream_enrollment.py b/src/lithic/resources/auth_stream_enrollment.py
index dfe3ac1f..25164169 100644
--- a/src/lithic/resources/auth_stream_enrollment.py
+++ b/src/lithic/resources/auth_stream_enrollment.py
@@ -40,7 +40,6 @@ def disenroll(
extra_body: Body | None = None,
) -> None:
"""Disenroll Authorization Stream Access (ASA) in Sandbox."""
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
"/auth_stream",
options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
@@ -80,7 +79,6 @@ def enroll(
extra_body: Add additional JSON properties to the request
"""
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._post(
"/auth_stream",
body={"webhook_url": webhook_url},
@@ -119,7 +117,6 @@ async def disenroll(
extra_body: Body | None = None,
) -> None:
"""Disenroll Authorization Stream Access (ASA) in Sandbox."""
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
"/auth_stream",
options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
@@ -159,7 +156,6 @@ async def enroll(
extra_body: Add additional JSON properties to the request
"""
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._post(
"/auth_stream",
body={"webhook_url": webhook_url},
diff --git a/src/lithic/resources/events/__init__.py b/src/lithic/resources/events/__init__.py
new file mode 100644
index 00000000..fb54a8e5
--- /dev/null
+++ b/src/lithic/resources/events/__init__.py
@@ -0,0 +1,6 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from .events import Events, AsyncEvents
+from .subscriptions import Subscriptions, AsyncSubscriptions
+
+__all__ = ["Subscriptions", "AsyncSubscriptions", "Events", "AsyncEvents"]
diff --git a/src/lithic/resources/events/events.py b/src/lithic/resources/events/events.py
new file mode 100644
index 00000000..0a2250d1
--- /dev/null
+++ b/src/lithic/resources/events/events.py
@@ -0,0 +1,218 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, List
+from typing_extensions import Literal
+
+from ...types import Event
+from ..._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ...pagination import SyncCursorPage, AsyncCursorPage
+from .subscriptions import Subscriptions, AsyncSubscriptions
+from ..._base_client import AsyncPaginator, make_request_options
+
+if TYPE_CHECKING:
+ from ..._client import Lithic, AsyncLithic
+
+__all__ = ["Events", "AsyncEvents"]
+
+
+class Events(SyncAPIResource):
+ subscriptions: Subscriptions
+
+ def __init__(self, client: Lithic) -> None:
+ super().__init__(client)
+ self.subscriptions = Subscriptions(client)
+
+ def retrieve(
+ self,
+ event_token: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> Event:
+ """Get an event."""
+ return self._get(
+ f"/events/{event_token}",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=Event,
+ )
+
+ def list(
+ self,
+ *,
+ begin: str | NotGiven = NOT_GIVEN,
+ end: str | NotGiven = NOT_GIVEN,
+ page_size: int | NotGiven = NOT_GIVEN,
+ starting_after: str | NotGiven = NOT_GIVEN,
+ ending_before: str | NotGiven = NOT_GIVEN,
+ event_types: List[Literal["dispute.updated", "digital_wallet.token_approval_request"]] | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> SyncCursorPage[Event]:
+ """List all events.
+
+ Args:
+ begin: Date string in 8601 format.
+
+ Only entries created after the specified date will
+ be included. UTC time zone.
+
+ end: Date string in 8601 format. Only entries created before the specified date will
+ be included. UTC time zone.
+
+ page_size: Page size (for pagination).
+
+ starting_after: The unique identifier of the last item in the previous page. Used to retrieve
+ the next page.
+
+ ending_before: The unique identifier of the first item in the previous page. Used to retrieve
+ the previous page.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+ """
+ return self._get_api_list(
+ "/events",
+ page=SyncCursorPage[Event],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ query={
+ "begin": begin,
+ "end": end,
+ "page_size": page_size,
+ "starting_after": starting_after,
+ "ending_before": ending_before,
+ "event_types": event_types,
+ },
+ ),
+ model=Event,
+ )
+
+ def resend(
+ self,
+ event_token: str,
+ *,
+ event_subscription_token: str,
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> None:
+ """Resend an event to an event subscription."""
+ self._post(
+ f"/events/{event_token}/event_subscriptions/{event_subscription_token}/resend",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=NoneType,
+ )
+
+
+class AsyncEvents(AsyncAPIResource):
+ subscriptions: AsyncSubscriptions
+
+ def __init__(self, client: AsyncLithic) -> None:
+ super().__init__(client)
+ self.subscriptions = AsyncSubscriptions(client)
+
+ async def retrieve(
+ self,
+ event_token: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> Event:
+ """Get an event."""
+ return await self._get(
+ f"/events/{event_token}",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=Event,
+ )
+
+ def list(
+ self,
+ *,
+ begin: str | NotGiven = NOT_GIVEN,
+ end: str | NotGiven = NOT_GIVEN,
+ page_size: int | NotGiven = NOT_GIVEN,
+ starting_after: str | NotGiven = NOT_GIVEN,
+ ending_before: str | NotGiven = NOT_GIVEN,
+ event_types: List[Literal["dispute.updated", "digital_wallet.token_approval_request"]] | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> AsyncPaginator[Event, AsyncCursorPage[Event]]:
+ """List all events.
+
+ Args:
+ begin: Date string in 8601 format.
+
+ Only entries created after the specified date will
+ be included. UTC time zone.
+
+ end: Date string in 8601 format. Only entries created before the specified date will
+ be included. UTC time zone.
+
+ page_size: Page size (for pagination).
+
+ starting_after: The unique identifier of the last item in the previous page. Used to retrieve
+ the next page.
+
+ ending_before: The unique identifier of the first item in the previous page. Used to retrieve
+ the previous page.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+ """
+ return self._get_api_list(
+ "/events",
+ page=AsyncCursorPage[Event],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ query={
+ "begin": begin,
+ "end": end,
+ "page_size": page_size,
+ "starting_after": starting_after,
+ "ending_before": ending_before,
+ "event_types": event_types,
+ },
+ ),
+ model=Event,
+ )
+
+ async def resend(
+ self,
+ event_token: str,
+ *,
+ event_subscription_token: str,
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> None:
+ """Resend an event to an event subscription."""
+ await self._post(
+ f"/events/{event_token}/event_subscriptions/{event_subscription_token}/resend",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=NoneType,
+ )
diff --git a/src/lithic/resources/events/subscriptions.py b/src/lithic/resources/events/subscriptions.py
new file mode 100644
index 00000000..c1e3ff44
--- /dev/null
+++ b/src/lithic/resources/events/subscriptions.py
@@ -0,0 +1,509 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import Literal
+
+from ...types import EventSubscription
+from ..._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ...pagination import SyncCursorPage, AsyncCursorPage
+from ..._base_client import AsyncPaginator, make_request_options
+from ...types.events import SubscriptionRetrieveSecretResponse
+
+__all__ = ["Subscriptions", "AsyncSubscriptions"]
+
+
+class Subscriptions(SyncAPIResource):
+ def create(
+ self,
+ *,
+ description: str | NotGiven = NOT_GIVEN,
+ disabled: bool | NotGiven = NOT_GIVEN,
+ event_types: List[Literal["dispute.updated", "digital_wallet.token_approval_request"]] | NotGiven = NOT_GIVEN,
+ url: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> EventSubscription:
+ """
+ Create a new event subscription.
+
+ Args:
+ description: Event subscription description.
+
+ disabled: Whether the event subscription is active (false) or inactive (true).
+
+ event_types: Indicates types of events that will be sent to this subscription. If left blank,
+ all types will be sent.
+
+ url: URL to which event webhooks will be sent. URL must be a valid HTTPS address.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+ """
+ return self._post(
+ "/event_subscriptions",
+ body={
+ "description": description,
+ "disabled": disabled,
+ "event_types": event_types,
+ "url": url,
+ },
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=EventSubscription,
+ )
+
+ def retrieve(
+ self,
+ event_subscription_token: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> EventSubscription:
+ """Get an event subscription."""
+ return self._get(
+ f"/event_subscriptions/{event_subscription_token}",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=EventSubscription,
+ )
+
+ def update(
+ self,
+ event_subscription_token: str,
+ *,
+ description: str | NotGiven = NOT_GIVEN,
+ disabled: bool | NotGiven = NOT_GIVEN,
+ event_types: List[Literal["dispute.updated", "digital_wallet.token_approval_request"]] | NotGiven = NOT_GIVEN,
+ url: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> EventSubscription:
+ """
+ Update an event subscription.
+
+ Args:
+ description: Event subscription description.
+
+ disabled: Whether the event subscription is active (false) or inactive (true).
+
+ event_types: Indicates types of events that will be sent to this subscription. If left blank,
+ all types will be sent.
+
+ url: URL to which event webhooks will be sent. URL must be a valid HTTPS address.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+ """
+ return self._patch(
+ f"/event_subscriptions/{event_subscription_token}",
+ body={
+ "description": description,
+ "disabled": disabled,
+ "event_types": event_types,
+ "url": url,
+ },
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=EventSubscription,
+ )
+
+ def list(
+ self,
+ *,
+ page_size: int | NotGiven = NOT_GIVEN,
+ starting_after: str | NotGiven = NOT_GIVEN,
+ ending_before: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> SyncCursorPage[EventSubscription]:
+ """
+ List all the event subscriptions.
+
+ Args:
+ page_size: Page size (for pagination).
+
+ starting_after: The unique identifier of the last item in the previous page. Used to retrieve
+ the next page.
+
+ ending_before: The unique identifier of the first item in the previous page. Used to retrieve
+ the previous page.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+ """
+ return self._get_api_list(
+ "/event_subscriptions",
+ page=SyncCursorPage[EventSubscription],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ query={
+ "page_size": page_size,
+ "starting_after": starting_after,
+ "ending_before": ending_before,
+ },
+ ),
+ model=EventSubscription,
+ )
+
+ def delete(
+ self,
+ event_subscription_token: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> None:
+ """Delete an event subscription."""
+ return self._delete(
+ f"/event_subscriptions/{event_subscription_token}",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=NoneType,
+ )
+
+ def recover(
+ self,
+ event_subscription_token: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> None:
+ """Resend all failed messages since a given time."""
+ return self._post(
+ f"/event_subscriptions/{event_subscription_token}/recover",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=NoneType,
+ )
+
+ def replay_missing(
+ self,
+ event_subscription_token: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> None:
+ """Replays messages to the endpoint.
+
+ Only messages that were created after `begin`
+ will be sent. Messages that were previously sent to the endpoint are not resent.
+ """
+ return self._post(
+ f"/event_subscriptions/{event_subscription_token}/replay_missing",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=NoneType,
+ )
+
+ def retrieve_secret(
+ self,
+ event_subscription_token: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> SubscriptionRetrieveSecretResponse:
+ """Get the secret for an event subscription."""
+ return self._get(
+ f"/event_subscriptions/{event_subscription_token}/secret",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=SubscriptionRetrieveSecretResponse,
+ )
+
+ def rotate_secret(
+ self,
+ event_subscription_token: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> None:
+ """Rotate the secret for an event subscription.
+
+ The previous secret will be valid
+ for the next 24 hours.
+ """
+ return self._post(
+ f"/event_subscriptions/{event_subscription_token}/secret/rotate",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=NoneType,
+ )
+
+
+class AsyncSubscriptions(AsyncAPIResource):
+ async def create(
+ self,
+ *,
+ description: str | NotGiven = NOT_GIVEN,
+ disabled: bool | NotGiven = NOT_GIVEN,
+ event_types: List[Literal["dispute.updated", "digital_wallet.token_approval_request"]] | NotGiven = NOT_GIVEN,
+ url: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> EventSubscription:
+ """
+ Create a new event subscription.
+
+ Args:
+ description: Event subscription description.
+
+ disabled: Whether the event subscription is active (false) or inactive (true).
+
+ event_types: Indicates types of events that will be sent to this subscription. If left blank,
+ all types will be sent.
+
+ url: URL to which event webhooks will be sent. URL must be a valid HTTPS address.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+ """
+ return await self._post(
+ "/event_subscriptions",
+ body={
+ "description": description,
+ "disabled": disabled,
+ "event_types": event_types,
+ "url": url,
+ },
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=EventSubscription,
+ )
+
+ async def retrieve(
+ self,
+ event_subscription_token: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> EventSubscription:
+ """Get an event subscription."""
+ return await self._get(
+ f"/event_subscriptions/{event_subscription_token}",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=EventSubscription,
+ )
+
+ async def update(
+ self,
+ event_subscription_token: str,
+ *,
+ description: str | NotGiven = NOT_GIVEN,
+ disabled: bool | NotGiven = NOT_GIVEN,
+ event_types: List[Literal["dispute.updated", "digital_wallet.token_approval_request"]] | NotGiven = NOT_GIVEN,
+ url: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> EventSubscription:
+ """
+ Update an event subscription.
+
+ Args:
+ description: Event subscription description.
+
+ disabled: Whether the event subscription is active (false) or inactive (true).
+
+ event_types: Indicates types of events that will be sent to this subscription. If left blank,
+ all types will be sent.
+
+ url: URL to which event webhooks will be sent. URL must be a valid HTTPS address.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+ """
+ return await self._patch(
+ f"/event_subscriptions/{event_subscription_token}",
+ body={
+ "description": description,
+ "disabled": disabled,
+ "event_types": event_types,
+ "url": url,
+ },
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=EventSubscription,
+ )
+
+ def list(
+ self,
+ *,
+ page_size: int | NotGiven = NOT_GIVEN,
+ starting_after: str | NotGiven = NOT_GIVEN,
+ ending_before: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> AsyncPaginator[EventSubscription, AsyncCursorPage[EventSubscription]]:
+ """
+ List all the event subscriptions.
+
+ Args:
+ page_size: Page size (for pagination).
+
+ starting_after: The unique identifier of the last item in the previous page. Used to retrieve
+ the next page.
+
+ ending_before: The unique identifier of the first item in the previous page. Used to retrieve
+ the previous page.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+ """
+ return self._get_api_list(
+ "/event_subscriptions",
+ page=AsyncCursorPage[EventSubscription],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ query={
+ "page_size": page_size,
+ "starting_after": starting_after,
+ "ending_before": ending_before,
+ },
+ ),
+ model=EventSubscription,
+ )
+
+ async def delete(
+ self,
+ event_subscription_token: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> None:
+ """Delete an event subscription."""
+ return await self._delete(
+ f"/event_subscriptions/{event_subscription_token}",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=NoneType,
+ )
+
+ async def recover(
+ self,
+ event_subscription_token: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> None:
+ """Resend all failed messages since a given time."""
+ return await self._post(
+ f"/event_subscriptions/{event_subscription_token}/recover",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=NoneType,
+ )
+
+ async def replay_missing(
+ self,
+ event_subscription_token: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> None:
+ """Replays messages to the endpoint.
+
+ Only messages that were created after `begin`
+ will be sent. Messages that were previously sent to the endpoint are not resent.
+ """
+ return await self._post(
+ f"/event_subscriptions/{event_subscription_token}/replay_missing",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=NoneType,
+ )
+
+ async def retrieve_secret(
+ self,
+ event_subscription_token: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> SubscriptionRetrieveSecretResponse:
+ """Get the secret for an event subscription."""
+ return await self._get(
+ f"/event_subscriptions/{event_subscription_token}/secret",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=SubscriptionRetrieveSecretResponse,
+ )
+
+ async def rotate_secret(
+ self,
+ event_subscription_token: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ ) -> None:
+ """Rotate the secret for an event subscription.
+
+ The previous secret will be valid
+ for the next 24 hours.
+ """
+ return await self._post(
+ f"/event_subscriptions/{event_subscription_token}/secret/rotate",
+ options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
+ cast_to=NoneType,
+ )
diff --git a/src/lithic/resources/transactions.py b/src/lithic/resources/transactions.py
index 825901fd..3bba5ae4 100644
--- a/src/lithic/resources/transactions.py
+++ b/src/lithic/resources/transactions.py
@@ -32,14 +32,7 @@ def retrieve(
extra_query: Query | None = None,
extra_body: Body | None = None,
) -> Transaction:
- """
- Get specific transaction.
-
- _Note that the transaction object returned via this endpoint will be changing in
- Sandbox on January 4, 2023 and in Production on February 8, 2023. Please refer
- to [this page](https://docs.lithic.com/docs/guide-to-q1-2023-lithic-api-changes)
- for more information._
- """
+ """Get specific transaction."""
return self._get(
f"/transactions/{transaction_token}",
options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
@@ -65,11 +58,6 @@ def list(
"""
List transactions.
- _Note that the transaction object returned via this endpoint will be changing in
- Sandbox on January 4, 2023 and in Production on February 8, 2023. Please refer
- to [this page](https://docs.lithic.com/docs/guide-to-q1-2023-lithic-api-changes)
- for more information._
-
Args:
account_token: Filters for transactions associated with a specific account.
@@ -356,8 +344,7 @@ def simulate_return_reversal(
"""
Voids a settled credit transaction – i.e., a transaction with a negative amount
and `SETTLED` status. These can be credit authorizations that have already
- cleared or financial credit authorizations. This endpoint will be available
- beginning January 4, 2023.
+ cleared or financial credit authorizations.
Args:
token: The transaction token returned from the /v1/simulate/authorize response.
@@ -436,14 +423,7 @@ async def retrieve(
extra_query: Query | None = None,
extra_body: Body | None = None,
) -> Transaction:
- """
- Get specific transaction.
-
- _Note that the transaction object returned via this endpoint will be changing in
- Sandbox on January 4, 2023 and in Production on February 8, 2023. Please refer
- to [this page](https://docs.lithic.com/docs/guide-to-q1-2023-lithic-api-changes)
- for more information._
- """
+ """Get specific transaction."""
return await self._get(
f"/transactions/{transaction_token}",
options=make_request_options(extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body),
@@ -469,11 +449,6 @@ def list(
"""
List transactions.
- _Note that the transaction object returned via this endpoint will be changing in
- Sandbox on January 4, 2023 and in Production on February 8, 2023. Please refer
- to [this page](https://docs.lithic.com/docs/guide-to-q1-2023-lithic-api-changes)
- for more information._
-
Args:
account_token: Filters for transactions associated with a specific account.
@@ -760,8 +735,7 @@ async def simulate_return_reversal(
"""
Voids a settled credit transaction – i.e., a transaction with a negative amount
and `SETTLED` status. These can be credit authorizations that have already
- cleared or financial credit authorizations. This endpoint will be available
- beginning January 4, 2023.
+ cleared or financial credit authorizations.
Args:
token: The transaction token returned from the /v1/simulate/authorize response.
diff --git a/src/lithic/types/__init__.py b/src/lithic/types/__init__.py
index 018b2894..0ebd962d 100644
--- a/src/lithic/types/__init__.py
+++ b/src/lithic/types/__init__.py
@@ -3,6 +3,7 @@
from __future__ import annotations
from .card import Card as Card
+from .event import Event as Event
from .shared import Address as Address
from .shared import ShippingAddress as ShippingAddress
from .account import Account as Account
@@ -13,11 +14,14 @@
from .funding_source import FundingSource as FundingSource
from .card_list_params import CardListParams as CardListParams
from .card_embed_params import CardEmbedParams as CardEmbedParams
+from .event_list_params import EventListParams as EventListParams
from .card_create_params import CardCreateParams as CardCreateParams
from .card_update_params import CardUpdateParams as CardUpdateParams
+from .event_subscription import EventSubscription as EventSubscription
from .account_list_params import AccountListParams as AccountListParams
from .card_embed_response import CardEmbedResponse as CardEmbedResponse
from .card_reissue_params import CardReissueParams as CardReissueParams
+from .event_resend_params import EventResendParams as EventResendParams
from .card_retrieve_params import CardRetrieveParams as CardRetrieveParams
from .embed_request_params import EmbedRequestParams as EmbedRequestParams
from .spend_limit_duration import SpendLimitDuration as SpendLimitDuration
diff --git a/src/lithic/types/event.py b/src/lithic/types/event.py
new file mode 100644
index 00000000..a871504b
--- /dev/null
+++ b/src/lithic/types/event.py
@@ -0,0 +1,28 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["Event"]
+
+
+class Event(BaseModel):
+ created: str
+ """An ISO 8601 timestamp for when the event was created. UTC time zone.
+
+ If no timezone is specified, UTC will be used.
+ """
+
+ event_type: Literal["dispute.updated", "digital_wallet.token_approval_request"]
+ """Event types:
+
+ - `dispute.updated` - A dispute has been updated.
+ - `digital_wallet.token_approval_request` - Card network's request to Lithic to
+ activate a digital wallet token.
+ """
+
+ payload: object
+
+ token: str
+ """Globally unique identifier."""
diff --git a/src/lithic/types/event_list_params.py b/src/lithic/types/event_list_params.py
new file mode 100644
index 00000000..f22a8924
--- /dev/null
+++ b/src/lithic/types/event_list_params.py
@@ -0,0 +1,39 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import Literal, TypedDict
+
+__all__ = ["EventListParams"]
+
+
+class EventListParams(TypedDict, total=False):
+ begin: str
+ """Date string in 8601 format.
+
+ Only entries created after the specified date will be included. UTC time zone.
+ """
+
+ end: str
+ """Date string in 8601 format.
+
+ Only entries created before the specified date will be included. UTC time zone.
+ """
+
+ ending_before: str
+ """The unique identifier of the first item in the previous page.
+
+ Used to retrieve the previous page.
+ """
+
+ event_types: List[Literal["dispute.updated", "digital_wallet.token_approval_request"]]
+
+ page_size: int
+ """Page size (for pagination)."""
+
+ starting_after: str
+ """The unique identifier of the last item in the previous page.
+
+ Used to retrieve the next page.
+ """
diff --git a/src/lithic/types/event_resend_params.py b/src/lithic/types/event_resend_params.py
new file mode 100644
index 00000000..0cc02fae
--- /dev/null
+++ b/src/lithic/types/event_resend_params.py
@@ -0,0 +1,40 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["EventResendParams"]
+
+
+class EventResendParams(TypedDict, total=False):
+ token: Required[str]
+ """Globally unique identifier for the card to be displayed."""
+
+ account_token: str
+ """Only needs to be included if one or more end-users have been enrolled."""
+
+ css: str
+ """
+ A publicly available URI, so the white-labeled card element can be styled with
+ the client's branding.
+ """
+
+ expiration: str
+ """An ISO 8601 timestamp for when the request should expire. UTC time zone.
+
+ If no timezone is specified, UTC will be used. If payload does not contain an
+ expiration, the request will never expire.
+
+ Using an `expiration` reduces the risk of a
+ [replay attack](https://en.wikipedia.org/wiki/Replay_attack). Without supplying
+ the `expiration`, in the event that a malicious user gets a copy of your request
+ in transit, they will be able to obtain the response data indefinitely.
+ """
+
+ target_origin: str
+ """Required if you want to post the element clicked to the parent iframe.
+
+ If you supply this param, you can also capture click events in the parent iframe
+ by adding an event listener.
+ """
diff --git a/src/lithic/types/event_subscription.py b/src/lithic/types/event_subscription.py
new file mode 100644
index 00000000..ba2e269c
--- /dev/null
+++ b/src/lithic/types/event_subscription.py
@@ -0,0 +1,23 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from typing import List, Optional
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["EventSubscription"]
+
+
+class EventSubscription(BaseModel):
+ description: str
+ """A description of the subscription."""
+
+ disabled: bool
+ """Whether the subscription is disabled."""
+
+ event_types: Optional[List[Literal["dispute.updated", "digital_wallet.token_approval_request"]]]
+
+ token: str
+ """Globally unique identifier."""
+
+ url: str
diff --git a/src/lithic/types/events/__init__.py b/src/lithic/types/events/__init__.py
new file mode 100644
index 00000000..32da7ea3
--- /dev/null
+++ b/src/lithic/types/events/__init__.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from .subscription_list_params import SubscriptionListParams as SubscriptionListParams
+from .subscription_create_params import (
+ SubscriptionCreateParams as SubscriptionCreateParams,
+)
+from .subscription_update_params import (
+ SubscriptionUpdateParams as SubscriptionUpdateParams,
+)
+from .subscription_retrieve_secret_response import (
+ SubscriptionRetrieveSecretResponse as SubscriptionRetrieveSecretResponse,
+)
diff --git a/src/lithic/types/events/subscription_create_params.py b/src/lithic/types/events/subscription_create_params.py
new file mode 100644
index 00000000..869f73db
--- /dev/null
+++ b/src/lithic/types/events/subscription_create_params.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["SubscriptionCreateParams"]
+
+
+class SubscriptionCreateParams(TypedDict, total=False):
+ url: Required[str]
+ """URL to which event webhooks will be sent. URL must be a valid HTTPS address."""
+
+ description: str
+ """Event subscription description."""
+
+ disabled: bool
+ """Whether the event subscription is active (false) or inactive (true)."""
+
+ event_types: List[Literal["dispute.updated", "digital_wallet.token_approval_request"]]
+ """Indicates types of events that will be sent to this subscription.
+
+ If left blank, all types will be sent.
+ """
diff --git a/src/lithic/types/events/subscription_list_params.py b/src/lithic/types/events/subscription_list_params.py
new file mode 100644
index 00000000..4b11e86d
--- /dev/null
+++ b/src/lithic/types/events/subscription_list_params.py
@@ -0,0 +1,24 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["SubscriptionListParams"]
+
+
+class SubscriptionListParams(TypedDict, total=False):
+ ending_before: str
+ """The unique identifier of the first item in the previous page.
+
+ Used to retrieve the previous page.
+ """
+
+ page_size: int
+ """Page size (for pagination)."""
+
+ starting_after: str
+ """The unique identifier of the last item in the previous page.
+
+ Used to retrieve the next page.
+ """
diff --git a/src/lithic/types/events/subscription_retrieve_secret_response.py b/src/lithic/types/events/subscription_retrieve_secret_response.py
new file mode 100644
index 00000000..c8dbc19f
--- /dev/null
+++ b/src/lithic/types/events/subscription_retrieve_secret_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from typing import Optional
+
+from ..._models import BaseModel
+
+__all__ = ["SubscriptionRetrieveSecretResponse"]
+
+
+class SubscriptionRetrieveSecretResponse(BaseModel):
+ key: Optional[str]
diff --git a/src/lithic/types/events/subscription_update_params.py b/src/lithic/types/events/subscription_update_params.py
new file mode 100644
index 00000000..6e90fef6
--- /dev/null
+++ b/src/lithic/types/events/subscription_update_params.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import Literal, TypedDict
+
+__all__ = ["SubscriptionUpdateParams"]
+
+
+class SubscriptionUpdateParams(TypedDict, total=False):
+ description: str
+ """Event subscription description."""
+
+ disabled: bool
+ """Whether the event subscription is active (false) or inactive (true)."""
+
+ event_types: List[Literal["dispute.updated", "digital_wallet.token_approval_request"]]
+ """Indicates types of events that will be sent to this subscription.
+
+ If left blank, all types will be sent.
+ """
+
+ url: str
+ """URL to which event webhooks will be sent. URL must be a valid HTTPS address."""
diff --git a/src/lithic/types/transaction.py b/src/lithic/types/transaction.py
index 76aca1f5..4afaefa4 100644
--- a/src/lithic/types/transaction.py
+++ b/src/lithic/types/transaction.py
@@ -5,10 +5,9 @@
from pydantic import Field
-from ..types import card
from .._models import BaseModel
-__all__ = ["Transaction", "CardholderAuthentication", "Event", "Funding", "Merchant"]
+__all__ = ["Transaction", "CardholderAuthentication", "Event", "Merchant"]
class CardholderAuthentication(BaseModel):
@@ -218,25 +217,6 @@ class Event(BaseModel):
- `RETURN` - A refund has been processed on the transaction.
- `RETURN_REVERSAL` - A refund has been reversed (e.g., when a merchant reverses
an incorrect refund).
- - `VOID` - Note this value will be removed with the February API changes (see
- https://docs.lithic.com/docs/guide-to-q1-2023-lithic-api-changes). A
- transaction has been voided (e.g., when a merchant reverses an incorrect
- authorization).
- """
-
-
-class Funding(BaseModel):
- amount: Optional[int]
- """Amount of the transaction event, including any acquirer fees."""
-
- token: Optional[str]
- """Funding account token."""
-
- type: Optional[Literal["DEPOSITORY_CHECKING", "DEPOSITORY_SAVINGS"]]
- """Types of funding:
-
- - `DEPOSITORY_CHECKING` - Bank checking account.
- - `DEPOSITORY_SAVINGS` - Bank savings account.
"""
@@ -292,20 +272,8 @@ class Transaction(BaseModel):
transaction with networks.
"""
- card: Optional[card.Card]
- """
- Note this field will be removed with the
- [February API changes](https://docs.lithic.com/docs/guide-to-q1-2023-lithic-api-changes).
- Card used in this transaction.
- """
-
card_token: Optional[str]
- """Token for the card used in this transaction. Note this field is not yet
- included.
-
- It will be added as part of the
- [February API changes](https://docs.lithic.com/docs/guide-to-q1-2023-lithic-api-changes).
- """
+ """Token for the card used in this transaction."""
cardholder_authentication: Optional[CardholderAuthentication]
@@ -315,16 +283,6 @@ class Transaction(BaseModel):
events: Optional[List[Event]]
"""A list of all events that have modified this transaction."""
- funding: Optional[List[Funding]]
- """
- Note this field will be removed with the
- [February API changes](https://docs.lithic.com/docs/guide-to-q1-2023-lithic-api-changes).
- A list of objects that describe how this transaction was funded, with the
- `amount` represented in cents. A reference to the funding account for the `card`
- that made this transaction may appear here and the `token` will match the
- `token` for the funding account in the `card` field.
- """
-
merchant: Optional[Merchant]
merchant_amount: Optional[int]
@@ -386,17 +344,11 @@ class Transaction(BaseModel):
status: Optional[Literal["BOUNCED", "DECLINED", "EXPIRED", "PENDING", "SETTLED", "SETTLING", "VOIDED"]]
"""Status types:
- - `BOUNCED` - The transaction was bounced. Note this value will be removed with
- the
- [February API changes](https://docs.lithic.com/docs/guide-to-q1-2023-lithic-api-changes).
- `DECLINED` - The transaction was declined.
- `EXPIRED` - Lithic reversed the authorization as it has passed its expiration
time.
- `PENDING` - Authorization is pending completion from the merchant.
- `SETTLED` - The transaction is complete.
- - `SETTLING` - The merchant has completed the transaction and the funding source
- is being debited. Note this value will be removed with the
- [February API changes](https://docs.lithic.com/docs/guide-to-q1-2023-lithic-api-changes).
- `VOIDED` - The merchant has voided the previously pending authorization.
"""
diff --git a/tests/api_resources/events/__init__.py b/tests/api_resources/events/__init__.py
new file mode 100644
index 00000000..1016754e
--- /dev/null
+++ b/tests/api_resources/events/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless.
diff --git a/tests/api_resources/events/test_subscriptions.py b/tests/api_resources/events/test_subscriptions.py
new file mode 100644
index 00000000..58da9275
--- /dev/null
+++ b/tests/api_resources/events/test_subscriptions.py
@@ -0,0 +1,217 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+import os
+
+import pytest
+
+from lithic import Lithic, AsyncLithic
+from lithic.types import EventSubscription
+from lithic.pagination import SyncCursorPage, AsyncCursorPage
+from lithic.types.events import SubscriptionRetrieveSecretResponse
+
+base_url = os.environ.get("API_BASE_URL", "http://127.0.0.1:4010")
+api_key = os.environ.get("API_KEY", "something1234")
+
+
+class TestSubscriptions:
+ strict_client = Lithic(base_url=base_url, api_key=api_key, _strict_response_validation=True)
+ loose_client = Lithic(base_url=base_url, api_key=api_key, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ def test_method_create(self, client: Lithic) -> None:
+ resource = client.events.subscriptions.create(
+ url="https://example.com",
+ )
+ assert isinstance(resource, EventSubscription)
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Lithic) -> None:
+ resource = client.events.subscriptions.create(
+ description="string",
+ disabled=True,
+ event_types=["dispute.updated", "dispute.updated", "dispute.updated"],
+ url="https://example.com",
+ )
+ assert isinstance(resource, EventSubscription)
+
+ @parametrize
+ def test_method_retrieve(self, client: Lithic) -> None:
+ resource = client.events.subscriptions.retrieve(
+ "string",
+ )
+ assert isinstance(resource, EventSubscription)
+
+ @parametrize
+ def test_method_update(self, client: Lithic) -> None:
+ resource = client.events.subscriptions.update(
+ "string",
+ )
+ assert isinstance(resource, EventSubscription)
+
+ @parametrize
+ def test_method_update_with_all_params(self, client: Lithic) -> None:
+ resource = client.events.subscriptions.update(
+ "string",
+ description="string",
+ disabled=True,
+ event_types=["dispute.updated", "dispute.updated", "dispute.updated"],
+ url="https://example.com",
+ )
+ assert isinstance(resource, EventSubscription)
+
+ @parametrize
+ def test_method_list(self, client: Lithic) -> None:
+ resource = client.events.subscriptions.list()
+ assert isinstance(resource, SyncCursorPage)
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Lithic) -> None:
+ resource = client.events.subscriptions.list(
+ page_size=1,
+ starting_after="string",
+ ending_before="string",
+ )
+ assert isinstance(resource, SyncCursorPage)
+
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
+ @parametrize
+ def test_method_delete(self, client: Lithic) -> None:
+ resource = client.events.subscriptions.delete(
+ "string",
+ )
+ assert resource is None
+
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
+ @parametrize
+ def test_method_recover(self, client: Lithic) -> None:
+ resource = client.events.subscriptions.recover(
+ "string",
+ )
+ assert resource is None
+
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
+ @parametrize
+ def test_method_replay_missing(self, client: Lithic) -> None:
+ resource = client.events.subscriptions.replay_missing(
+ "string",
+ )
+ assert resource is None
+
+ @parametrize
+ def test_method_retrieve_secret(self, client: Lithic) -> None:
+ resource = client.events.subscriptions.retrieve_secret(
+ "string",
+ )
+ assert isinstance(resource, SubscriptionRetrieveSecretResponse)
+
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
+ @parametrize
+ def test_method_rotate_secret(self, client: Lithic) -> None:
+ resource = client.events.subscriptions.rotate_secret(
+ "string",
+ )
+ assert resource is None
+
+
+class TestAsyncSubscriptions:
+ strict_client = AsyncLithic(base_url=base_url, api_key=api_key, _strict_response_validation=True)
+ loose_client = AsyncLithic(base_url=base_url, api_key=api_key, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ async def test_method_create(self, client: AsyncLithic) -> None:
+ resource = await client.events.subscriptions.create(
+ url="https://example.com",
+ )
+ assert isinstance(resource, EventSubscription)
+
+ @parametrize
+ async def test_method_create_with_all_params(self, client: AsyncLithic) -> None:
+ resource = await client.events.subscriptions.create(
+ description="string",
+ disabled=True,
+ event_types=["dispute.updated", "dispute.updated", "dispute.updated"],
+ url="https://example.com",
+ )
+ assert isinstance(resource, EventSubscription)
+
+ @parametrize
+ async def test_method_retrieve(self, client: AsyncLithic) -> None:
+ resource = await client.events.subscriptions.retrieve(
+ "string",
+ )
+ assert isinstance(resource, EventSubscription)
+
+ @parametrize
+ async def test_method_update(self, client: AsyncLithic) -> None:
+ resource = await client.events.subscriptions.update(
+ "string",
+ )
+ assert isinstance(resource, EventSubscription)
+
+ @parametrize
+ async def test_method_update_with_all_params(self, client: AsyncLithic) -> None:
+ resource = await client.events.subscriptions.update(
+ "string",
+ description="string",
+ disabled=True,
+ event_types=["dispute.updated", "dispute.updated", "dispute.updated"],
+ url="https://example.com",
+ )
+ assert isinstance(resource, EventSubscription)
+
+ @parametrize
+ async def test_method_list(self, client: AsyncLithic) -> None:
+ resource = await client.events.subscriptions.list()
+ assert isinstance(resource, AsyncCursorPage)
+
+ @parametrize
+ async def test_method_list_with_all_params(self, client: AsyncLithic) -> None:
+ resource = await client.events.subscriptions.list(
+ page_size=1,
+ starting_after="string",
+ ending_before="string",
+ )
+ assert isinstance(resource, AsyncCursorPage)
+
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
+ @parametrize
+ async def test_method_delete(self, client: AsyncLithic) -> None:
+ resource = await client.events.subscriptions.delete(
+ "string",
+ )
+ assert resource is None
+
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
+ @parametrize
+ async def test_method_recover(self, client: AsyncLithic) -> None:
+ resource = await client.events.subscriptions.recover(
+ "string",
+ )
+ assert resource is None
+
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
+ @parametrize
+ async def test_method_replay_missing(self, client: AsyncLithic) -> None:
+ resource = await client.events.subscriptions.replay_missing(
+ "string",
+ )
+ assert resource is None
+
+ @parametrize
+ async def test_method_retrieve_secret(self, client: AsyncLithic) -> None:
+ resource = await client.events.subscriptions.retrieve_secret(
+ "string",
+ )
+ assert isinstance(resource, SubscriptionRetrieveSecretResponse)
+
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
+ @parametrize
+ async def test_method_rotate_secret(self, client: AsyncLithic) -> None:
+ resource = await client.events.subscriptions.rotate_secret(
+ "string",
+ )
+ assert resource is None
diff --git a/tests/api_resources/test_auth_stream_enrollment.py b/tests/api_resources/test_auth_stream_enrollment.py
index 3567a451..b1214629 100644
--- a/tests/api_resources/test_auth_stream_enrollment.py
+++ b/tests/api_resources/test_auth_stream_enrollment.py
@@ -23,22 +23,19 @@ def test_method_retrieve(self, client: Lithic) -> None:
resource = client.auth_stream_enrollment.retrieve()
assert isinstance(resource, AuthStreamEnrollment)
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
@parametrize
def test_method_disenroll(self, client: Lithic) -> None:
resource = client.auth_stream_enrollment.disenroll()
assert resource is None
- @pytest.mark.skip(
- reason="currently no good way to test endpoints defining callbacks, Prism mock server will fail trying to reach the provided callback url"
- )
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
@parametrize
def test_method_enroll(self, client: Lithic) -> None:
resource = client.auth_stream_enrollment.enroll()
assert resource is None
- @pytest.mark.skip(
- reason="currently no good way to test endpoints defining callbacks, Prism mock server will fail trying to reach the provided callback url"
- )
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
@parametrize
def test_method_enroll_with_all_params(self, client: Lithic) -> None:
resource = client.auth_stream_enrollment.enroll(
@@ -57,22 +54,19 @@ async def test_method_retrieve(self, client: AsyncLithic) -> None:
resource = await client.auth_stream_enrollment.retrieve()
assert isinstance(resource, AuthStreamEnrollment)
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
@parametrize
async def test_method_disenroll(self, client: AsyncLithic) -> None:
resource = await client.auth_stream_enrollment.disenroll()
assert resource is None
- @pytest.mark.skip(
- reason="currently no good way to test endpoints defining callbacks, Prism mock server will fail trying to reach the provided callback url"
- )
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
@parametrize
async def test_method_enroll(self, client: AsyncLithic) -> None:
resource = await client.auth_stream_enrollment.enroll()
assert resource is None
- @pytest.mark.skip(
- reason="currently no good way to test endpoints defining callbacks, Prism mock server will fail trying to reach the provided callback url"
- )
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
@parametrize
async def test_method_enroll_with_all_params(self, client: AsyncLithic) -> None:
resource = await client.auth_stream_enrollment.enroll(
diff --git a/tests/api_resources/test_events.py b/tests/api_resources/test_events.py
new file mode 100644
index 00000000..9d05c5bd
--- /dev/null
+++ b/tests/api_resources/test_events.py
@@ -0,0 +1,88 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+import os
+
+import pytest
+
+from lithic import Lithic, AsyncLithic
+from lithic.types import Event
+from lithic.pagination import SyncCursorPage, AsyncCursorPage
+
+base_url = os.environ.get("API_BASE_URL", "http://127.0.0.1:4010")
+api_key = os.environ.get("API_KEY", "something1234")
+
+
+class TestEvents:
+ strict_client = Lithic(base_url=base_url, api_key=api_key, _strict_response_validation=True)
+ loose_client = Lithic(base_url=base_url, api_key=api_key, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ def test_method_retrieve(self, client: Lithic) -> None:
+ resource = client.events.retrieve(
+ "string",
+ )
+ assert isinstance(resource, Event)
+
+ @parametrize
+ def test_method_list(self, client: Lithic) -> None:
+ resource = client.events.list()
+ assert isinstance(resource, SyncCursorPage)
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Lithic) -> None:
+ resource = client.events.list(
+ begin="2019-12-27T18:11:19.117Z",
+ end="2019-12-27T18:11:19.117Z",
+ page_size=1,
+ starting_after="string",
+ ending_before="string",
+ event_types=["dispute.updated", "dispute.updated", "dispute.updated"],
+ )
+ assert isinstance(resource, SyncCursorPage)
+
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
+ def test_method_resend(self) -> None:
+ self.strict_client.events.resend(
+ "string",
+ event_subscription_token="string",
+ )
+
+
+class TestAsyncEvents:
+ strict_client = AsyncLithic(base_url=base_url, api_key=api_key, _strict_response_validation=True)
+ loose_client = AsyncLithic(base_url=base_url, api_key=api_key, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ async def test_method_retrieve(self, client: AsyncLithic) -> None:
+ resource = await client.events.retrieve(
+ "string",
+ )
+ assert isinstance(resource, Event)
+
+ @parametrize
+ async def test_method_list(self, client: AsyncLithic) -> None:
+ resource = await client.events.list()
+ assert isinstance(resource, AsyncCursorPage)
+
+ @parametrize
+ async def test_method_list_with_all_params(self, client: AsyncLithic) -> None:
+ resource = await client.events.list(
+ begin="2019-12-27T18:11:19.117Z",
+ end="2019-12-27T18:11:19.117Z",
+ page_size=1,
+ starting_after="string",
+ ending_before="string",
+ event_types=["dispute.updated", "dispute.updated", "dispute.updated"],
+ )
+ assert isinstance(resource, AsyncCursorPage)
+
+ @pytest.mark.skip(reason="Prism Mock server doesnt want Accept header, but server requires it.")
+ async def test_method_resend(self) -> None:
+ await self.strict_client.events.resend(
+ "string",
+ event_subscription_token="string",
+ )