diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 71a7a376..11ee3b31 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,6 +10,7 @@ on:
jobs:
lint:
+ timeout-minutes: 10
name: lint
runs-on: ubuntu-latest
steps:
@@ -30,6 +31,7 @@ jobs:
run: ./scripts/lint
test:
+ timeout-minutes: 10
name: test
runs-on: ubuntu-latest
steps:
@@ -50,6 +52,7 @@ jobs:
run: ./scripts/test
examples:
+ timeout-minutes: 10
name: examples
runs-on: ubuntu-latest
if: github.repository == 'lithic-com/lithic-python'
diff --git a/.stats.yml b/.stats.yml
index c5254b76..a758eb12 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 156
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-18973e063e9e9233433290bb4d641df8e17e1f21f5b1ec57e00182f0a48dbdec.yml
-openapi_spec_hash: ab503dc3772f962b603ade7b91b8534c
-config_hash: 6729d695e399d14fff4891b6b82ec86c
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-569e7dcb415398515370989172038db711642cd3b0bd7559bfd2b94e325a6086.yml
+openapi_spec_hash: ce1dae8c6eb50d4490e75357c5e520a7
+config_hash: e9de93b19060a153a852f7c03f235162
diff --git a/README.md b/README.md
index 95c3d2ec..93380fa4 100644
--- a/README.md
+++ b/README.md
@@ -154,7 +154,6 @@ client = Lithic()
card = client.cards.create(
type="VIRTUAL",
)
-print(card.product_id)
```
## Webhook Verification
diff --git a/api.md b/api.md
index a0bc4be9..702d84dc 100644
--- a/api.md
+++ b/api.md
@@ -180,6 +180,7 @@ Types:
from lithic.types import (
Card,
CardSpendLimits,
+ NonPCICard,
SpendLimitDuration,
CardEmbedResponse,
CardProvisionResponse,
@@ -191,7 +192,7 @@ Methods:
- client.cards.create(\*\*params) -> Card
- client.cards.retrieve(card_token) -> Card
- client.cards.update(card_token, \*\*params) -> Card
-- client.cards.list(\*\*params) -> SyncCursorPage[Card]
+- client.cards.list(\*\*params) -> SyncCursorPage[NonPCICard]
- client.cards.convert_physical(card_token, \*\*params) -> Card
- client.cards.embed(\*\*params) -> str
- client.cards.provision(card_token, \*\*params) -> CardProvisionResponse
diff --git a/mypy.ini b/mypy.ini
index c0bb47f6..d895d267 100644
--- a/mypy.ini
+++ b/mypy.ini
@@ -8,7 +8,7 @@ show_error_codes = True
#
# We also exclude our `tests` as mypy doesn't always infer
# types correctly and Pyright will still catch any type errors.
-exclude = ^(src/lithic/_files\.py|_dev/.*\.py|tests/.*|src/lithic/resources/external_bank_accounts/external_bank_accounts\.py)$
+exclude = ^(src/lithic/_files\.py|_dev/.*\.py|tests/.*)$
strict_equality = True
implicit_reexport = True
diff --git a/pyproject.toml b/pyproject.toml
index 503b9057..5d73b169 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -42,7 +42,7 @@ Repository = "https://github.com/lithic-com/lithic-python"
managed = true
# version pins are in requirements-dev.lock
dev-dependencies = [
- "pyright>=1.1.359",
+ "pyright==1.1.399",
"mypy",
"respx",
"pytest",
@@ -147,11 +147,10 @@ exclude = [
]
reportImplicitOverride = true
+reportOverlappingOverload = false
reportImportCycles = false
reportPrivateUsage = false
-reportOverlappingOverload = false
-
[tool.ruff]
line-length = 120
diff --git a/requirements-dev.lock b/requirements-dev.lock
index 196ee452..e0d8eb25 100644
--- a/requirements-dev.lock
+++ b/requirements-dev.lock
@@ -69,7 +69,7 @@ pydantic-core==2.27.1
# via pydantic
pygments==2.18.0
# via rich
-pyright==1.1.392.post0
+pyright==1.1.399
pytest==8.3.3
# via pytest-asyncio
pytest-asyncio==0.24.0
diff --git a/src/lithic/_base_client.py b/src/lithic/_base_client.py
index c3a3eb97..c8a00a94 100644
--- a/src/lithic/_base_client.py
+++ b/src/lithic/_base_client.py
@@ -99,7 +99,11 @@
_AsyncStreamT = TypeVar("_AsyncStreamT", bound=AsyncStream[Any])
if TYPE_CHECKING:
- from httpx._config import DEFAULT_TIMEOUT_CONFIG as HTTPX_DEFAULT_TIMEOUT
+ from httpx._config import (
+ DEFAULT_TIMEOUT_CONFIG, # pyright: ignore[reportPrivateImportUsage]
+ )
+
+ HTTPX_DEFAULT_TIMEOUT = DEFAULT_TIMEOUT_CONFIG
else:
try:
from httpx._config import DEFAULT_TIMEOUT_CONFIG as HTTPX_DEFAULT_TIMEOUT
@@ -116,6 +120,7 @@ class PageInfo:
url: URL | NotGiven
params: Query | NotGiven
+ json: Body | NotGiven
@overload
def __init__(
@@ -131,19 +136,30 @@ def __init__(
params: Query,
) -> None: ...
+ @overload
+ def __init__(
+ self,
+ *,
+ json: Body,
+ ) -> None: ...
+
def __init__(
self,
*,
url: URL | NotGiven = NOT_GIVEN,
+ json: Body | NotGiven = NOT_GIVEN,
params: Query | NotGiven = NOT_GIVEN,
) -> None:
self.url = url
+ self.json = json
self.params = params
@override
def __repr__(self) -> str:
if self.url:
return f"{self.__class__.__name__}(url={self.url})"
+ if self.json:
+ return f"{self.__class__.__name__}(json={self.json})"
return f"{self.__class__.__name__}(params={self.params})"
@@ -192,6 +208,19 @@ def _info_to_options(self, info: PageInfo) -> FinalRequestOptions:
options.url = str(url)
return options
+ if not isinstance(info.json, NotGiven):
+ if not is_mapping(info.json):
+ raise TypeError("Pagination is only supported with mappings")
+
+ if not options.json_data:
+ options.json_data = {**info.json}
+ else:
+ if not is_mapping(options.json_data):
+ raise TypeError("Pagination is only supported with mappings")
+
+ options.json_data = {**options.json_data, **info.json}
+ return options
+
raise ValueError("Unexpected PageInfo state")
@@ -410,7 +439,8 @@ def _build_headers(self, options: FinalRequestOptions, *, retries_taken: int = 0
idempotency_header = self._idempotency_header
if idempotency_header and options.method.lower() != "get" and idempotency_header not in headers:
- headers[idempotency_header] = options.idempotency_key or self._idempotency_key()
+ options.idempotency_key = options.idempotency_key or self._idempotency_key()
+ headers[idempotency_header] = options.idempotency_key
# Don't set these headers if they were already set or removed by the caller. We check
# `custom_headers`, which can contain `Omit()`, instead of `headers` to account for the removal case.
@@ -944,6 +974,10 @@ def _request(
request = self._build_request(options, retries_taken=retries_taken)
self._prepare_request(request)
+ if options.idempotency_key:
+ # ensure the idempotency key is reused between requests
+ input_options.idempotency_key = options.idempotency_key
+
kwargs: HttpxSendArgs = {}
if self.custom_auth is not None:
kwargs["auth"] = self.custom_auth
@@ -1490,6 +1524,10 @@ async def _request(
request = self._build_request(options, retries_taken=retries_taken)
await self._prepare_request(request)
+ if options.idempotency_key:
+ # ensure the idempotency key is reused between requests
+ input_options.idempotency_key = options.idempotency_key
+
kwargs: HttpxSendArgs = {}
if self.custom_auth is not None:
kwargs["auth"] = self.custom_auth
diff --git a/src/lithic/_models.py b/src/lithic/_models.py
index 34935716..58b9263e 100644
--- a/src/lithic/_models.py
+++ b/src/lithic/_models.py
@@ -19,7 +19,6 @@
)
import pydantic
-import pydantic.generics
from pydantic.fields import FieldInfo
from ._types import (
diff --git a/src/lithic/_utils/_typing.py b/src/lithic/_utils/_typing.py
index 1958820f..1bac9542 100644
--- a/src/lithic/_utils/_typing.py
+++ b/src/lithic/_utils/_typing.py
@@ -110,7 +110,7 @@ class MyResponse(Foo[_T]):
```
"""
cls = cast(object, get_origin(typ) or typ)
- if cls in generic_bases:
+ if cls in generic_bases: # pyright: ignore[reportUnnecessaryContains]
# we're given the class directly
return extract_type_arg(typ, index)
diff --git a/src/lithic/resources/account_holders.py b/src/lithic/resources/account_holders.py
index c4379897..fcd70ecc 100644
--- a/src/lithic/resources/account_holders.py
+++ b/src/lithic/resources/account_holders.py
@@ -88,15 +88,17 @@ def create(
Create an account holder and initiate the appropriate onboarding workflow.
Account holders and accounts have a 1:1 relationship. When an account holder is
successfully created an associated account is also created. All calls to this
- endpoint will return an immediate response - though in some cases, the response
- may indicate the enrollment is under review or further action will be needed to
- complete the account enrollment process. This endpoint can only be used on
- accounts that are part of the program that the calling API key manages.
+ endpoint will return a synchronous response. The response time will depend on
+ the workflow. In some cases, the response may indicate the workflow is under
+ review or further action will be needed to complete the account creation
+ process. This endpoint can only be used on accounts that are part of the program
+ that the calling API key manages.
Args:
- beneficial_owner_individuals: List of all direct and indirect individuals with 25% or more ownership in the
- company. If no individual owns 25% of the company, please identify the largest
- shareholder in this field. See
+ beneficial_owner_individuals: You must submit a list of all direct and indirect individuals with 25% or more
+ ownership in the company. A maximum of 4 beneficial owners can be submitted. If
+ no individual owns 25% of the company you do not need to send beneficial owner
+ information. See
[FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
(Section I) for more background on individuals that should be included.
@@ -163,10 +165,11 @@ def create(
Create an account holder and initiate the appropriate onboarding workflow.
Account holders and accounts have a 1:1 relationship. When an account holder is
successfully created an associated account is also created. All calls to this
- endpoint will return an immediate response - though in some cases, the response
- may indicate the enrollment is under review or further action will be needed to
- complete the account enrollment process. This endpoint can only be used on
- accounts that are part of the program that the calling API key manages.
+ endpoint will return a synchronous response. The response time will depend on
+ the workflow. In some cases, the response may indicate the workflow is under
+ review or further action will be needed to complete the account creation
+ process. This endpoint can only be used on accounts that are part of the program
+ that the calling API key manages.
Args:
individual: Information on individual for whom the account is being opened and KYC is being
@@ -220,10 +223,11 @@ def create(
Create an account holder and initiate the appropriate onboarding workflow.
Account holders and accounts have a 1:1 relationship. When an account holder is
successfully created an associated account is also created. All calls to this
- endpoint will return an immediate response - though in some cases, the response
- may indicate the enrollment is under review or further action will be needed to
- complete the account enrollment process. This endpoint can only be used on
- accounts that are part of the program that the calling API key manages.
+ endpoint will return a synchronous response. The response time will depend on
+ the workflow. In some cases, the response may indicate the workflow is under
+ review or further action will be needed to complete the account creation
+ process. This endpoint can only be used on accounts that are part of the program
+ that the calling API key manages.
Args:
address: KYC Exempt user's current address - PO boxes, UPS drops, and FedEx drops are not
@@ -398,17 +402,19 @@ def update(
is performing KYB or KYC and additional verification is required we will run the
individual's or business's updated information again and return whether the
status is accepted or pending (i.e., further action required). All calls to this
- endpoint will return an immediate response - though in some cases, the response
- may indicate the workflow is under review or further action will be needed to
- complete the evaluation process. This endpoint can only be used on existing
- accounts that are part of the program that the calling API key manages.
+ endpoint will return a synchronous response. The response time will depend on
+ the workflow. In some cases, the response may indicate the workflow is under
+ review or further action will be needed to complete the account creation
+ process. This endpoint can only be used on existing accounts that are part of
+ the program that the calling API key manages.
Args:
beneficial_owner_entities: Deprecated.
- beneficial_owner_individuals: List of all direct and indirect individuals with 25% or more ownership in the
- company. If no individual owns 25% of the company, please identify the largest
- shareholder in this field. See
+ beneficial_owner_individuals: You must submit a list of all direct and indirect individuals with 25% or more
+ ownership in the company. A maximum of 4 beneficial owners can be submitted. If
+ no individual owns 25% of the company you do not need to send beneficial owner
+ information. See
[FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
(Section I) for more background on individuals that should be included.
@@ -462,10 +468,11 @@ def update(
is performing KYB or KYC and additional verification is required we will run the
individual's or business's updated information again and return whether the
status is accepted or pending (i.e., further action required). All calls to this
- endpoint will return an immediate response - though in some cases, the response
- may indicate the workflow is under review or further action will be needed to
- complete the evaluation process. This endpoint can only be used on existing
- accounts that are part of the program that the calling API key manages.
+ endpoint will return a synchronous response. The response time will depend on
+ the workflow. In some cases, the response may indicate the workflow is under
+ review or further action will be needed to complete the account creation
+ process. This endpoint can only be used on existing accounts that are part of
+ the program that the calling API key manages.
Args:
external_id: A user provided id that can be used to link an account holder with an external
@@ -509,10 +516,11 @@ def update(
is performing KYB or KYC and additional verification is required we will run the
individual's or business's updated information again and return whether the
status is accepted or pending (i.e., further action required). All calls to this
- endpoint will return an immediate response - though in some cases, the response
- may indicate the workflow is under review or further action will be needed to
- complete the evaluation process. This endpoint can only be used on existing
- accounts that are part of the program that the calling API key manages.
+ endpoint will return a synchronous response. The response time will depend on
+ the workflow. In some cases, the response may indicate the workflow is under
+ review or further action will be needed to complete the account creation
+ process. This endpoint can only be used on existing accounts that are part of
+ the program that the calling API key manages.
Args:
address: Allowed for: KYC-Exempt, BYO-KYC, BYO-KYB.
@@ -1069,15 +1077,17 @@ async def create(
Create an account holder and initiate the appropriate onboarding workflow.
Account holders and accounts have a 1:1 relationship. When an account holder is
successfully created an associated account is also created. All calls to this
- endpoint will return an immediate response - though in some cases, the response
- may indicate the enrollment is under review or further action will be needed to
- complete the account enrollment process. This endpoint can only be used on
- accounts that are part of the program that the calling API key manages.
+ endpoint will return a synchronous response. The response time will depend on
+ the workflow. In some cases, the response may indicate the workflow is under
+ review or further action will be needed to complete the account creation
+ process. This endpoint can only be used on accounts that are part of the program
+ that the calling API key manages.
Args:
- beneficial_owner_individuals: List of all direct and indirect individuals with 25% or more ownership in the
- company. If no individual owns 25% of the company, please identify the largest
- shareholder in this field. See
+ beneficial_owner_individuals: You must submit a list of all direct and indirect individuals with 25% or more
+ ownership in the company. A maximum of 4 beneficial owners can be submitted. If
+ no individual owns 25% of the company you do not need to send beneficial owner
+ information. See
[FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
(Section I) for more background on individuals that should be included.
@@ -1144,10 +1154,11 @@ async def create(
Create an account holder and initiate the appropriate onboarding workflow.
Account holders and accounts have a 1:1 relationship. When an account holder is
successfully created an associated account is also created. All calls to this
- endpoint will return an immediate response - though in some cases, the response
- may indicate the enrollment is under review or further action will be needed to
- complete the account enrollment process. This endpoint can only be used on
- accounts that are part of the program that the calling API key manages.
+ endpoint will return a synchronous response. The response time will depend on
+ the workflow. In some cases, the response may indicate the workflow is under
+ review or further action will be needed to complete the account creation
+ process. This endpoint can only be used on accounts that are part of the program
+ that the calling API key manages.
Args:
individual: Information on individual for whom the account is being opened and KYC is being
@@ -1201,10 +1212,11 @@ async def create(
Create an account holder and initiate the appropriate onboarding workflow.
Account holders and accounts have a 1:1 relationship. When an account holder is
successfully created an associated account is also created. All calls to this
- endpoint will return an immediate response - though in some cases, the response
- may indicate the enrollment is under review or further action will be needed to
- complete the account enrollment process. This endpoint can only be used on
- accounts that are part of the program that the calling API key manages.
+ endpoint will return a synchronous response. The response time will depend on
+ the workflow. In some cases, the response may indicate the workflow is under
+ review or further action will be needed to complete the account creation
+ process. This endpoint can only be used on accounts that are part of the program
+ that the calling API key manages.
Args:
address: KYC Exempt user's current address - PO boxes, UPS drops, and FedEx drops are not
@@ -1379,17 +1391,19 @@ async def update(
is performing KYB or KYC and additional verification is required we will run the
individual's or business's updated information again and return whether the
status is accepted or pending (i.e., further action required). All calls to this
- endpoint will return an immediate response - though in some cases, the response
- may indicate the workflow is under review or further action will be needed to
- complete the evaluation process. This endpoint can only be used on existing
- accounts that are part of the program that the calling API key manages.
+ endpoint will return a synchronous response. The response time will depend on
+ the workflow. In some cases, the response may indicate the workflow is under
+ review or further action will be needed to complete the account creation
+ process. This endpoint can only be used on existing accounts that are part of
+ the program that the calling API key manages.
Args:
beneficial_owner_entities: Deprecated.
- beneficial_owner_individuals: List of all direct and indirect individuals with 25% or more ownership in the
- company. If no individual owns 25% of the company, please identify the largest
- shareholder in this field. See
+ beneficial_owner_individuals: You must submit a list of all direct and indirect individuals with 25% or more
+ ownership in the company. A maximum of 4 beneficial owners can be submitted. If
+ no individual owns 25% of the company you do not need to send beneficial owner
+ information. See
[FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
(Section I) for more background on individuals that should be included.
@@ -1443,10 +1457,11 @@ async def update(
is performing KYB or KYC and additional verification is required we will run the
individual's or business's updated information again and return whether the
status is accepted or pending (i.e., further action required). All calls to this
- endpoint will return an immediate response - though in some cases, the response
- may indicate the workflow is under review or further action will be needed to
- complete the evaluation process. This endpoint can only be used on existing
- accounts that are part of the program that the calling API key manages.
+ endpoint will return a synchronous response. The response time will depend on
+ the workflow. In some cases, the response may indicate the workflow is under
+ review or further action will be needed to complete the account creation
+ process. This endpoint can only be used on existing accounts that are part of
+ the program that the calling API key manages.
Args:
external_id: A user provided id that can be used to link an account holder with an external
@@ -1490,10 +1505,11 @@ async def update(
is performing KYB or KYC and additional verification is required we will run the
individual's or business's updated information again and return whether the
status is accepted or pending (i.e., further action required). All calls to this
- endpoint will return an immediate response - though in some cases, the response
- may indicate the workflow is under review or further action will be needed to
- complete the evaluation process. This endpoint can only be used on existing
- accounts that are part of the program that the calling API key manages.
+ endpoint will return a synchronous response. The response time will depend on
+ the workflow. In some cases, the response may indicate the workflow is under
+ review or further action will be needed to complete the account creation
+ process. This endpoint can only be used on existing accounts that are part of
+ the program that the calling API key manages.
Args:
address: Allowed for: KYC-Exempt, BYO-KYC, BYO-KYB.
diff --git a/src/lithic/resources/cards/cards.py b/src/lithic/resources/cards/cards.py
index 7a0f467b..a74b42a1 100644
--- a/src/lithic/resources/cards/cards.py
+++ b/src/lithic/resources/cards/cards.py
@@ -62,6 +62,7 @@
AggregateBalancesWithStreamingResponse,
AsyncAggregateBalancesWithStreamingResponse,
)
+from ...types.non_pci_card import NonPCICard
from .financial_transactions import (
FinancialTransactions,
AsyncFinancialTransactions,
@@ -435,7 +436,7 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> SyncCursorPage[Card]:
+ ) -> SyncCursorPage[NonPCICard]:
"""
List cards.
@@ -468,7 +469,7 @@ def list(
"""
return self._get_api_list(
"/v1/cards",
- page=SyncCursorPage[Card],
+ page=SyncCursorPage[NonPCICard],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -487,7 +488,7 @@ def list(
card_list_params.CardListParams,
),
),
- model=Card,
+ model=NonPCICard,
)
def convert_physical(
@@ -1422,7 +1423,7 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> AsyncPaginator[Card, AsyncCursorPage[Card]]:
+ ) -> AsyncPaginator[NonPCICard, AsyncCursorPage[NonPCICard]]:
"""
List cards.
@@ -1455,7 +1456,7 @@ def list(
"""
return self._get_api_list(
"/v1/cards",
- page=AsyncCursorPage[Card],
+ page=AsyncCursorPage[NonPCICard],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -1474,7 +1475,7 @@ def list(
card_list_params.CardListParams,
),
),
- model=Card,
+ model=NonPCICard,
)
async def convert_physical(
diff --git a/src/lithic/resources/management_operations.py b/src/lithic/resources/management_operations.py
index f40679a6..ff1aff7f 100644
--- a/src/lithic/resources/management_operations.py
+++ b/src/lithic/resources/management_operations.py
@@ -53,25 +53,35 @@ def create(
self,
*,
amount: int,
- category: Literal["MANAGEMENT_FEE", "MANAGEMENT_DISPUTE", "MANAGEMENT_REWARD", "MANAGEMENT_ADJUSTMENT"],
+ category: Literal[
+ "MANAGEMENT_FEE",
+ "MANAGEMENT_DISPUTE",
+ "MANAGEMENT_REWARD",
+ "MANAGEMENT_ADJUSTMENT",
+ "MANAGEMENT_DISBURSEMENT",
+ ],
direction: Literal["CREDIT", "DEBIT"],
effective_date: Union[str, date],
event_type: Literal[
- "CASH_BACK",
- "CURRENCY_CONVERSION",
- "INTEREST",
- "LATE_PAYMENT",
- "BILLING_ERROR",
- "PROVISIONAL_CREDIT",
"LOSS_WRITE_OFF",
+ "CASH_BACK",
"CASH_BACK_REVERSAL",
+ "CURRENCY_CONVERSION",
"CURRENCY_CONVERSION_REVERSAL",
+ "INTEREST",
"INTEREST_REVERSAL",
+ "LATE_PAYMENT",
"LATE_PAYMENT_REVERSAL",
+ "BILLING_ERROR",
"BILLING_ERROR_REVERSAL",
+ "PROVISIONAL_CREDIT",
"PROVISIONAL_CREDIT_REVERSAL",
"RETURNED_PAYMENT",
"RETURNED_PAYMENT_REVERSAL",
+ "DISPUTE_WON",
+ "DISPUTE_WON_REVERSAL",
+ "DISBURSE",
+ "DISBURSE_REVERSAL",
],
financial_account_token: str,
token: str | NotGiven = NOT_GIVEN,
@@ -160,7 +170,13 @@ def list(
*,
begin: Union[str, datetime] | NotGiven = NOT_GIVEN,
business_account_token: str | NotGiven = NOT_GIVEN,
- category: Literal["MANAGEMENT_FEE", "MANAGEMENT_DISPUTE", "MANAGEMENT_REWARD", "MANAGEMENT_ADJUSTMENT"]
+ category: Literal[
+ "MANAGEMENT_FEE",
+ "MANAGEMENT_DISPUTE",
+ "MANAGEMENT_REWARD",
+ "MANAGEMENT_ADJUSTMENT",
+ "MANAGEMENT_DISBURSEMENT",
+ ]
| NotGiven = NOT_GIVEN,
end: Union[str, datetime] | NotGiven = NOT_GIVEN,
ending_before: str | NotGiven = NOT_GIVEN,
@@ -304,25 +320,35 @@ async def create(
self,
*,
amount: int,
- category: Literal["MANAGEMENT_FEE", "MANAGEMENT_DISPUTE", "MANAGEMENT_REWARD", "MANAGEMENT_ADJUSTMENT"],
+ category: Literal[
+ "MANAGEMENT_FEE",
+ "MANAGEMENT_DISPUTE",
+ "MANAGEMENT_REWARD",
+ "MANAGEMENT_ADJUSTMENT",
+ "MANAGEMENT_DISBURSEMENT",
+ ],
direction: Literal["CREDIT", "DEBIT"],
effective_date: Union[str, date],
event_type: Literal[
- "CASH_BACK",
- "CURRENCY_CONVERSION",
- "INTEREST",
- "LATE_PAYMENT",
- "BILLING_ERROR",
- "PROVISIONAL_CREDIT",
"LOSS_WRITE_OFF",
+ "CASH_BACK",
"CASH_BACK_REVERSAL",
+ "CURRENCY_CONVERSION",
"CURRENCY_CONVERSION_REVERSAL",
+ "INTEREST",
"INTEREST_REVERSAL",
+ "LATE_PAYMENT",
"LATE_PAYMENT_REVERSAL",
+ "BILLING_ERROR",
"BILLING_ERROR_REVERSAL",
+ "PROVISIONAL_CREDIT",
"PROVISIONAL_CREDIT_REVERSAL",
"RETURNED_PAYMENT",
"RETURNED_PAYMENT_REVERSAL",
+ "DISPUTE_WON",
+ "DISPUTE_WON_REVERSAL",
+ "DISBURSE",
+ "DISBURSE_REVERSAL",
],
financial_account_token: str,
token: str | NotGiven = NOT_GIVEN,
@@ -411,7 +437,13 @@ def list(
*,
begin: Union[str, datetime] | NotGiven = NOT_GIVEN,
business_account_token: str | NotGiven = NOT_GIVEN,
- category: Literal["MANAGEMENT_FEE", "MANAGEMENT_DISPUTE", "MANAGEMENT_REWARD", "MANAGEMENT_ADJUSTMENT"]
+ category: Literal[
+ "MANAGEMENT_FEE",
+ "MANAGEMENT_DISPUTE",
+ "MANAGEMENT_REWARD",
+ "MANAGEMENT_ADJUSTMENT",
+ "MANAGEMENT_DISBURSEMENT",
+ ]
| NotGiven = NOT_GIVEN,
end: Union[str, datetime] | NotGiven = NOT_GIVEN,
ending_before: str | NotGiven = NOT_GIVEN,
diff --git a/src/lithic/resources/payments.py b/src/lithic/resources/payments.py
index f2261cea..99017a27 100644
--- a/src/lithic/resources/payments.py
+++ b/src/lithic/resources/payments.py
@@ -336,7 +336,7 @@ def simulate_receipt(
Simulates a receipt of a Payment.
Args:
- token: Payment token
+ token: Customer-generated payment token used to uniquely identify the simulated payment
amount: Amount
@@ -750,7 +750,7 @@ async def simulate_receipt(
Simulates a receipt of a Payment.
Args:
- token: Payment token
+ token: Customer-generated payment token used to uniquely identify the simulated payment
amount: Amount
diff --git a/src/lithic/types/__init__.py b/src/lithic/types/__init__.py
index 1e468619..f29b77ba 100644
--- a/src/lithic/types/__init__.py
+++ b/src/lithic/types/__init__.py
@@ -23,6 +23,7 @@
from .owner_type import OwnerType as OwnerType
from .transaction import Transaction as Transaction
from .card_program import CardProgram as CardProgram
+from .non_pci_card import NonPCICard as NonPCICard
from .tokenization import Tokenization as Tokenization
from .account_holder import AccountHolder as AccountHolder
from .message_attempt import MessageAttempt as MessageAttempt
diff --git a/src/lithic/types/account.py b/src/lithic/types/account.py
index 42cfa81c..cc78097c 100644
--- a/src/lithic/types/account.py
+++ b/src/lithic/types/account.py
@@ -76,10 +76,7 @@ class Account(BaseModel):
"""
created: Optional[datetime] = None
- """Timestamp of when the account was created.
-
- For accounts created before 2023-05-11, this field will be null.
- """
+ """Timestamp of when the account was created."""
spend_limit: SpendLimit
"""
diff --git a/src/lithic/types/account_holder.py b/src/lithic/types/account_holder.py
index 9c30be34..0c2369d4 100644
--- a/src/lithic/types/account_holder.py
+++ b/src/lithic/types/account_holder.py
@@ -210,9 +210,10 @@ class AccountHolder(BaseModel):
beneficial_owner_individuals: Optional[List[BeneficialOwnerIndividual]] = None
"""
- Only present when user_type == "BUSINESS". List of all direct and indirect
- individuals with 25% or more ownership in the company. If no individual owns 25%
- of the company, please identify the largest shareholder in this field. See
+ Only present when user_type == "BUSINESS". You must submit a list of all direct
+ and indirect individuals with 25% or more ownership in the company. A maximum of
+ 4 beneficial owners can be submitted. If no individual owns 25% of the company
+ you do not need to send beneficial owner information. See
[FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
(Section I) for more background on individuals that should be included.
"""
diff --git a/src/lithic/types/account_holder_create_params.py b/src/lithic/types/account_holder_create_params.py
index eb5939dc..bc242c85 100644
--- a/src/lithic/types/account_holder_create_params.py
+++ b/src/lithic/types/account_holder_create_params.py
@@ -23,9 +23,10 @@
class KYB(TypedDict, total=False):
beneficial_owner_individuals: Required[Iterable[KYBBeneficialOwnerIndividual]]
"""
- List of all direct and indirect individuals with 25% or more ownership in the
- company. If no individual owns 25% of the company, please identify the largest
- shareholder in this field. See
+ You must submit a list of all direct and indirect individuals with 25% or more
+ ownership in the company. A maximum of 4 beneficial owners can be submitted. If
+ no individual owns 25% of the company you do not need to send beneficial owner
+ information. See
[FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
(Section I) for more background on individuals that should be included.
"""
diff --git a/src/lithic/types/account_holder_simulate_enrollment_review_response.py b/src/lithic/types/account_holder_simulate_enrollment_review_response.py
index 7a95e2a2..3fd973b0 100644
--- a/src/lithic/types/account_holder_simulate_enrollment_review_response.py
+++ b/src/lithic/types/account_holder_simulate_enrollment_review_response.py
@@ -255,9 +255,10 @@ class AccountHolderSimulateEnrollmentReviewResponse(BaseModel):
beneficial_owner_individuals: Optional[List[BeneficialOwnerIndividual]] = None
"""Only present when user_type == "BUSINESS".
- List of all direct and indirect individuals with 25% or more ownership in the
- company. If no individual owns 25% of the company, please identify the largest
- shareholder in this field. See
+ You must submit a list of all direct and indirect individuals with 25% or more
+ ownership in the company. A maximum of 4 beneficial owners can be submitted. If
+ no individual owns 25% of the company you do not need to send beneficial owner
+ information. See
[FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
(Section I) for more background on individuals that should be included.
"""
diff --git a/src/lithic/types/account_holder_update_params.py b/src/lithic/types/account_holder_update_params.py
index 51e97a84..89b2caf5 100644
--- a/src/lithic/types/account_holder_update_params.py
+++ b/src/lithic/types/account_holder_update_params.py
@@ -26,9 +26,10 @@ class KYBPatchRequest(TypedDict, total=False):
beneficial_owner_individuals: Iterable[KYBPatchRequestBeneficialOwnerIndividual]
"""
- List of all direct and indirect individuals with 25% or more ownership in the
- company. If no individual owns 25% of the company, please identify the largest
- shareholder in this field. See
+ You must submit a list of all direct and indirect individuals with 25% or more
+ ownership in the company. A maximum of 4 beneficial owners can be submitted. If
+ no individual owns 25% of the company you do not need to send beneficial owner
+ information. See
[FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
(Section I) for more background on individuals that should be included.
"""
diff --git a/src/lithic/types/account_holder_update_response.py b/src/lithic/types/account_holder_update_response.py
index d6e436fb..490c5b4f 100644
--- a/src/lithic/types/account_holder_update_response.py
+++ b/src/lithic/types/account_holder_update_response.py
@@ -258,9 +258,10 @@ class KYBKYCPatchResponse(BaseModel):
beneficial_owner_individuals: Optional[List[KybkycPatchResponseBeneficialOwnerIndividual]] = None
"""Only present when user_type == "BUSINESS".
- List of all direct and indirect individuals with 25% or more ownership in the
- company. If no individual owns 25% of the company, please identify the largest
- shareholder in this field. See
+ You must submit a list of all direct and indirect individuals with 25% or more
+ ownership in the company. A maximum of 4 beneficial owners can be submitted. If
+ no individual owns 25% of the company you do not need to send beneficial owner
+ information. See
[FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
(Section I) for more background on individuals that should be included.
"""
diff --git a/src/lithic/types/card.py b/src/lithic/types/card.py
index e722490d..61bf6a0b 100644
--- a/src/lithic/types/card.py
+++ b/src/lithic/types/card.py
@@ -1,205 +1,19 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
+from typing import Optional
-from .._models import BaseModel
-from .spend_limit_duration import SpendLimitDuration
+from .non_pci_card import NonPCICard
-__all__ = ["Card", "Funding"]
+__all__ = ["Card"]
-class Funding(BaseModel):
- token: str
- """A globally unique identifier for this FundingAccount."""
-
- created: datetime
- """
- An RFC 3339 string representing when this funding source was added to the Lithic
- account. This may be `null`. UTC time zone.
- """
-
- last_four: str
- """The last 4 digits of the account (e.g.
-
- bank account, debit card) associated with this FundingAccount. This may be null.
- """
-
- state: Literal["DELETED", "ENABLED", "PENDING"]
- """State of funding source.
-
- Funding source states:
-
- - `ENABLED` - The funding account is available to use for card creation and
- transactions.
- - `PENDING` - The funding account is still being verified e.g. bank
- micro-deposits verification.
- - `DELETED` - The founding account has been deleted.
- """
-
- type: Literal["DEPOSITORY_CHECKING", "DEPOSITORY_SAVINGS"]
- """Types of funding source:
-
- - `DEPOSITORY_CHECKING` - Bank checking account.
- - `DEPOSITORY_SAVINGS` - Bank savings account.
- """
-
- account_name: Optional[str] = None
- """Account name identifying the funding source. This may be `null`."""
-
- nickname: Optional[str] = None
- """The nickname given to the `FundingAccount` or `null` if it has no nickname."""
-
-
-class Card(BaseModel):
- token: str
- """Globally unique identifier."""
-
- account_token: str
- """Globally unique identifier for the account to which the card belongs."""
-
- card_program_token: str
- """Globally unique identifier for the card program on which the card exists."""
-
- created: datetime
- """An RFC 3339 timestamp for when the card was created. UTC time zone."""
-
- funding: Funding
- """Deprecated: Funding account for the card."""
-
- last_four: str
- """Last four digits of the card number."""
-
- pin_status: Literal["OK", "BLOCKED", "NOT_SET"]
- """Indicates if a card is blocked due a PIN status issue (e.g.
-
- excessive incorrect attempts).
- """
-
- spend_limit: int
- """Amount (in cents) to limit approved authorizations (e.g.
-
- 100000 would be a $1,000 limit). Transaction requests above the spend limit will
- be declined.
- """
-
- spend_limit_duration: SpendLimitDuration
- """Spend limit duration values:
-
- - `ANNUALLY` - Card will authorize transactions up to spend limit for the
- trailing year.
- - `FOREVER` - Card will authorize only up to spend limit for the entire lifetime
- of the card.
- - `MONTHLY` - Card will authorize transactions up to spend limit for the
- trailing month. To support recurring monthly payments, which can occur on
- different day every month, the time window we consider for monthly velocity
- starts 6 days after the current calendar date one month prior.
- - `TRANSACTION` - Card will authorize multiple transactions if each individual
- transaction is under the spend limit.
- """
-
- state: Literal["CLOSED", "OPEN", "PAUSED", "PENDING_ACTIVATION", "PENDING_FULFILLMENT"]
- """Card state values:
-
- - `CLOSED` - Card will no longer approve authorizations. Closing a card cannot
- be undone.
- - `OPEN` - Card will approve authorizations (if they match card and account
- parameters).
- - `PAUSED` - Card will decline authorizations, but can be resumed at a later
- time.
- - `PENDING_FULFILLMENT` - The initial state for cards of type `PHYSICAL`. The
- card is provisioned pending manufacturing and fulfillment. Cards in this state
- can accept authorizations for e-commerce purchases, but not for "Card Present"
- purchases where the physical card itself is present.
- - `PENDING_ACTIVATION` - At regular intervals, cards of type `PHYSICAL` in state
- `PENDING_FULFILLMENT` are sent to the card production warehouse and updated to
- state `PENDING_ACTIVATION` . Similar to `PENDING_FULFILLMENT`, cards in this
- state can be used for e-commerce transactions or can be added to mobile
- wallets. API clients should update the card's state to `OPEN` only after the
- cardholder confirms receipt of the card.
-
- In sandbox, the same daily batch fulfillment occurs, but no cards are actually
- manufactured.
- """
-
- type: Literal["MERCHANT_LOCKED", "PHYSICAL", "SINGLE_USE", "VIRTUAL", "UNLOCKED", "DIGITAL_WALLET"]
- """Card types:
-
- - `VIRTUAL` - Card will authorize at any merchant and can be added to a digital
- wallet like Apple Pay or Google Pay (if the card program is digital
- wallet-enabled).
- - `PHYSICAL` - Manufactured and sent to the cardholder. We offer white label
- branding, credit, ATM, PIN debit, chip/EMV, NFC and magstripe functionality.
- Reach out at [lithic.com/contact](https://lithic.com/contact) for more
- information.
- - `SINGLE_USE` - Card is closed upon first successful authorization.
- - `MERCHANT_LOCKED` - _[Deprecated]_ Card is locked to the first merchant that
- successfully authorizes the card.
- - `UNLOCKED` - _[Deprecated]_ Similar behavior to VIRTUAL cards, please use
- VIRTUAL instead.
- - `DIGITAL_WALLET` - _[Deprecated]_ Similar behavior to VIRTUAL cards, please
- use VIRTUAL instead.
- """
-
- auth_rule_tokens: Optional[List[str]] = None
- """
- List of identifiers for the Auth Rule(s) that are applied on the card. This
- field is deprecated and will no longer be populated in the `Card` object. The
- key will be removed from the schema in a future release. Use the `/auth_rules`
- endpoints to fetch Auth Rule information instead.
- """
-
- cardholder_currency: Optional[str] = None
- """3-character alphabetic ISO 4217 code for the currency of the cardholder."""
-
+class Card(NonPCICard):
cvv: Optional[str] = None
"""Three digit cvv printed on the back of the card."""
- digital_card_art_token: Optional[str] = None
- """
- Specifies the digital card art to be displayed in the user’s digital wallet
- after tokenization. This artwork must be approved by Mastercard and configured
- by Lithic to use. See
- [Flexible Card Art Guide](https://docs.lithic.com/docs/about-digital-wallets#flexible-card-art).
- """
-
- exp_month: Optional[str] = None
- """Two digit (MM) expiry month."""
-
- exp_year: Optional[str] = None
- """Four digit (yyyy) expiry year."""
-
- hostname: Optional[str] = None
- """Hostname of card’s locked merchant (will be empty if not applicable)."""
-
- memo: Optional[str] = None
- """Friendly name to identify the card."""
-
pan: Optional[str] = None
"""Primary Account Number (PAN) (i.e.
the card number). Customers must be PCI compliant to have PAN returned as a
- field in production. Please contact
- [support@lithic.com](mailto:support@lithic.com) for questions.
- """
-
- pending_commands: Optional[List[str]] = None
- """
- Indicates if there are offline PIN changes pending card interaction with an
- offline PIN terminal. Possible commands are: CHANGE_PIN, UNBLOCK_PIN. Applicable
- only to cards issued in markets supporting offline PINs.
- """
-
- product_id: Optional[str] = None
- """Only applicable to cards of type `PHYSICAL`.
-
- This must be configured with Lithic before use. Specifies the configuration
- (i.e., physical card art) that the card should be manufactured with.
- """
-
- replacement_for: Optional[str] = None
- """
- If the card is a replacement for another card, the globally unique identifier
- for the card that was replaced.
+ field in production. Please contact support@lithic.com for questions.
"""
diff --git a/src/lithic/types/dispute.py b/src/lithic/types/dispute.py
index e217d8e8..38a26a97 100644
--- a/src/lithic/types/dispute.py
+++ b/src/lithic/types/dispute.py
@@ -86,9 +86,6 @@ class Dispute(BaseModel):
representment_date: Optional[datetime] = None
"""Date the representment was received."""
- resolution_amount: Optional[int] = None
- """Resolution amount net of network fees."""
-
resolution_date: Optional[datetime] = None
"""Date that the dispute was resolved."""
diff --git a/src/lithic/types/financial_account.py b/src/lithic/types/financial_account.py
index bb763758..88682948 100644
--- a/src/lithic/types/financial_account.py
+++ b/src/lithic/types/financial_account.py
@@ -48,7 +48,14 @@ class FinancialAccount(BaseModel):
"""Status of the financial account"""
type: Literal[
- "ISSUING", "RESERVE", "OPERATING", "CHARGED_OFF_FEES", "CHARGED_OFF_INTEREST", "CHARGED_OFF_PRINCIPAL"
+ "ISSUING",
+ "RESERVE",
+ "OPERATING",
+ "CHARGED_OFF_FEES",
+ "CHARGED_OFF_INTEREST",
+ "CHARGED_OFF_PRINCIPAL",
+ "SECURITY",
+ "PROGRAM_RECEIVABLES",
]
updated: datetime
diff --git a/src/lithic/types/financial_accounts/statements/statement_line_items.py b/src/lithic/types/financial_accounts/statements/statement_line_items.py
index 1269fb72..3b9bc40e 100644
--- a/src/lithic/types/financial_accounts/statements/statement_line_items.py
+++ b/src/lithic/types/financial_accounts/statements/statement_line_items.py
@@ -28,6 +28,7 @@ class Data(BaseModel):
"MANAGEMENT_DISPUTE",
"MANAGEMENT_FEE",
"MANAGEMENT_REWARD",
+ "MANAGEMENT_DISBURSEMENT",
]
created: datetime
@@ -108,6 +109,7 @@ class Data(BaseModel):
"TRANSFER_INSUFFICIENT_FUNDS",
"RETURNED_PAYMENT",
"RETURNED_PAYMENT_REVERSAL",
+ "LITHIC_NETWORK_PAYMENT",
]
financial_account_token: str
diff --git a/src/lithic/types/financial_transaction.py b/src/lithic/types/financial_transaction.py
index 0f4a21ee..ecbbade3 100644
--- a/src/lithic/types/financial_transaction.py
+++ b/src/lithic/types/financial_transaction.py
@@ -95,6 +95,7 @@ class Event(BaseModel):
"TRANSFER_INSUFFICIENT_FUNDS",
"RETURNED_PAYMENT",
"RETURNED_PAYMENT_REVERSAL",
+ "LITHIC_NETWORK_PAYMENT",
]
] = None
diff --git a/src/lithic/types/kyb_param.py b/src/lithic/types/kyb_param.py
index 46944344..a799e1f7 100644
--- a/src/lithic/types/kyb_param.py
+++ b/src/lithic/types/kyb_param.py
@@ -147,9 +147,10 @@ class BeneficialOwnerEntity(TypedDict, total=False):
class KYBParam(TypedDict, total=False):
beneficial_owner_individuals: Required[Iterable[BeneficialOwnerIndividual]]
"""
- List of all direct and indirect individuals with 25% or more ownership in the
- company. If no individual owns 25% of the company, please identify the largest
- shareholder in this field. See
+ You must submit a list of all direct and indirect individuals with 25% or more
+ ownership in the company. A maximum of 4 beneficial owners can be submitted. If
+ no individual owns 25% of the company you do not need to send beneficial owner
+ information. See
[FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
(Section I) for more background on individuals that should be included.
"""
diff --git a/src/lithic/types/management_operation_create_params.py b/src/lithic/types/management_operation_create_params.py
index d8e8b559..df6a0956 100644
--- a/src/lithic/types/management_operation_create_params.py
+++ b/src/lithic/types/management_operation_create_params.py
@@ -14,7 +14,15 @@
class ManagementOperationCreateParams(TypedDict, total=False):
amount: Required[int]
- category: Required[Literal["MANAGEMENT_FEE", "MANAGEMENT_DISPUTE", "MANAGEMENT_REWARD", "MANAGEMENT_ADJUSTMENT"]]
+ category: Required[
+ Literal[
+ "MANAGEMENT_FEE",
+ "MANAGEMENT_DISPUTE",
+ "MANAGEMENT_REWARD",
+ "MANAGEMENT_ADJUSTMENT",
+ "MANAGEMENT_DISBURSEMENT",
+ ]
+ ]
direction: Required[Literal["CREDIT", "DEBIT"]]
@@ -22,21 +30,25 @@ class ManagementOperationCreateParams(TypedDict, total=False):
event_type: Required[
Literal[
- "CASH_BACK",
- "CURRENCY_CONVERSION",
- "INTEREST",
- "LATE_PAYMENT",
- "BILLING_ERROR",
- "PROVISIONAL_CREDIT",
"LOSS_WRITE_OFF",
+ "CASH_BACK",
"CASH_BACK_REVERSAL",
+ "CURRENCY_CONVERSION",
"CURRENCY_CONVERSION_REVERSAL",
+ "INTEREST",
"INTEREST_REVERSAL",
+ "LATE_PAYMENT",
"LATE_PAYMENT_REVERSAL",
+ "BILLING_ERROR",
"BILLING_ERROR_REVERSAL",
+ "PROVISIONAL_CREDIT",
"PROVISIONAL_CREDIT_REVERSAL",
"RETURNED_PAYMENT",
"RETURNED_PAYMENT_REVERSAL",
+ "DISPUTE_WON",
+ "DISPUTE_WON_REVERSAL",
+ "DISBURSE",
+ "DISBURSE_REVERSAL",
]
]
diff --git a/src/lithic/types/management_operation_list_params.py b/src/lithic/types/management_operation_list_params.py
index 7e460afe..7ce00805 100644
--- a/src/lithic/types/management_operation_list_params.py
+++ b/src/lithic/types/management_operation_list_params.py
@@ -20,7 +20,9 @@ class ManagementOperationListParams(TypedDict, total=False):
business_account_token: str
- category: Literal["MANAGEMENT_FEE", "MANAGEMENT_DISPUTE", "MANAGEMENT_REWARD", "MANAGEMENT_ADJUSTMENT"]
+ category: Literal[
+ "MANAGEMENT_FEE", "MANAGEMENT_DISPUTE", "MANAGEMENT_REWARD", "MANAGEMENT_ADJUSTMENT", "MANAGEMENT_DISBURSEMENT"
+ ]
"""Management operation category to be returned."""
end: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
diff --git a/src/lithic/types/management_operation_transaction.py b/src/lithic/types/management_operation_transaction.py
index e115eb40..dce9996e 100644
--- a/src/lithic/types/management_operation_transaction.py
+++ b/src/lithic/types/management_operation_transaction.py
@@ -25,21 +25,25 @@ class Event(BaseModel):
result: Literal["APPROVED", "DECLINED"]
type: Literal[
- "CASH_BACK",
- "CURRENCY_CONVERSION",
- "INTEREST",
- "LATE_PAYMENT",
- "BILLING_ERROR",
- "PROVISIONAL_CREDIT",
"LOSS_WRITE_OFF",
+ "CASH_BACK",
"CASH_BACK_REVERSAL",
+ "CURRENCY_CONVERSION",
"CURRENCY_CONVERSION_REVERSAL",
+ "INTEREST",
"INTEREST_REVERSAL",
+ "LATE_PAYMENT",
"LATE_PAYMENT_REVERSAL",
+ "BILLING_ERROR",
"BILLING_ERROR_REVERSAL",
+ "PROVISIONAL_CREDIT",
"PROVISIONAL_CREDIT_REVERSAL",
"RETURNED_PAYMENT",
"RETURNED_PAYMENT_REVERSAL",
+ "DISPUTE_WON",
+ "DISPUTE_WON_REVERSAL",
+ "DISBURSE",
+ "DISBURSE_REVERSAL",
]
subtype: Optional[str] = None
@@ -56,7 +60,9 @@ class TransactionSeries(BaseModel):
class ManagementOperationTransaction(BaseModel):
token: str
- category: Literal["MANAGEMENT_FEE", "MANAGEMENT_DISPUTE", "MANAGEMENT_REWARD", "MANAGEMENT_ADJUSTMENT"]
+ category: Literal[
+ "MANAGEMENT_FEE", "MANAGEMENT_DISPUTE", "MANAGEMENT_REWARD", "MANAGEMENT_ADJUSTMENT", "MANAGEMENT_DISBURSEMENT"
+ ]
created: datetime
diff --git a/src/lithic/types/non_pci_card.py b/src/lithic/types/non_pci_card.py
new file mode 100644
index 00000000..cdaf8d6e
--- /dev/null
+++ b/src/lithic/types/non_pci_card.py
@@ -0,0 +1,166 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["NonPCICard", "Funding"]
+
+
+class Funding(BaseModel):
+ token: str
+ """A globally unique identifier for this FundingAccount."""
+
+ created: datetime
+ """
+ An RFC 3339 string representing when this funding source was added to the Lithic
+ account. This may be `null`. UTC time zone.
+ """
+
+ last_four: str
+ """The last 4 digits of the account (e.g.
+
+ bank account, debit card) associated with this FundingAccount. This may be null.
+ """
+
+ state: Literal["DELETED", "ENABLED", "PENDING"]
+ """State of funding source.
+
+ Funding source states: _ `ENABLED` - The funding account is available to use for
+ card creation and transactions. _ `PENDING` - The funding account is still being
+ verified e.g. bank micro-deposits verification. \\** `DELETED` - The founding
+ account has been deleted.
+ """
+
+ type: Literal["DEPOSITORY_CHECKING", "DEPOSITORY_SAVINGS"]
+ """Types of funding source: \\** `DEPOSITORY_CHECKING` - Bank checking account.
+
+ - `DEPOSITORY_SAVINGS` - Bank savings account.
+ """
+
+ account_name: Optional[str] = None
+ """Account name identifying the funding source. This may be `null`."""
+
+ nickname: Optional[str] = None
+ """The nickname given to the `FundingAccount` or `null` if it has no nickname."""
+
+
+class NonPCICard(BaseModel):
+ token: str
+ """Globally unique identifier."""
+
+ account_token: str
+ """Globally unique identifier for the account to which the card belongs."""
+
+ card_program_token: str
+ """Globally unique identifier for the card program on which the card exists."""
+
+ created: datetime
+ """An RFC 3339 timestamp for when the card was created. UTC time zone."""
+
+ funding: Funding
+ """Deprecated: Funding account for the card."""
+
+ last_four: str
+ """Last four digits of the card number."""
+
+ pin_status: Literal["OK", "BLOCKED", "NOT_SET"]
+ """Indicates if a card is blocked due a PIN status issue (e.g.
+
+ excessive incorrect attempts).
+ """
+
+ spend_limit: int
+ """Amount (in cents) to limit approved authorizations (e.g.
+
+ 100000 would be a $1,000 limit). Transaction requests above the spend limit will
+ be declined.
+ """
+
+ spend_limit_duration: Literal["ANNUALLY", "FOREVER", "MONTHLY", "TRANSACTION", "DAILY"]
+ """Spend limit duration"""
+
+ state: Literal["CLOSED", "OPEN", "PAUSED", "PENDING_ACTIVATION", "PENDING_FULFILLMENT"]
+ """Card state values: \\** `CLOSED` - Card will no longer approve authorizations.
+
+ Closing a card cannot be undone. _ `OPEN` - Card will approve authorizations (if
+ they match card and account parameters). _ `PAUSED` - Card will decline
+ authorizations, but can be resumed at a later time. _ `PENDING_FULFILLMENT` -
+ The initial state for cards of type `PHYSICAL`. The card is provisioned pending
+ manufacturing and fulfillment. Cards in this state can accept authorizations for
+ e-commerce purchases, but not for "Card Present" purchases where the physical
+ card itself is present. _ `PENDING_ACTIVATION` - At regular intervals, cards of
+ type `PHYSICAL` in state `PENDING_FULFILLMENT` are sent to the card production
+ warehouse and updated to state `PENDING_ACTIVATION`. Similar to
+ `PENDING_FULFILLMENT`, cards in this state can be used for e-commerce
+ transactions or can be added to mobile wallets. API clients should update the
+ card's state to `OPEN` only after the cardholder confirms receipt of the card.
+ In sandbox, the same daily batch fulfillment occurs, but no cards are actually
+ manufactured.
+ """
+
+ type: Literal["MERCHANT_LOCKED", "PHYSICAL", "SINGLE_USE", "VIRTUAL", "UNLOCKED", "DIGITAL_WALLET"]
+ """
+ Card types: _ `VIRTUAL` - Card will authorize at any merchant and can be added
+ to a digital wallet like Apple Pay or Google Pay (if the card program is digital
+ wallet-enabled). _ `PHYSICAL` - Manufactured and sent to the cardholder. We
+ offer white label branding, credit, ATM, PIN debit, chip/EMV, NFC and magstripe
+ functionality. _ `SINGLE_USE` - Card is closed upon first successful
+ authorization. _ `MERCHANT_LOCKED` - _[Deprecated]_ Card is locked to the first
+ merchant that successfully authorizes the card. _ `UNLOCKED` - _[Deprecated]_
+ Similar behavior to VIRTUAL cards, please use VIRTUAL instead. _
+ `DIGITAL_WALLET` - _[Deprecated]_ Similar behavior to VIRTUAL cards, please use
+ VIRTUAL instead.
+ """
+
+ auth_rule_tokens: Optional[List[str]] = None
+ """List of identifiers for the Auth Rule(s) that are applied on the card.
+
+ This field is deprecated and will no longer be populated in the `Card` object.
+ The key will be removed from the schema in a future release. Use the
+ `/auth_rules` endpoints to fetch Auth Rule information instead.
+ """
+
+ cardholder_currency: Optional[str] = None
+ """3-character alphabetic ISO 4217 code for the currency of the cardholder."""
+
+ digital_card_art_token: Optional[str] = None
+ """
+ Specifies the digital card art to be displayed in the user's digital wallet
+ after tokenization. This artwork must be approved by Mastercard and configured
+ by Lithic to use.
+ """
+
+ exp_month: Optional[str] = None
+ """Two digit (MM) expiry month."""
+
+ exp_year: Optional[str] = None
+ """Four digit (yyyy) expiry year."""
+
+ hostname: Optional[str] = None
+ """Hostname of card's locked merchant (will be empty if not applicable)."""
+
+ memo: Optional[str] = None
+ """Friendly name to identify the card."""
+
+ pending_commands: Optional[List[str]] = None
+ """
+ Indicates if there are offline PIN changes pending card interaction with an
+ offline PIN terminal. Possible commands are: CHANGE_PIN, UNBLOCK_PIN. Applicable
+ only to cards issued in markets supporting offline PINs.
+ """
+
+ product_id: Optional[str] = None
+ """Only applicable to cards of type `PHYSICAL`.
+
+ This must be configured with Lithic before use. Specifies the configuration
+ (i.e., physical card art) that the card should be manufactured with.
+ """
+
+ replacement_for: Optional[str] = None
+ """
+ If the card is a replacement for another card, the globally unique identifier
+ for the card that was replaced.
+ """
diff --git a/src/lithic/types/payment_simulate_receipt_params.py b/src/lithic/types/payment_simulate_receipt_params.py
index 86618fc1..4c574031 100644
--- a/src/lithic/types/payment_simulate_receipt_params.py
+++ b/src/lithic/types/payment_simulate_receipt_params.py
@@ -9,7 +9,9 @@
class PaymentSimulateReceiptParams(TypedDict, total=False):
token: Required[str]
- """Payment token"""
+ """
+ Customer-generated payment token used to uniquely identify the simulated payment
+ """
amount: Required[int]
"""Amount"""
diff --git a/src/lithic/types/shared/instance_financial_account_type.py b/src/lithic/types/shared/instance_financial_account_type.py
index 912d719c..4051b683 100644
--- a/src/lithic/types/shared/instance_financial_account_type.py
+++ b/src/lithic/types/shared/instance_financial_account_type.py
@@ -5,5 +5,12 @@
__all__ = ["InstanceFinancialAccountType"]
InstanceFinancialAccountType: TypeAlias = Literal[
- "ISSUING", "RESERVE", "OPERATING", "CHARGED_OFF_FEES", "CHARGED_OFF_INTEREST", "CHARGED_OFF_PRINCIPAL"
+ "ISSUING",
+ "RESERVE",
+ "OPERATING",
+ "CHARGED_OFF_FEES",
+ "CHARGED_OFF_INTEREST",
+ "CHARGED_OFF_PRINCIPAL",
+ "SECURITY",
+ "PROGRAM_RECEIVABLES",
]
diff --git a/src/lithic/types/transaction.py b/src/lithic/types/transaction.py
index 0080ef14..7a56ffc7 100644
--- a/src/lithic/types/transaction.py
+++ b/src/lithic/types/transaction.py
@@ -33,6 +33,10 @@
"EventNetworkInfoMastercard",
"EventNetworkInfoVisa",
"EventRuleResult",
+ "EventNetworkSpecificData",
+ "EventNetworkSpecificDataMastercard",
+ "EventNetworkSpecificDataMastercardOnBehalfServiceResult",
+ "EventNetworkSpecificDataVisa",
]
@@ -284,6 +288,12 @@ class PosTerminal(BaseModel):
]
"""POS Type"""
+ acceptor_terminal_id: Optional[str] = None
+ """
+ Uniquely identifies a terminal at the card acceptor location of acquiring
+ institutions or merchant POS Systems
+ """
+
class Pos(BaseModel):
entry_mode: PosEntryMode
@@ -494,6 +504,46 @@ class EventRuleResult(BaseModel):
"""The detailed_result associated with this rule's decline."""
+class EventNetworkSpecificDataMastercardOnBehalfServiceResult(BaseModel):
+ result_1: str
+ """Indicates the results of the service processing."""
+
+ result_2: str
+ """Identifies the results of the service processing."""
+
+ service: str
+ """Indicates the service performed on the transaction."""
+
+
+class EventNetworkSpecificDataMastercard(BaseModel):
+ ecommerce_security_level_indicator: Optional[str] = None
+ """Indicates the electronic commerce security level and UCAF collection."""
+
+ on_behalf_service_result: Optional[List[EventNetworkSpecificDataMastercardOnBehalfServiceResult]] = None
+ """The On-behalf Service performed on the transaction and the results.
+
+ Contains all applicable, on-behalf service results that were performed on a
+ given transaction.
+ """
+
+ transaction_type_identifier: Optional[str] = None
+ """Indicates the type of additional transaction purpose."""
+
+
+class EventNetworkSpecificDataVisa(BaseModel):
+ business_application_identifier: Optional[str] = None
+ """
+ Identifies the purpose or category of a transaction, used to classify and
+ process transactions according to Visa’s rules.
+ """
+
+
+class EventNetworkSpecificData(BaseModel):
+ mastercard: EventNetworkSpecificDataMastercard
+
+ visa: EventNetworkSpecificDataVisa
+
+
class Event(BaseModel):
token: str
"""Transaction event identifier."""
@@ -625,6 +675,8 @@ class Event(BaseModel):
]
"""Type of transaction event"""
+ network_specific_data: Optional[EventNetworkSpecificData] = None
+
class Transaction(BaseModel):
token: str
diff --git a/tests/api_resources/test_cards.py b/tests/api_resources/test_cards.py
index dd116a09..a089e191 100644
--- a/tests/api_resources/test_cards.py
+++ b/tests/api_resources/test_cards.py
@@ -11,6 +11,7 @@
from tests.utils import assert_matches_type
from lithic.types import (
Card,
+ NonPCICard,
CardSpendLimits,
CardProvisionResponse,
)
@@ -182,7 +183,7 @@ def test_path_params_update(self, client: Lithic) -> None:
@parametrize
def test_method_list(self, client: Lithic) -> None:
card = client.cards.list()
- assert_matches_type(SyncCursorPage[Card], card, path=["response"])
+ assert_matches_type(SyncCursorPage[NonPCICard], card, path=["response"])
@parametrize
def test_method_list_with_all_params(self, client: Lithic) -> None:
@@ -195,7 +196,7 @@ def test_method_list_with_all_params(self, client: Lithic) -> None:
starting_after="starting_after",
state="CLOSED",
)
- assert_matches_type(SyncCursorPage[Card], card, path=["response"])
+ assert_matches_type(SyncCursorPage[NonPCICard], card, path=["response"])
@parametrize
def test_raw_response_list(self, client: Lithic) -> None:
@@ -204,7 +205,7 @@ def test_raw_response_list(self, client: Lithic) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
card = response.parse()
- assert_matches_type(SyncCursorPage[Card], card, path=["response"])
+ assert_matches_type(SyncCursorPage[NonPCICard], card, path=["response"])
@parametrize
def test_streaming_response_list(self, client: Lithic) -> None:
@@ -213,7 +214,7 @@ def test_streaming_response_list(self, client: Lithic) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
card = response.parse()
- assert_matches_type(SyncCursorPage[Card], card, path=["response"])
+ assert_matches_type(SyncCursorPage[NonPCICard], card, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -803,7 +804,7 @@ async def test_path_params_update(self, async_client: AsyncLithic) -> None:
@parametrize
async def test_method_list(self, async_client: AsyncLithic) -> None:
card = await async_client.cards.list()
- assert_matches_type(AsyncCursorPage[Card], card, path=["response"])
+ assert_matches_type(AsyncCursorPage[NonPCICard], card, path=["response"])
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncLithic) -> None:
@@ -816,7 +817,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLithic) -> N
starting_after="starting_after",
state="CLOSED",
)
- assert_matches_type(AsyncCursorPage[Card], card, path=["response"])
+ assert_matches_type(AsyncCursorPage[NonPCICard], card, path=["response"])
@parametrize
async def test_raw_response_list(self, async_client: AsyncLithic) -> None:
@@ -825,7 +826,7 @@ async def test_raw_response_list(self, async_client: AsyncLithic) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
card = response.parse()
- assert_matches_type(AsyncCursorPage[Card], card, path=["response"])
+ assert_matches_type(AsyncCursorPage[NonPCICard], card, path=["response"])
@parametrize
async def test_streaming_response_list(self, async_client: AsyncLithic) -> None:
@@ -834,7 +835,7 @@ async def test_streaming_response_list(self, async_client: AsyncLithic) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
card = await response.parse()
- assert_matches_type(AsyncCursorPage[Card], card, path=["response"])
+ assert_matches_type(AsyncCursorPage[NonPCICard], card, path=["response"])
assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/test_management_operations.py b/tests/api_resources/test_management_operations.py
index f299847b..6288fda4 100644
--- a/tests/api_resources/test_management_operations.py
+++ b/tests/api_resources/test_management_operations.py
@@ -28,7 +28,7 @@ def test_method_create(self, client: Lithic) -> None:
category="MANAGEMENT_FEE",
direction="CREDIT",
effective_date=parse_date("2019-12-27"),
- event_type="CASH_BACK",
+ event_type="LOSS_WRITE_OFF",
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(ManagementOperationTransaction, management_operation, path=["response"])
@@ -40,7 +40,7 @@ def test_method_create_with_all_params(self, client: Lithic) -> None:
category="MANAGEMENT_FEE",
direction="CREDIT",
effective_date=parse_date("2019-12-27"),
- event_type="CASH_BACK",
+ event_type="LOSS_WRITE_OFF",
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
memo="memo",
@@ -56,7 +56,7 @@ def test_raw_response_create(self, client: Lithic) -> None:
category="MANAGEMENT_FEE",
direction="CREDIT",
effective_date=parse_date("2019-12-27"),
- event_type="CASH_BACK",
+ event_type="LOSS_WRITE_OFF",
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
@@ -72,7 +72,7 @@ def test_streaming_response_create(self, client: Lithic) -> None:
category="MANAGEMENT_FEE",
direction="CREDIT",
effective_date=parse_date("2019-12-27"),
- event_type="CASH_BACK",
+ event_type="LOSS_WRITE_OFF",
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
@@ -227,7 +227,7 @@ async def test_method_create(self, async_client: AsyncLithic) -> None:
category="MANAGEMENT_FEE",
direction="CREDIT",
effective_date=parse_date("2019-12-27"),
- event_type="CASH_BACK",
+ event_type="LOSS_WRITE_OFF",
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(ManagementOperationTransaction, management_operation, path=["response"])
@@ -239,7 +239,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncLithic) ->
category="MANAGEMENT_FEE",
direction="CREDIT",
effective_date=parse_date("2019-12-27"),
- event_type="CASH_BACK",
+ event_type="LOSS_WRITE_OFF",
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
memo="memo",
@@ -255,7 +255,7 @@ async def test_raw_response_create(self, async_client: AsyncLithic) -> None:
category="MANAGEMENT_FEE",
direction="CREDIT",
effective_date=parse_date("2019-12-27"),
- event_type="CASH_BACK",
+ event_type="LOSS_WRITE_OFF",
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
@@ -271,7 +271,7 @@ async def test_streaming_response_create(self, async_client: AsyncLithic) -> Non
category="MANAGEMENT_FEE",
direction="CREDIT",
effective_date=parse_date("2019-12-27"),
- event_type="CASH_BACK",
+ event_type="LOSS_WRITE_OFF",
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
diff --git a/tests/conftest.py b/tests/conftest.py
index f38ded45..4de50f30 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -10,7 +10,7 @@
from lithic import Lithic, AsyncLithic
if TYPE_CHECKING:
- from _pytest.fixtures import FixtureRequest
+ from _pytest.fixtures import FixtureRequest # pyright: ignore[reportPrivateImportUsage]
pytest.register_assert_rewrite("tests.utils")
diff --git a/tests/test_models.py b/tests/test_models.py
index 154fc144..00798c04 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -492,12 +492,15 @@ class Model(BaseModel):
resource_id: Optional[str] = None
m = Model.construct()
+ assert m.resource_id is None
assert "resource_id" not in m.model_fields_set
m = Model.construct(resource_id=None)
+ assert m.resource_id is None
assert "resource_id" in m.model_fields_set
m = Model.construct(resource_id="foo")
+ assert m.resource_id == "foo"
assert "resource_id" in m.model_fields_set
@@ -832,7 +835,7 @@ class B(BaseModel):
@pytest.mark.skipif(not PYDANTIC_V2, reason="TypeAliasType is not supported in Pydantic v1")
def test_type_alias_type() -> None:
- Alias = TypeAliasType("Alias", str)
+ Alias = TypeAliasType("Alias", str) # pyright: ignore
class Model(BaseModel):
alias: Alias