diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 016de58f..7ec2e07d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -61,14 +61,18 @@ jobs: run: rye build - name: Get GitHub OIDC Token - if: github.repository == 'stainless-sdks/lithic-python' + if: |- + github.repository == 'stainless-sdks/lithic-python' && + !startsWith(github.ref, 'refs/heads/stl/') id: github-oidc uses: actions/github-script@v8 with: script: core.setOutput('github_token', await core.getIDToken()); - name: Upload tarball - if: github.repository == 'stainless-sdks/lithic-python' + if: |- + github.repository == 'stainless-sdks/lithic-python' && + !startsWith(github.ref, 'refs/heads/stl/') env: URL: https://pkg.stainless.com/s AUTH: ${{ steps.github-oidc.outputs.github_token }} diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b6700282..617f7502 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.117.0" + ".": "0.118.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index eba290a5..1259727d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 184 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-ee8607f0a2cdcaee420935050334a439db8dd097be83023fccdaf1d6f9a7de14.yml -openapi_spec_hash: 0f21c68cdddb7c5bd99f42356d507393 -config_hash: fb5070d41fcabdedbc084b83964b592a +configured_endpoints: 189 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-e88a4837037207e9591d48d534bd61acca57ca6e7c59ec0d4fdcf6e05288cc6d.yml +openapi_spec_hash: fd8bbc173d1b6dafd117fb1a3a3d446c +config_hash: 3005e2502301e77754e5e1455584525b diff --git a/CHANGELOG.md b/CHANGELOG.md index b82d9dc5..45ef6455 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,40 @@ # Changelog +## 0.118.0 (2026-03-16) + +Full Changelog: [v0.117.0...v0.118.0](https://github.com/lithic-com/lithic-python/compare/v0.117.0...v0.118.0) + +### Features + +* **api:** add ACH_RECEIPT_RELEASED_EARLY event type to payments ([5c64610](https://github.com/lithic-com/lithic-python/commit/5c64610e0a6306c4aa6138b0e5574368a1b539d1)) +* **api:** add EARLY_DIRECT_DEPOSIT_FLOAT type to financial accounts ([6b3cfd6](https://github.com/lithic-com/lithic-python/commit/6b3cfd6ac06980b80d110b19b20697068bbeeee9)) +* **api:** add event_subtype field to statement line items ([5545804](https://github.com/lithic-com/lithic-python/commit/5545804313ec283e1749d6bebf058b62c3b9ea28)) +* **api:** add excluded_account_tokens parameter to auth_rules v2 create/update ([9a13e1d](https://github.com/lithic-com/lithic-python/commit/9a13e1df3d7e6ec585304e9aac9735d5a821251c)) +* **api:** add loan_tape_date field to statement line items ([e4ff030](https://github.com/lithic-com/lithic-python/commit/e4ff03048937dc447d5ceba8ecfa3f804d880fd1)) +* **api:** add penalty_rates to interest tier schedule create ([224cb0c](https://github.com/lithic-com/lithic-python/commit/224cb0c851605095646d0ee649645e9227919948)) +* **api:** add typescript_code rule type, state/error fields to auth_rules ([f6dc800](https://github.com/lithic-com/lithic-python/commit/f6dc800f95e413c8a9436c5a966a2bb12d27b6b6)) +* **api:** add versions field to auth_rules DailyStatistic model ([5cce645](https://github.com/lithic-com/lithic-python/commit/5cce6456e5f26d05b456cb27ae2dc424a6172475)) +* **api:** add WIRE category, wire events, remove remittance_information from payment ([aa66507](https://github.com/lithic-com/lithic-python/commit/aa66507238f574018428f8e5e327eb4f22af67a4)) + + +### Bug Fixes + +* **api:** [breaking] unify webhook schemas for digital_wallet.tokenization_approval_request webhooks ([c6f0508](https://github.com/lithic-com/lithic-python/commit/c6f05085946c26c8d2a52bae6d25c25243674ec4)) +* **api:** Disable MCP server to fix TypeScript SDK package publishing ([f23d302](https://github.com/lithic-com/lithic-python/commit/f23d3022b0b0a860db16cefc008153f09c0bae48)) +* **types:** make start/end required, remove auth_rule_token in SimulationParameters ([96a4a8c](https://github.com/lithic-com/lithic-python/commit/96a4a8cb6107548b1404d5904ca72a0523f32a23)) + + +### Chores + +* **internal:** codegen related update ([845458d](https://github.com/lithic-com/lithic-python/commit/845458d17d741e51d1ef212fac9de9a9cbd8b0e5)) +* **internal:** regenerate SDK with no functional changes ([fc13bed](https://github.com/lithic-com/lithic-python/commit/fc13bedbd24a3c0b99ceb95b2f371906558325db)) + + +### Documentation + +* **api:** update disputes docstrings to use chargeback terminology ([0f35c28](https://github.com/lithic-com/lithic-python/commit/0f35c286c78528c332f4d82fa10ed88e014819b8)) +* **client:** add MCP Server setup documentation ([9f8d54b](https://github.com/lithic-com/lithic-python/commit/9f8d54b2b2c29e590f601635459d3ef20b092759)) + ## 0.117.0 (2026-03-05) Full Changelog: [v0.116.0...v0.117.0](https://github.com/lithic-com/lithic-python/compare/v0.116.0...v0.117.0) diff --git a/api.md b/api.md index e247a6e0..754f24b2 100644 --- a/api.md +++ b/api.md @@ -96,6 +96,7 @@ Types: from lithic.types.auth_rules import ( AuthRule, AuthRuleCondition, + AuthRuleVersion, BacktestStats, Conditional3DSActionParameters, ConditionalACHActionParameters, @@ -108,9 +109,13 @@ from lithic.types.auth_rules import ( EventStream, MerchantLockParameters, ReportStats, + RuleFeature, + TypescriptCodeParameters, + VelocityLimitFilters, VelocityLimitParams, VelocityLimitPeriod, V2ListResultsResponse, + V2ListVersionsResponse, V2RetrieveFeaturesResponse, V2RetrieveReportResponse, ) @@ -125,6 +130,7 @@ Methods: - client.auth_rules.v2.delete(auth_rule_token) -> None - client.auth_rules.v2.draft(auth_rule_token, \*\*params) -> AuthRule - client.auth_rules.v2.list_results(\*\*params) -> SyncCursorPage[V2ListResultsResponse] +- client.auth_rules.v2.list_versions(auth_rule_token) -> V2ListVersionsResponse - client.auth_rules.v2.promote(auth_rule_token) -> AuthRule - client.auth_rules.v2.retrieve_features(auth_rule_token, \*\*params) -> V2RetrieveFeaturesResponse - client.auth_rules.v2.retrieve_report(auth_rule_token, \*\*params) -> V2RetrieveReportResponse @@ -827,6 +833,21 @@ Methods: - client.network_programs.retrieve(network_program_token) -> NetworkProgram - client.network_programs.list(\*\*params) -> SyncSinglePage[NetworkProgram] +# Holds + +Types: + +```python +from lithic.types import Hold, HoldEvent +``` + +Methods: + +- client.holds.create(financial_account_token, \*\*params) -> Hold +- client.holds.retrieve(hold_token) -> Hold +- client.holds.list(financial_account_token, \*\*params) -> SyncCursorPage[Hold] +- client.holds.void(hold_token, \*\*params) -> Hold + # AccountActivity Types: @@ -867,7 +888,6 @@ from lithic.types import ( AccountHolderVerificationWebhookEvent, AccountHolderDocumentUpdatedWebhookEvent, CardAuthorizationApprovalRequestWebhookEvent, - TokenizationDecisioningRequestWebhookEvent, AuthRulesBacktestReportCreatedWebhookEvent, BalanceUpdatedWebhookEvent, BookTransferTransactionCreatedWebhookEvent, diff --git a/pyproject.toml b/pyproject.toml index 33fa6251..9df22bbb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "lithic" -version = "0.117.0" +version = "0.118.0" description = "The official Python library for the lithic API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/lithic/_client.py b/src/lithic/_client.py index 4f9fd51a..4a7a8a88 100644 --- a/src/lithic/_client.py +++ b/src/lithic/_client.py @@ -40,6 +40,7 @@ from .resources import ( cards, fraud, + holds, events, reports, accounts, @@ -69,6 +70,7 @@ external_bank_accounts, tokenization_decisioning, ) + from .resources.holds import Holds, AsyncHolds from .resources.accounts import Accounts, AsyncAccounts from .resources.balances import Balances, AsyncBalances from .resources.disputes import Disputes, AsyncDisputes @@ -374,6 +376,12 @@ def network_programs(self) -> NetworkPrograms: return NetworkPrograms(self) + @cached_property + def holds(self) -> Holds: + from .resources.holds import Holds + + return Holds(self) + @cached_property def account_activity(self) -> AccountActivity: from .resources.account_activity import AccountActivity @@ -783,6 +791,12 @@ def network_programs(self) -> AsyncNetworkPrograms: return AsyncNetworkPrograms(self) + @cached_property + def holds(self) -> AsyncHolds: + from .resources.holds import AsyncHolds + + return AsyncHolds(self) + @cached_property def account_activity(self) -> AsyncAccountActivity: from .resources.account_activity import AsyncAccountActivity @@ -1115,6 +1129,12 @@ def network_programs(self) -> network_programs.NetworkProgramsWithRawResponse: return NetworkProgramsWithRawResponse(self._client.network_programs) + @cached_property + def holds(self) -> holds.HoldsWithRawResponse: + from .resources.holds import HoldsWithRawResponse + + return HoldsWithRawResponse(self._client.holds) + @cached_property def account_activity(self) -> account_activity.AccountActivityWithRawResponse: from .resources.account_activity import AccountActivityWithRawResponse @@ -1306,6 +1326,12 @@ def network_programs(self) -> network_programs.AsyncNetworkProgramsWithRawRespon return AsyncNetworkProgramsWithRawResponse(self._client.network_programs) + @cached_property + def holds(self) -> holds.AsyncHoldsWithRawResponse: + from .resources.holds import AsyncHoldsWithRawResponse + + return AsyncHoldsWithRawResponse(self._client.holds) + @cached_property def account_activity(self) -> account_activity.AsyncAccountActivityWithRawResponse: from .resources.account_activity import AsyncAccountActivityWithRawResponse @@ -1497,6 +1523,12 @@ def network_programs(self) -> network_programs.NetworkProgramsWithStreamingRespo return NetworkProgramsWithStreamingResponse(self._client.network_programs) + @cached_property + def holds(self) -> holds.HoldsWithStreamingResponse: + from .resources.holds import HoldsWithStreamingResponse + + return HoldsWithStreamingResponse(self._client.holds) + @cached_property def account_activity(self) -> account_activity.AccountActivityWithStreamingResponse: from .resources.account_activity import AccountActivityWithStreamingResponse @@ -1688,6 +1720,12 @@ def network_programs(self) -> network_programs.AsyncNetworkProgramsWithStreaming return AsyncNetworkProgramsWithStreamingResponse(self._client.network_programs) + @cached_property + def holds(self) -> holds.AsyncHoldsWithStreamingResponse: + from .resources.holds import AsyncHoldsWithStreamingResponse + + return AsyncHoldsWithStreamingResponse(self._client.holds) + @cached_property def account_activity(self) -> account_activity.AsyncAccountActivityWithStreamingResponse: from .resources.account_activity import AsyncAccountActivityWithStreamingResponse diff --git a/src/lithic/_version.py b/src/lithic/_version.py index 39276f3d..86511f28 100644 --- a/src/lithic/_version.py +++ b/src/lithic/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "lithic" -__version__ = "0.117.0" # x-release-please-version +__version__ = "0.118.0" # x-release-please-version diff --git a/src/lithic/resources/__init__.py b/src/lithic/resources/__init__.py index 07be719f..47ee1966 100644 --- a/src/lithic/resources/__init__.py +++ b/src/lithic/resources/__init__.py @@ -16,6 +16,14 @@ FraudWithStreamingResponse, AsyncFraudWithStreamingResponse, ) +from .holds import ( + Holds, + AsyncHolds, + HoldsWithRawResponse, + AsyncHoldsWithRawResponse, + HoldsWithStreamingResponse, + AsyncHoldsWithStreamingResponse, +) from .events import ( Events, AsyncEvents, @@ -411,6 +419,12 @@ "AsyncNetworkProgramsWithRawResponse", "NetworkProgramsWithStreamingResponse", "AsyncNetworkProgramsWithStreamingResponse", + "Holds", + "AsyncHolds", + "HoldsWithRawResponse", + "AsyncHoldsWithRawResponse", + "HoldsWithStreamingResponse", + "AsyncHoldsWithStreamingResponse", "AccountActivity", "AsyncAccountActivity", "AccountActivityWithRawResponse", diff --git a/src/lithic/resources/account_activity.py b/src/lithic/resources/account_activity.py index c9cd0223..e9934587 100644 --- a/src/lithic/resources/account_activity.py +++ b/src/lithic/resources/account_activity.py @@ -51,6 +51,7 @@ def list( business_account_token: str | Omit = omit, category: Literal[ "ACH", + "WIRE", "BALANCE_OR_FUNDING", "FEE", "REWARD", @@ -69,6 +70,7 @@ def list( "MANAGEMENT_FEE", "MANAGEMENT_REWARD", "MANAGEMENT_DISBURSEMENT", + "HOLD", "PROGRAM_FUNDING", ] | Omit = omit, @@ -221,6 +223,7 @@ def list( business_account_token: str | Omit = omit, category: Literal[ "ACH", + "WIRE", "BALANCE_OR_FUNDING", "FEE", "REWARD", @@ -239,6 +242,7 @@ def list( "MANAGEMENT_FEE", "MANAGEMENT_REWARD", "MANAGEMENT_DISBURSEMENT", + "HOLD", "PROGRAM_FUNDING", ] | Omit = omit, diff --git a/src/lithic/resources/auth_rules/v2/v2.py b/src/lithic/resources/auth_rules/v2/v2.py index 59a7ad20..3c8039b7 100644 --- a/src/lithic/resources/auth_rules/v2/v2.py +++ b/src/lithic/resources/auth_rules/v2/v2.py @@ -37,6 +37,7 @@ from ....types.auth_rules.auth_rule import AuthRule from ....types.auth_rules.event_stream import EventStream from ....types.auth_rules.v2_list_results_response import V2ListResultsResponse +from ....types.auth_rules.v2_list_versions_response import V2ListVersionsResponse from ....types.auth_rules.v2_retrieve_report_response import V2RetrieveReportResponse from ....types.auth_rules.v2_retrieve_features_response import V2RetrieveFeaturesResponse @@ -72,7 +73,7 @@ def create( self, *, parameters: v2_create_params.AccountLevelRuleParameters, - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"], + type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"], account_tokens: SequenceNotStr[str] | Omit = omit, business_account_tokens: SequenceNotStr[str] | Omit = omit, event_stream: EventStream | Omit = omit, @@ -101,6 +102,8 @@ def create( - `MERCHANT_LOCK`: AUTHORIZATION event stream. - `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. + - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, + ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. account_tokens: Account tokens to which the Auth Rule applies. @@ -126,7 +129,7 @@ def create( *, card_tokens: SequenceNotStr[str], parameters: v2_create_params.CardLevelRuleParameters, - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"], + type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"], event_stream: EventStream | Omit = omit, name: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -155,6 +158,8 @@ def create( - `MERCHANT_LOCK`: AUTHORIZATION event stream. - `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. + - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, + ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. event_stream: The event stream during which the rule will be evaluated. @@ -176,8 +181,10 @@ def create( *, parameters: v2_create_params.ProgramLevelRuleParameters, program_level: bool, - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"], + type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"], event_stream: EventStream | Omit = omit, + excluded_account_tokens: SequenceNotStr[str] | Omit = omit, + excluded_business_account_tokens: SequenceNotStr[str] | Omit = omit, excluded_card_tokens: SequenceNotStr[str] | Omit = omit, name: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -206,9 +213,15 @@ def create( - `MERCHANT_LOCK`: AUTHORIZATION event stream. - `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. + - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, + ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. event_stream: The event stream during which the rule will be evaluated. + excluded_account_tokens: Account tokens to which the Auth Rule does not apply. + + excluded_business_account_tokens: Business account tokens to which the Auth Rule does not apply. + excluded_card_tokens: Card tokens to which the Auth Rule does not apply. name: Auth Rule Name @@ -232,13 +245,15 @@ def create( parameters: v2_create_params.AccountLevelRuleParameters | v2_create_params.CardLevelRuleParameters | v2_create_params.ProgramLevelRuleParameters, - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"], + type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"], account_tokens: SequenceNotStr[str] | Omit = omit, business_account_tokens: SequenceNotStr[str] | Omit = omit, event_stream: EventStream | Omit = omit, name: Optional[str] | Omit = omit, card_tokens: SequenceNotStr[str] | Omit = omit, program_level: bool | Omit = omit, + excluded_account_tokens: SequenceNotStr[str] | Omit = omit, + excluded_business_account_tokens: SequenceNotStr[str] | Omit = omit, excluded_card_tokens: SequenceNotStr[str] | Omit = omit, # 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. @@ -259,6 +274,8 @@ def create( "name": name, "card_tokens": card_tokens, "program_level": program_level, + "excluded_account_tokens": excluded_account_tokens, + "excluded_business_account_tokens": excluded_business_account_tokens, "excluded_card_tokens": excluded_card_tokens, }, v2_create_params.V2CreateParams, @@ -321,9 +338,9 @@ def update( """ Updates a V2 Auth rule's properties - If `account_tokens`, `card_tokens`, `program_level`, or `excluded_card_tokens` - is provided, this will replace existing associations with the provided list of - entities. + If `account_tokens`, `card_tokens`, `program_level`, `excluded_card_tokens`, + `excluded_account_tokens`, or `excluded_business_account_tokens` is provided, + this will replace existing associations with the provided list of entities. Args: account_tokens: Account tokens to which the Auth Rule applies. @@ -366,9 +383,9 @@ def update( """ Updates a V2 Auth rule's properties - If `account_tokens`, `card_tokens`, `program_level`, or `excluded_card_tokens` - is provided, this will replace existing associations with the provided list of - entities. + If `account_tokens`, `card_tokens`, `program_level`, `excluded_card_tokens`, + `excluded_account_tokens`, or `excluded_business_account_tokens` is provided, + this will replace existing associations with the provided list of entities. Args: card_tokens: Card tokens to which the Auth Rule applies. @@ -396,6 +413,8 @@ def update( self, auth_rule_token: str, *, + excluded_account_tokens: SequenceNotStr[str] | Omit = omit, + excluded_business_account_tokens: SequenceNotStr[str] | Omit = omit, excluded_card_tokens: SequenceNotStr[str] | Omit = omit, name: Optional[str] | Omit = omit, program_level: bool | Omit = omit, @@ -410,11 +429,15 @@ def update( """ Updates a V2 Auth rule's properties - If `account_tokens`, `card_tokens`, `program_level`, or `excluded_card_tokens` - is provided, this will replace existing associations with the provided list of - entities. + If `account_tokens`, `card_tokens`, `program_level`, `excluded_card_tokens`, + `excluded_account_tokens`, or `excluded_business_account_tokens` is provided, + this will replace existing associations with the provided list of entities. Args: + excluded_account_tokens: Account tokens to which the Auth Rule does not apply. + + excluded_business_account_tokens: Business account tokens to which the Auth Rule does not apply. + excluded_card_tokens: Card tokens to which the Auth Rule does not apply. name: Auth Rule Name @@ -446,6 +469,8 @@ def update( name: Optional[str] | Omit = omit, state: Literal["INACTIVE"] | Omit = omit, card_tokens: SequenceNotStr[str] | Omit = omit, + excluded_account_tokens: SequenceNotStr[str] | Omit = omit, + excluded_business_account_tokens: SequenceNotStr[str] | Omit = omit, excluded_card_tokens: SequenceNotStr[str] | Omit = omit, program_level: bool | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -466,6 +491,8 @@ def update( "name": name, "state": state, "card_tokens": card_tokens, + "excluded_account_tokens": excluded_account_tokens, + "excluded_business_account_tokens": excluded_business_account_tokens, "excluded_card_tokens": excluded_card_tokens, "program_level": program_level, }, @@ -712,6 +739,40 @@ def list_results( model=cast(Any, V2ListResultsResponse), # Union types cannot be passed in as arguments in the type system ) + def list_versions( + self, + auth_rule_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, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> V2ListVersionsResponse: + """ + Returns all versions of an auth rule, sorted by version number descending + (newest first). + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not auth_rule_token: + raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") + return self._get( + f"/v2/auth_rules/{auth_rule_token}/versions", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=V2ListVersionsResponse, + ) + def promote( self, auth_rule_token: str, @@ -890,7 +951,7 @@ async def create( self, *, parameters: v2_create_params.AccountLevelRuleParameters, - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"], + type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"], account_tokens: SequenceNotStr[str] | Omit = omit, business_account_tokens: SequenceNotStr[str] | Omit = omit, event_stream: EventStream | Omit = omit, @@ -919,6 +980,8 @@ async def create( - `MERCHANT_LOCK`: AUTHORIZATION event stream. - `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. + - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, + ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. account_tokens: Account tokens to which the Auth Rule applies. @@ -944,7 +1007,7 @@ async def create( *, card_tokens: SequenceNotStr[str], parameters: v2_create_params.CardLevelRuleParameters, - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"], + type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"], event_stream: EventStream | Omit = omit, name: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -973,6 +1036,8 @@ async def create( - `MERCHANT_LOCK`: AUTHORIZATION event stream. - `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. + - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, + ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. event_stream: The event stream during which the rule will be evaluated. @@ -994,8 +1059,10 @@ async def create( *, parameters: v2_create_params.ProgramLevelRuleParameters, program_level: bool, - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"], + type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"], event_stream: EventStream | Omit = omit, + excluded_account_tokens: SequenceNotStr[str] | Omit = omit, + excluded_business_account_tokens: SequenceNotStr[str] | Omit = omit, excluded_card_tokens: SequenceNotStr[str] | Omit = omit, name: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -1024,9 +1091,15 @@ async def create( - `MERCHANT_LOCK`: AUTHORIZATION event stream. - `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. + - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, + ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. event_stream: The event stream during which the rule will be evaluated. + excluded_account_tokens: Account tokens to which the Auth Rule does not apply. + + excluded_business_account_tokens: Business account tokens to which the Auth Rule does not apply. + excluded_card_tokens: Card tokens to which the Auth Rule does not apply. name: Auth Rule Name @@ -1050,13 +1123,15 @@ async def create( parameters: v2_create_params.AccountLevelRuleParameters | v2_create_params.CardLevelRuleParameters | v2_create_params.ProgramLevelRuleParameters, - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"], + type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"], account_tokens: SequenceNotStr[str] | Omit = omit, business_account_tokens: SequenceNotStr[str] | Omit = omit, event_stream: EventStream | Omit = omit, name: Optional[str] | Omit = omit, card_tokens: SequenceNotStr[str] | Omit = omit, program_level: bool | Omit = omit, + excluded_account_tokens: SequenceNotStr[str] | Omit = omit, + excluded_business_account_tokens: SequenceNotStr[str] | Omit = omit, excluded_card_tokens: SequenceNotStr[str] | Omit = omit, # 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. @@ -1077,6 +1152,8 @@ async def create( "name": name, "card_tokens": card_tokens, "program_level": program_level, + "excluded_account_tokens": excluded_account_tokens, + "excluded_business_account_tokens": excluded_business_account_tokens, "excluded_card_tokens": excluded_card_tokens, }, v2_create_params.V2CreateParams, @@ -1139,9 +1216,9 @@ async def update( """ Updates a V2 Auth rule's properties - If `account_tokens`, `card_tokens`, `program_level`, or `excluded_card_tokens` - is provided, this will replace existing associations with the provided list of - entities. + If `account_tokens`, `card_tokens`, `program_level`, `excluded_card_tokens`, + `excluded_account_tokens`, or `excluded_business_account_tokens` is provided, + this will replace existing associations with the provided list of entities. Args: account_tokens: Account tokens to which the Auth Rule applies. @@ -1184,9 +1261,9 @@ async def update( """ Updates a V2 Auth rule's properties - If `account_tokens`, `card_tokens`, `program_level`, or `excluded_card_tokens` - is provided, this will replace existing associations with the provided list of - entities. + If `account_tokens`, `card_tokens`, `program_level`, `excluded_card_tokens`, + `excluded_account_tokens`, or `excluded_business_account_tokens` is provided, + this will replace existing associations with the provided list of entities. Args: card_tokens: Card tokens to which the Auth Rule applies. @@ -1214,6 +1291,8 @@ async def update( self, auth_rule_token: str, *, + excluded_account_tokens: SequenceNotStr[str] | Omit = omit, + excluded_business_account_tokens: SequenceNotStr[str] | Omit = omit, excluded_card_tokens: SequenceNotStr[str] | Omit = omit, name: Optional[str] | Omit = omit, program_level: bool | Omit = omit, @@ -1228,11 +1307,15 @@ async def update( """ Updates a V2 Auth rule's properties - If `account_tokens`, `card_tokens`, `program_level`, or `excluded_card_tokens` - is provided, this will replace existing associations with the provided list of - entities. + If `account_tokens`, `card_tokens`, `program_level`, `excluded_card_tokens`, + `excluded_account_tokens`, or `excluded_business_account_tokens` is provided, + this will replace existing associations with the provided list of entities. Args: + excluded_account_tokens: Account tokens to which the Auth Rule does not apply. + + excluded_business_account_tokens: Business account tokens to which the Auth Rule does not apply. + excluded_card_tokens: Card tokens to which the Auth Rule does not apply. name: Auth Rule Name @@ -1264,6 +1347,8 @@ async def update( name: Optional[str] | Omit = omit, state: Literal["INACTIVE"] | Omit = omit, card_tokens: SequenceNotStr[str] | Omit = omit, + excluded_account_tokens: SequenceNotStr[str] | Omit = omit, + excluded_business_account_tokens: SequenceNotStr[str] | Omit = omit, excluded_card_tokens: SequenceNotStr[str] | Omit = omit, program_level: bool | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -1284,6 +1369,8 @@ async def update( "name": name, "state": state, "card_tokens": card_tokens, + "excluded_account_tokens": excluded_account_tokens, + "excluded_business_account_tokens": excluded_business_account_tokens, "excluded_card_tokens": excluded_card_tokens, "program_level": program_level, }, @@ -1530,6 +1617,40 @@ def list_results( model=cast(Any, V2ListResultsResponse), # Union types cannot be passed in as arguments in the type system ) + async def list_versions( + self, + auth_rule_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, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> V2ListVersionsResponse: + """ + Returns all versions of an auth rule, sorted by version number descending + (newest first). + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not auth_rule_token: + raise ValueError(f"Expected a non-empty value for `auth_rule_token` but received {auth_rule_token!r}") + return await self._get( + f"/v2/auth_rules/{auth_rule_token}/versions", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=V2ListVersionsResponse, + ) + async def promote( self, auth_rule_token: str, @@ -1704,6 +1825,9 @@ def __init__(self, v2: V2) -> None: self.list_results = _legacy_response.to_raw_response_wrapper( v2.list_results, ) + self.list_versions = _legacy_response.to_raw_response_wrapper( + v2.list_versions, + ) self.promote = _legacy_response.to_raw_response_wrapper( v2.promote, ) @@ -1744,6 +1868,9 @@ def __init__(self, v2: AsyncV2) -> None: self.list_results = _legacy_response.async_to_raw_response_wrapper( v2.list_results, ) + self.list_versions = _legacy_response.async_to_raw_response_wrapper( + v2.list_versions, + ) self.promote = _legacy_response.async_to_raw_response_wrapper( v2.promote, ) @@ -1784,6 +1911,9 @@ def __init__(self, v2: V2) -> None: self.list_results = to_streamed_response_wrapper( v2.list_results, ) + self.list_versions = to_streamed_response_wrapper( + v2.list_versions, + ) self.promote = to_streamed_response_wrapper( v2.promote, ) @@ -1824,6 +1954,9 @@ def __init__(self, v2: AsyncV2) -> None: self.list_results = async_to_streamed_response_wrapper( v2.list_results, ) + self.list_versions = async_to_streamed_response_wrapper( + v2.list_versions, + ) self.promote = async_to_streamed_response_wrapper( v2.promote, ) diff --git a/src/lithic/resources/disputes.py b/src/lithic/resources/disputes.py index a6a50705..6369b647 100644 --- a/src/lithic/resources/disputes.py +++ b/src/lithic/resources/disputes.py @@ -80,18 +80,18 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Dispute: """ - Initiate a dispute. + Request a chargeback. Args: - amount: Amount to dispute + amount: Amount for chargeback - reason: Reason for dispute + reason: Reason for chargeback - transaction_token: Transaction to dispute + transaction_token: Transaction for chargeback - customer_filed_date: Date the customer filed the dispute + customer_filed_date: Date the customer filed the chargeback request - customer_note: Customer description of dispute + customer_note: Customer description extra_headers: Send extra headers @@ -131,7 +131,7 @@ def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Dispute: """ - Get dispute. + Get chargeback request. Args: extra_headers: Send extra headers @@ -183,18 +183,18 @@ def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Dispute: - """Update dispute. + """Update chargeback request. Can only be modified if status is `NEW`. Args: - amount: Amount to dispute + amount: Amount for chargeback - customer_filed_date: Date the customer filed the dispute + customer_filed_date: Date the customer filed the chargeback request - customer_note: Customer description of dispute + customer_note: Customer description - reason: Reason for dispute + reason: Reason for chargeback extra_headers: Send extra headers @@ -250,7 +250,7 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncCursorPage[Dispute]: - """List disputes. + """List chargeback requests. Args: begin: Date string in RFC 3339 format. @@ -269,7 +269,7 @@ def list( starting_after: A cursor representing an item's token after which a page of results should begin. Used to retrieve the next page of results after this item. - status: List disputes of a specific status. + status: Filter by status. transaction_tokens: Transaction tokens to filter by. @@ -317,7 +317,7 @@ def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Dispute: """ - Withdraw dispute. + Withdraw chargeback request. Args: extra_headers: Send extra headers @@ -350,10 +350,10 @@ def delete_evidence( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DisputeEvidence: - """Soft delete evidence for a dispute. + """Soft delete evidence for a chargeback request. - Evidence will not be reviewed or submitted - by Lithic after it is withdrawn. + Evidence will not be reviewed or + submitted by Lithic after it is withdrawn. Args: extra_headers: Send extra headers @@ -388,10 +388,10 @@ def initiate_evidence_upload( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DisputeEvidence: - """Use this endpoint to upload evidences for the dispute. + """Use this endpoint to upload evidence for a chargeback request. - It will return a URL to - upload your documents to. The URL will expire in 30 minutes. + It will return a + URL to upload your documents to. The URL will expire in 30 minutes. Uploaded documents must either be a `jpg`, `png` or `pdf` file, and each must be less than 5 GiB. @@ -437,7 +437,7 @@ def list_evidences( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncCursorPage[DisputeEvidence]: """ - List evidence metadata for a dispute. + List evidence for a chargeback request. Args: begin: Date string in RFC 3339 format. Only entries created after the specified time @@ -499,7 +499,7 @@ def retrieve_evidence( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DisputeEvidence: """ - Get a dispute's evidence metadata. + Get evidence for a chargeback request. Args: extra_headers: Send extra headers @@ -596,18 +596,18 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Dispute: """ - Initiate a dispute. + Request a chargeback. Args: - amount: Amount to dispute + amount: Amount for chargeback - reason: Reason for dispute + reason: Reason for chargeback - transaction_token: Transaction to dispute + transaction_token: Transaction for chargeback - customer_filed_date: Date the customer filed the dispute + customer_filed_date: Date the customer filed the chargeback request - customer_note: Customer description of dispute + customer_note: Customer description extra_headers: Send extra headers @@ -647,7 +647,7 @@ async def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Dispute: """ - Get dispute. + Get chargeback request. Args: extra_headers: Send extra headers @@ -699,18 +699,18 @@ async def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Dispute: - """Update dispute. + """Update chargeback request. Can only be modified if status is `NEW`. Args: - amount: Amount to dispute + amount: Amount for chargeback - customer_filed_date: Date the customer filed the dispute + customer_filed_date: Date the customer filed the chargeback request - customer_note: Customer description of dispute + customer_note: Customer description - reason: Reason for dispute + reason: Reason for chargeback extra_headers: Send extra headers @@ -766,7 +766,7 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[Dispute, AsyncCursorPage[Dispute]]: - """List disputes. + """List chargeback requests. Args: begin: Date string in RFC 3339 format. @@ -785,7 +785,7 @@ def list( starting_after: A cursor representing an item's token after which a page of results should begin. Used to retrieve the next page of results after this item. - status: List disputes of a specific status. + status: Filter by status. transaction_tokens: Transaction tokens to filter by. @@ -833,7 +833,7 @@ async def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Dispute: """ - Withdraw dispute. + Withdraw chargeback request. Args: extra_headers: Send extra headers @@ -866,10 +866,10 @@ async def delete_evidence( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DisputeEvidence: - """Soft delete evidence for a dispute. + """Soft delete evidence for a chargeback request. - Evidence will not be reviewed or submitted - by Lithic after it is withdrawn. + Evidence will not be reviewed or + submitted by Lithic after it is withdrawn. Args: extra_headers: Send extra headers @@ -904,10 +904,10 @@ async def initiate_evidence_upload( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DisputeEvidence: - """Use this endpoint to upload evidences for the dispute. + """Use this endpoint to upload evidence for a chargeback request. - It will return a URL to - upload your documents to. The URL will expire in 30 minutes. + It will return a + URL to upload your documents to. The URL will expire in 30 minutes. Uploaded documents must either be a `jpg`, `png` or `pdf` file, and each must be less than 5 GiB. @@ -953,7 +953,7 @@ def list_evidences( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[DisputeEvidence, AsyncCursorPage[DisputeEvidence]]: """ - List evidence metadata for a dispute. + List evidence for a chargeback request. Args: begin: Date string in RFC 3339 format. Only entries created after the specified time @@ -1015,7 +1015,7 @@ async def retrieve_evidence( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DisputeEvidence: """ - Get a dispute's evidence metadata. + Get evidence for a chargeback request. Args: extra_headers: Send extra headers diff --git a/src/lithic/resources/events/events.py b/src/lithic/resources/events/events.py index b0dd5337..6583c851 100644 --- a/src/lithic/resources/events/events.py +++ b/src/lithic/resources/events/events.py @@ -125,7 +125,6 @@ def list( "card.renewed", "card.shipped", "card.updated", - "digital_wallet.tokenization_approval_request", "digital_wallet.tokenization_result", "digital_wallet.tokenization_two_factor_authentication_code", "digital_wallet.tokenization_two_factor_authentication_code_sent", @@ -400,7 +399,6 @@ def list( "card.renewed", "card.shipped", "card.updated", - "digital_wallet.tokenization_approval_request", "digital_wallet.tokenization_result", "digital_wallet.tokenization_two_factor_authentication_code", "digital_wallet.tokenization_two_factor_authentication_code_sent", diff --git a/src/lithic/resources/events/subscriptions.py b/src/lithic/resources/events/subscriptions.py index 66a24c75..5e3f385f 100644 --- a/src/lithic/resources/events/subscriptions.py +++ b/src/lithic/resources/events/subscriptions.py @@ -77,7 +77,6 @@ def create( "card.renewed", "card.shipped", "card.updated", - "digital_wallet.tokenization_approval_request", "digital_wallet.tokenization_result", "digital_wallet.tokenization_two_factor_authentication_code", "digital_wallet.tokenization_two_factor_authentication_code_sent", @@ -222,7 +221,6 @@ def update( "card.renewed", "card.shipped", "card.updated", - "digital_wallet.tokenization_approval_request", "digital_wallet.tokenization_result", "digital_wallet.tokenization_two_factor_authentication_code", "digital_wallet.tokenization_two_factor_authentication_code_sent", @@ -673,7 +671,6 @@ def send_simulated_example( "card.renewed", "card.shipped", "card.updated", - "digital_wallet.tokenization_approval_request", "digital_wallet.tokenization_result", "digital_wallet.tokenization_two_factor_authentication_code", "digital_wallet.tokenization_two_factor_authentication_code_sent", @@ -794,7 +791,6 @@ async def create( "card.renewed", "card.shipped", "card.updated", - "digital_wallet.tokenization_approval_request", "digital_wallet.tokenization_result", "digital_wallet.tokenization_two_factor_authentication_code", "digital_wallet.tokenization_two_factor_authentication_code_sent", @@ -939,7 +935,6 @@ async def update( "card.renewed", "card.shipped", "card.updated", - "digital_wallet.tokenization_approval_request", "digital_wallet.tokenization_result", "digital_wallet.tokenization_two_factor_authentication_code", "digital_wallet.tokenization_two_factor_authentication_code_sent", @@ -1390,7 +1385,6 @@ async def send_simulated_example( "card.renewed", "card.shipped", "card.updated", - "digital_wallet.tokenization_approval_request", "digital_wallet.tokenization_result", "digital_wallet.tokenization_two_factor_authentication_code", "digital_wallet.tokenization_two_factor_authentication_code_sent", diff --git a/src/lithic/resources/financial_accounts/financial_accounts.py b/src/lithic/resources/financial_accounts/financial_accounts.py index e26c023c..3c42d154 100644 --- a/src/lithic/resources/financial_accounts/financial_accounts.py +++ b/src/lithic/resources/financial_accounts/financial_accounts.py @@ -251,7 +251,7 @@ def list( *, account_token: str | Omit = omit, business_account_token: str | Omit = omit, - type: Literal["ISSUING", "OPERATING", "RESERVE", "SECURITY"] | Omit = omit, + type: Literal["ISSUING", "OPERATING", "RESERVE", "SECURITY", "EARLY_DIRECT_DEPOSIT_FLOAT"] | Omit = omit, # 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, @@ -569,7 +569,7 @@ def list( *, account_token: str | Omit = omit, business_account_token: str | Omit = omit, - type: Literal["ISSUING", "OPERATING", "RESERVE", "SECURITY"] | Omit = omit, + type: Literal["ISSUING", "OPERATING", "RESERVE", "SECURITY", "EARLY_DIRECT_DEPOSIT_FLOAT"] | Omit = omit, # 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, diff --git a/src/lithic/resources/financial_accounts/interest_tier_schedule.py b/src/lithic/resources/financial_accounts/interest_tier_schedule.py index 55f13682..6dae7a88 100644 --- a/src/lithic/resources/financial_accounts/interest_tier_schedule.py +++ b/src/lithic/resources/financial_accounts/interest_tier_schedule.py @@ -51,6 +51,7 @@ def create( *, credit_product_token: str, effective_date: Union[str, date], + penalty_rates: object | Omit = omit, tier_name: str | Omit = omit, tier_rates: object | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -68,6 +69,8 @@ def create( effective_date: Date the tier should be effective in YYYY-MM-DD format + penalty_rates: Custom rates per category for penalties + tier_name: Name of a tier contained in the credit product. Mutually exclusive with tier_rates @@ -91,6 +94,7 @@ def create( { "credit_product_token": credit_product_token, "effective_date": effective_date, + "penalty_rates": penalty_rates, "tier_name": tier_name, "tier_rates": tier_rates, }, @@ -145,6 +149,7 @@ def update( effective_date: Union[str, date], *, financial_account_token: str, + penalty_rates: object | Omit = omit, tier_name: str | Omit = omit, tier_rates: object | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -158,6 +163,8 @@ def update( Update an existing interest tier schedule Args: + penalty_rates: Custom rates per category for penalties + tier_name: Name of a tier contained in the credit product. Mutually exclusive with tier_rates @@ -181,6 +188,7 @@ def update( f"/v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}", body=maybe_transform( { + "penalty_rates": penalty_rates, "tier_name": tier_name, "tier_rates": tier_rates, }, @@ -337,6 +345,7 @@ async def create( *, credit_product_token: str, effective_date: Union[str, date], + penalty_rates: object | Omit = omit, tier_name: str | Omit = omit, tier_rates: object | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -354,6 +363,8 @@ async def create( effective_date: Date the tier should be effective in YYYY-MM-DD format + penalty_rates: Custom rates per category for penalties + tier_name: Name of a tier contained in the credit product. Mutually exclusive with tier_rates @@ -377,6 +388,7 @@ async def create( { "credit_product_token": credit_product_token, "effective_date": effective_date, + "penalty_rates": penalty_rates, "tier_name": tier_name, "tier_rates": tier_rates, }, @@ -431,6 +443,7 @@ async def update( effective_date: Union[str, date], *, financial_account_token: str, + penalty_rates: object | Omit = omit, tier_name: str | Omit = omit, tier_rates: object | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -444,6 +457,8 @@ async def update( Update an existing interest tier schedule Args: + penalty_rates: Custom rates per category for penalties + tier_name: Name of a tier contained in the credit product. Mutually exclusive with tier_rates @@ -467,6 +482,7 @@ async def update( f"/v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}", body=await async_maybe_transform( { + "penalty_rates": penalty_rates, "tier_name": tier_name, "tier_rates": tier_rates, }, diff --git a/src/lithic/resources/holds.py b/src/lithic/resources/holds.py new file mode 100644 index 00000000..45d6c4ae --- /dev/null +++ b/src/lithic/resources/holds.py @@ -0,0 +1,550 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union, Optional +from datetime import datetime +from typing_extensions import Literal + +import httpx + +from .. import _legacy_response +from ..types import hold_list_params, hold_void_params, hold_create_params +from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from .._utils import maybe_transform, async_maybe_transform +from .._compat import cached_property +from .._resource import SyncAPIResource, AsyncAPIResource +from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper +from ..pagination import SyncCursorPage, AsyncCursorPage +from ..types.hold import Hold +from .._base_client import AsyncPaginator, make_request_options + +__all__ = ["Holds", "AsyncHolds"] + + +class Holds(SyncAPIResource): + @cached_property + def with_raw_response(self) -> HoldsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/lithic-com/lithic-python#accessing-raw-response-data-eg-headers + """ + return HoldsWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> HoldsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/lithic-com/lithic-python#with_streaming_response + """ + return HoldsWithStreamingResponse(self) + + def create( + self, + financial_account_token: str, + *, + amount: int, + token: str | Omit = omit, + expiration_datetime: Union[str, datetime] | Omit = omit, + memo: Optional[str] | Omit = omit, + user_defined_id: str | Omit = omit, + # 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, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Hold: + """Create a hold on a financial account. + + Holds reserve funds by moving them from + available to pending balance. They can be resolved via settlement (linked to a + payment or book transfer), voiding, or expiration. + + Args: + amount: Amount to hold in cents + + token: Customer-provided token for idempotency. Becomes the hold token. + + expiration_datetime: When the hold should auto-expire + + memo: Reason for the hold + + user_defined_id: User-provided identifier for the hold + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not financial_account_token: + raise ValueError( + f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" + ) + return self._post( + f"/v1/financial_accounts/{financial_account_token}/holds", + body=maybe_transform( + { + "amount": amount, + "token": token, + "expiration_datetime": expiration_datetime, + "memo": memo, + "user_defined_id": user_defined_id, + }, + hold_create_params.HoldCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Hold, + ) + + def retrieve( + self, + hold_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, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Hold: + """ + Get hold by token. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not hold_token: + raise ValueError(f"Expected a non-empty value for `hold_token` but received {hold_token!r}") + return self._get( + f"/v1/holds/{hold_token}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Hold, + ) + + def list( + self, + financial_account_token: str, + *, + begin: Union[str, datetime] | Omit = omit, + end: Union[str, datetime] | Omit = omit, + ending_before: str | Omit = omit, + page_size: int | Omit = omit, + starting_after: str | Omit = omit, + status: Literal["PENDING", "SETTLED", "EXPIRED", "VOIDED"] | Omit = omit, + # 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, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncCursorPage[Hold]: + """ + List holds for a financial account. + + Args: + begin: Date string in RFC 3339 format. Only entries created after the specified time + will be included. UTC time zone. + + end: Date string in RFC 3339 format. Only entries created before the specified time + will be included. UTC time zone. + + ending_before: A cursor representing an item's token before which a page of results should end. + Used to retrieve the previous page of results before this item. + + page_size: Page size (for pagination). + + starting_after: A cursor representing an item's token after which a page of results should + begin. Used to retrieve the next page of results after this item. + + status: Hold status to filter by. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not financial_account_token: + raise ValueError( + f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" + ) + return self._get_api_list( + f"/v1/financial_accounts/{financial_account_token}/holds", + page=SyncCursorPage[Hold], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "begin": begin, + "end": end, + "ending_before": ending_before, + "page_size": page_size, + "starting_after": starting_after, + "status": status, + }, + hold_list_params.HoldListParams, + ), + ), + model=Hold, + ) + + def void( + self, + hold_token: str, + *, + memo: Optional[str] | Omit = omit, + # 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, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Hold: + """Void an active hold. + + This returns the held funds from pending back to available + balance. Only holds in PENDING status can be voided. + + Args: + memo: Reason for voiding the hold + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not hold_token: + raise ValueError(f"Expected a non-empty value for `hold_token` but received {hold_token!r}") + return self._post( + f"/v1/holds/{hold_token}/void", + body=maybe_transform({"memo": memo}, hold_void_params.HoldVoidParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Hold, + ) + + +class AsyncHolds(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncHoldsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/lithic-com/lithic-python#accessing-raw-response-data-eg-headers + """ + return AsyncHoldsWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncHoldsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/lithic-com/lithic-python#with_streaming_response + """ + return AsyncHoldsWithStreamingResponse(self) + + async def create( + self, + financial_account_token: str, + *, + amount: int, + token: str | Omit = omit, + expiration_datetime: Union[str, datetime] | Omit = omit, + memo: Optional[str] | Omit = omit, + user_defined_id: str | Omit = omit, + # 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, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Hold: + """Create a hold on a financial account. + + Holds reserve funds by moving them from + available to pending balance. They can be resolved via settlement (linked to a + payment or book transfer), voiding, or expiration. + + Args: + amount: Amount to hold in cents + + token: Customer-provided token for idempotency. Becomes the hold token. + + expiration_datetime: When the hold should auto-expire + + memo: Reason for the hold + + user_defined_id: User-provided identifier for the hold + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not financial_account_token: + raise ValueError( + f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" + ) + return await self._post( + f"/v1/financial_accounts/{financial_account_token}/holds", + body=await async_maybe_transform( + { + "amount": amount, + "token": token, + "expiration_datetime": expiration_datetime, + "memo": memo, + "user_defined_id": user_defined_id, + }, + hold_create_params.HoldCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Hold, + ) + + async def retrieve( + self, + hold_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, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Hold: + """ + Get hold by token. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not hold_token: + raise ValueError(f"Expected a non-empty value for `hold_token` but received {hold_token!r}") + return await self._get( + f"/v1/holds/{hold_token}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Hold, + ) + + def list( + self, + financial_account_token: str, + *, + begin: Union[str, datetime] | Omit = omit, + end: Union[str, datetime] | Omit = omit, + ending_before: str | Omit = omit, + page_size: int | Omit = omit, + starting_after: str | Omit = omit, + status: Literal["PENDING", "SETTLED", "EXPIRED", "VOIDED"] | Omit = omit, + # 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, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[Hold, AsyncCursorPage[Hold]]: + """ + List holds for a financial account. + + Args: + begin: Date string in RFC 3339 format. Only entries created after the specified time + will be included. UTC time zone. + + end: Date string in RFC 3339 format. Only entries created before the specified time + will be included. UTC time zone. + + ending_before: A cursor representing an item's token before which a page of results should end. + Used to retrieve the previous page of results before this item. + + page_size: Page size (for pagination). + + starting_after: A cursor representing an item's token after which a page of results should + begin. Used to retrieve the next page of results after this item. + + status: Hold status to filter by. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not financial_account_token: + raise ValueError( + f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" + ) + return self._get_api_list( + f"/v1/financial_accounts/{financial_account_token}/holds", + page=AsyncCursorPage[Hold], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "begin": begin, + "end": end, + "ending_before": ending_before, + "page_size": page_size, + "starting_after": starting_after, + "status": status, + }, + hold_list_params.HoldListParams, + ), + ), + model=Hold, + ) + + async def void( + self, + hold_token: str, + *, + memo: Optional[str] | Omit = omit, + # 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, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Hold: + """Void an active hold. + + This returns the held funds from pending back to available + balance. Only holds in PENDING status can be voided. + + Args: + memo: Reason for voiding the hold + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not hold_token: + raise ValueError(f"Expected a non-empty value for `hold_token` but received {hold_token!r}") + return await self._post( + f"/v1/holds/{hold_token}/void", + body=await async_maybe_transform({"memo": memo}, hold_void_params.HoldVoidParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Hold, + ) + + +class HoldsWithRawResponse: + def __init__(self, holds: Holds) -> None: + self._holds = holds + + self.create = _legacy_response.to_raw_response_wrapper( + holds.create, + ) + self.retrieve = _legacy_response.to_raw_response_wrapper( + holds.retrieve, + ) + self.list = _legacy_response.to_raw_response_wrapper( + holds.list, + ) + self.void = _legacy_response.to_raw_response_wrapper( + holds.void, + ) + + +class AsyncHoldsWithRawResponse: + def __init__(self, holds: AsyncHolds) -> None: + self._holds = holds + + self.create = _legacy_response.async_to_raw_response_wrapper( + holds.create, + ) + self.retrieve = _legacy_response.async_to_raw_response_wrapper( + holds.retrieve, + ) + self.list = _legacy_response.async_to_raw_response_wrapper( + holds.list, + ) + self.void = _legacy_response.async_to_raw_response_wrapper( + holds.void, + ) + + +class HoldsWithStreamingResponse: + def __init__(self, holds: Holds) -> None: + self._holds = holds + + self.create = to_streamed_response_wrapper( + holds.create, + ) + self.retrieve = to_streamed_response_wrapper( + holds.retrieve, + ) + self.list = to_streamed_response_wrapper( + holds.list, + ) + self.void = to_streamed_response_wrapper( + holds.void, + ) + + +class AsyncHoldsWithStreamingResponse: + def __init__(self, holds: AsyncHolds) -> None: + self._holds = holds + + self.create = async_to_streamed_response_wrapper( + holds.create, + ) + self.retrieve = async_to_streamed_response_wrapper( + holds.retrieve, + ) + self.list = async_to_streamed_response_wrapper( + holds.list, + ) + self.void = async_to_streamed_response_wrapper( + holds.void, + ) diff --git a/src/lithic/resources/payments.py b/src/lithic/resources/payments.py index 9235899b..afca033b 100644 --- a/src/lithic/resources/payments.py +++ b/src/lithic/resources/payments.py @@ -345,6 +345,7 @@ def simulate_action( "ACH_ORIGINATION_SETTLED", "ACH_RECEIPT_SETTLED", "ACH_RECEIPT_RELEASED", + "ACH_RECEIPT_RELEASED_EARLY", "ACH_RETURN_INITIATED", "ACH_RETURN_PROCESSED", "ACH_RETURN_SETTLED", @@ -849,6 +850,7 @@ async def simulate_action( "ACH_ORIGINATION_SETTLED", "ACH_RECEIPT_SETTLED", "ACH_RECEIPT_RELEASED", + "ACH_RECEIPT_RELEASED_EARLY", "ACH_RETURN_INITIATED", "ACH_RETURN_PROCESSED", "ACH_RETURN_SETTLED", diff --git a/src/lithic/types/__init__.py b/src/lithic/types/__init__.py index 5532206f..a78b5f11 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 .hold import Hold as Hold from .event import Event as Event from .device import Device as Device from .shared import ( @@ -24,6 +25,7 @@ from .kyc_param import KYCParam as KYCParam from .api_status import APIStatus as APIStatus from .dispute_v2 import DisputeV2 as DisputeV2 +from .hold_event import HoldEvent as HoldEvent from .owner_type import OwnerType as OwnerType from .token_info import TokenInfo as TokenInfo from .transaction import Transaction as Transaction @@ -42,6 +44,8 @@ from .digital_card_art import DigitalCardArt as DigitalCardArt from .dispute_evidence import DisputeEvidence as DisputeEvidence from .external_payment import ExternalPayment as ExternalPayment +from .hold_list_params import HoldListParams as HoldListParams +from .hold_void_params import HoldVoidParams as HoldVoidParams from .kyc_exempt_param import KYCExemptParam as KYCExemptParam from .statement_totals import StatementTotals as StatementTotals from .card_embed_params import CardEmbedParams as CardEmbedParams @@ -57,6 +61,7 @@ from .card_create_params import CardCreateParams as CardCreateParams from .card_update_params import CardUpdateParams as CardUpdateParams from .event_subscription import EventSubscription as EventSubscription +from .hold_create_params import HoldCreateParams as HoldCreateParams from .provision_response import ProvisionResponse as ProvisionResponse from .wire_party_details import WirePartyDetails as WirePartyDetails from .account_list_params import AccountListParams as AccountListParams @@ -301,9 +306,6 @@ from .account_activity_retrieve_transaction_response import ( AccountActivityRetrieveTransactionResponse as AccountActivityRetrieveTransactionResponse, ) -from .tokenization_decisioning_request_webhook_event import ( - TokenizationDecisioningRequestWebhookEvent as TokenizationDecisioningRequestWebhookEvent, -) from .book_transfer_transaction_created_webhook_event import ( BookTransferTransactionCreatedWebhookEvent as BookTransferTransactionCreatedWebhookEvent, ) diff --git a/src/lithic/types/account_activity_list_params.py b/src/lithic/types/account_activity_list_params.py index 7b28515b..1edf4ab8 100644 --- a/src/lithic/types/account_activity_list_params.py +++ b/src/lithic/types/account_activity_list_params.py @@ -26,6 +26,7 @@ class AccountActivityListParams(TypedDict, total=False): category: Literal[ "ACH", + "WIRE", "BALANCE_OR_FUNDING", "FEE", "REWARD", @@ -44,6 +45,7 @@ class AccountActivityListParams(TypedDict, total=False): "MANAGEMENT_FEE", "MANAGEMENT_REWARD", "MANAGEMENT_DISBURSEMENT", + "HOLD", "PROGRAM_FUNDING", ] """Filter by transaction category""" diff --git a/src/lithic/types/account_activity_list_response.py b/src/lithic/types/account_activity_list_response.py index 33992124..77fff49b 100644 --- a/src/lithic/types/account_activity_list_response.py +++ b/src/lithic/types/account_activity_list_response.py @@ -4,6 +4,7 @@ from datetime import datetime from typing_extensions import Literal, Annotated, TypeAlias +from .hold import Hold from .._utils import PropertyInfo from .payment import Payment from .._models import BaseModel @@ -24,6 +25,7 @@ class FinancialTransaction(BaseModel): category: Literal[ "ACH", + "WIRE", "BALANCE_OR_FUNDING", "FEE", "REWARD", @@ -42,6 +44,7 @@ class FinancialTransaction(BaseModel): "MANAGEMENT_FEE", "MANAGEMENT_REWARD", "MANAGEMENT_DISBURSEMENT", + "HOLD", "PROGRAM_FUNDING", ] """Transaction category""" @@ -107,6 +110,7 @@ class CardTransaction(Transaction): Payment, ExternalPayment, ManagementOperationTransaction, + Hold, ], PropertyInfo(discriminator="family"), ] diff --git a/src/lithic/types/account_activity_retrieve_transaction_response.py b/src/lithic/types/account_activity_retrieve_transaction_response.py index 202fd3eb..ddb55e7d 100644 --- a/src/lithic/types/account_activity_retrieve_transaction_response.py +++ b/src/lithic/types/account_activity_retrieve_transaction_response.py @@ -4,6 +4,7 @@ from datetime import datetime from typing_extensions import Literal, Annotated, TypeAlias +from .hold import Hold from .._utils import PropertyInfo from .payment import Payment from .._models import BaseModel @@ -24,6 +25,7 @@ class FinancialTransaction(BaseModel): category: Literal[ "ACH", + "WIRE", "BALANCE_OR_FUNDING", "FEE", "REWARD", @@ -42,6 +44,7 @@ class FinancialTransaction(BaseModel): "MANAGEMENT_FEE", "MANAGEMENT_REWARD", "MANAGEMENT_DISBURSEMENT", + "HOLD", "PROGRAM_FUNDING", ] """Transaction category""" @@ -107,6 +110,7 @@ class CardTransaction(Transaction): Payment, ExternalPayment, ManagementOperationTransaction, + Hold, ], PropertyInfo(discriminator="family"), ] diff --git a/src/lithic/types/auth_rules/__init__.py b/src/lithic/types/auth_rules/__init__.py index a580f180..ccc86c5a 100644 --- a/src/lithic/types/auth_rules/__init__.py +++ b/src/lithic/types/auth_rules/__init__.py @@ -5,30 +5,38 @@ from .auth_rule import AuthRule as AuthRule from .event_stream import EventStream as EventStream from .report_stats import ReportStats as ReportStats +from .rule_feature import RuleFeature as RuleFeature from .backtest_stats import BacktestStats as BacktestStats from .v2_list_params import V2ListParams as V2ListParams from .v2_draft_params import V2DraftParams as V2DraftParams from .v2_create_params import V2CreateParams as V2CreateParams from .v2_update_params import V2UpdateParams as V2UpdateParams +from .auth_rule_version import AuthRuleVersion as AuthRuleVersion from .conditional_value import ConditionalValue as ConditionalValue +from .rule_feature_param import RuleFeatureParam as RuleFeatureParam from .auth_rule_condition import AuthRuleCondition as AuthRuleCondition from .conditional_attribute import ConditionalAttribute as ConditionalAttribute from .conditional_operation import ConditionalOperation as ConditionalOperation from .velocity_limit_params import VelocityLimitParams as VelocityLimitParams from .velocity_limit_period import VelocityLimitPeriod as VelocityLimitPeriod from .v2_list_results_params import V2ListResultsParams as V2ListResultsParams +from .velocity_limit_filters import VelocityLimitFilters as VelocityLimitFilters from .conditional_value_param import ConditionalValueParam as ConditionalValueParam from .merchant_lock_parameters import MerchantLockParameters as MerchantLockParameters from .v2_list_results_response import V2ListResultsResponse as V2ListResultsResponse from .auth_rule_condition_param import AuthRuleConditionParam as AuthRuleConditionParam +from .v2_list_versions_response import V2ListVersionsResponse as V2ListVersionsResponse from .v2_retrieve_report_params import V2RetrieveReportParams as V2RetrieveReportParams +from .typescript_code_parameters import TypescriptCodeParameters as TypescriptCodeParameters from .v2_retrieve_features_params import V2RetrieveFeaturesParams as V2RetrieveFeaturesParams from .v2_retrieve_report_response import V2RetrieveReportResponse as V2RetrieveReportResponse from .velocity_limit_params_param import VelocityLimitParamsParam as VelocityLimitParamsParam from .velocity_limit_period_param import VelocityLimitPeriodParam as VelocityLimitPeriodParam from .conditional_block_parameters import ConditionalBlockParameters as ConditionalBlockParameters +from .velocity_limit_filters_param import VelocityLimitFiltersParam as VelocityLimitFiltersParam from .v2_retrieve_features_response import V2RetrieveFeaturesResponse as V2RetrieveFeaturesResponse from .merchant_lock_parameters_param import MerchantLockParametersParam as MerchantLockParametersParam +from .typescript_code_parameters_param import TypescriptCodeParametersParam as TypescriptCodeParametersParam from .conditional_3ds_action_parameters import Conditional3DSActionParameters as Conditional3DSActionParameters from .conditional_ach_action_parameters import ConditionalACHActionParameters as ConditionalACHActionParameters from .conditional_block_parameters_param import ConditionalBlockParametersParam as ConditionalBlockParametersParam diff --git a/src/lithic/types/auth_rules/auth_rule.py b/src/lithic/types/auth_rules/auth_rule.py index 3708f7e1..74cabb08 100644 --- a/src/lithic/types/auth_rules/auth_rule.py +++ b/src/lithic/types/auth_rules/auth_rule.py @@ -7,6 +7,7 @@ from .event_stream import EventStream from .velocity_limit_params import VelocityLimitParams from .merchant_lock_parameters import MerchantLockParameters +from .typescript_code_parameters import TypescriptCodeParameters from .conditional_block_parameters import ConditionalBlockParameters from .conditional_3ds_action_parameters import Conditional3DSActionParameters from .conditional_ach_action_parameters import ConditionalACHActionParameters @@ -23,6 +24,7 @@ ConditionalAuthorizationActionParameters, ConditionalACHActionParameters, ConditionalTokenizationActionParameters, + TypescriptCodeParameters, ] @@ -45,13 +47,34 @@ class CurrentVersion(BaseModel): ConditionalAuthorizationActionParameters, ConditionalACHActionParameters, ConditionalTokenizationActionParameters, + TypescriptCodeParameters, ] class DraftVersion(BaseModel): + error: Optional[str] = None + """An error message if the draft version failed compilation. + + Populated when `state` is `ERROR`, `null` otherwise. + """ + parameters: DraftVersionParameters """Parameters for the Auth Rule""" + state: Literal["PENDING", "SHADOWING", "ERROR"] + """The state of the draft version. + + Most rules are created synchronously and the state is immediately `SHADOWING`. + Rules backed by TypeScript code are compiled asynchronously — the state starts + as `PENDING` and transitions to `SHADOWING` on success or `ERROR` on failure. + + - `PENDING`: Compilation of the rule is in progress (TypeScript rules only). + - `SHADOWING`: The draft version is ready and evaluating in shadow mode + alongside the current active version. It can be promoted to the active + version. + - `ERROR`: Compilation of the rule failed. Check the `error` field for details. + """ + version: int """ The version of the rule, this is incremented whenever the rule's parameters @@ -94,7 +117,7 @@ class AuthRule(BaseModel): state: Literal["ACTIVE", "INACTIVE"] """The state of the Auth Rule""" - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"] + type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"] """The type of Auth Rule. For certain rule types, this determines the event stream during which it will be @@ -107,7 +130,15 @@ class AuthRule(BaseModel): - `MERCHANT_LOCK`: AUTHORIZATION event stream. - `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. + - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, + ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. """ + excluded_account_tokens: Optional[List[str]] = None + """Account tokens to which the Auth Rule does not apply.""" + + excluded_business_account_tokens: Optional[List[str]] = None + """Business account tokens to which the Auth Rule does not apply.""" + excluded_card_tokens: Optional[List[str]] = None """Card tokens to which the Auth Rule does not apply.""" diff --git a/src/lithic/types/auth_rules/auth_rule_version.py b/src/lithic/types/auth_rules/auth_rule_version.py new file mode 100644 index 00000000..4dcbc321 --- /dev/null +++ b/src/lithic/types/auth_rules/auth_rule_version.py @@ -0,0 +1,45 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Union +from datetime import datetime +from typing_extensions import Literal, TypeAlias + +from ..._models import BaseModel +from .velocity_limit_params import VelocityLimitParams +from .merchant_lock_parameters import MerchantLockParameters +from .typescript_code_parameters import TypescriptCodeParameters +from .conditional_block_parameters import ConditionalBlockParameters +from .conditional_3ds_action_parameters import Conditional3DSActionParameters +from .conditional_ach_action_parameters import ConditionalACHActionParameters +from .conditional_tokenization_action_parameters import ConditionalTokenizationActionParameters +from .conditional_authorization_action_parameters import ConditionalAuthorizationActionParameters + +__all__ = ["AuthRuleVersion", "Parameters"] + +Parameters: TypeAlias = Union[ + ConditionalBlockParameters, + VelocityLimitParams, + MerchantLockParameters, + Conditional3DSActionParameters, + ConditionalAuthorizationActionParameters, + ConditionalACHActionParameters, + ConditionalTokenizationActionParameters, + TypescriptCodeParameters, +] + + +class AuthRuleVersion(BaseModel): + created: datetime + """Timestamp of when this version was created.""" + + parameters: Parameters + """Parameters for the Auth Rule""" + + state: Literal["ACTIVE", "SHADOW", "INACTIVE"] + """The current state of this version.""" + + version: int + """ + The version of the rule, this is incremented whenever the rule's parameters + change. + """ diff --git a/src/lithic/types/auth_rules/rule_feature.py b/src/lithic/types/auth_rules/rule_feature.py new file mode 100644 index 00000000..40fffc14 --- /dev/null +++ b/src/lithic/types/auth_rules/rule_feature.py @@ -0,0 +1,96 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Union, Optional +from typing_extensions import Literal, TypeAlias + +from ..._models import BaseModel +from .velocity_limit_period import VelocityLimitPeriod +from .velocity_limit_filters import VelocityLimitFilters + +__all__ = [ + "RuleFeature", + "AuthorizationFeature", + "AuthenticationFeature", + "TokenizationFeature", + "ACHReceiptFeature", + "CardFeature", + "AccountHolderFeature", + "IPMetadataFeature", + "SpendVelocityFeature", +] + + +class AuthorizationFeature(BaseModel): + type: Literal["AUTHORIZATION"] + + name: Optional[str] = None + """The variable name for this feature in the rule function signature""" + + +class AuthenticationFeature(BaseModel): + type: Literal["AUTHENTICATION"] + + name: Optional[str] = None + """The variable name for this feature in the rule function signature""" + + +class TokenizationFeature(BaseModel): + type: Literal["TOKENIZATION"] + + name: Optional[str] = None + """The variable name for this feature in the rule function signature""" + + +class ACHReceiptFeature(BaseModel): + type: Literal["ACH_RECEIPT"] + + name: Optional[str] = None + """The variable name for this feature in the rule function signature""" + + +class CardFeature(BaseModel): + type: Literal["CARD"] + + name: Optional[str] = None + """The variable name for this feature in the rule function signature""" + + +class AccountHolderFeature(BaseModel): + type: Literal["ACCOUNT_HOLDER"] + + name: Optional[str] = None + """The variable name for this feature in the rule function signature""" + + +class IPMetadataFeature(BaseModel): + type: Literal["IP_METADATA"] + + name: Optional[str] = None + """The variable name for this feature in the rule function signature""" + + +class SpendVelocityFeature(BaseModel): + period: VelocityLimitPeriod + """Velocity over the current day since 00:00 / 12 AM in Eastern Time""" + + scope: Literal["CARD", "ACCOUNT"] + """The scope the velocity is calculated for""" + + type: Literal["SPEND_VELOCITY"] + + filters: Optional[VelocityLimitFilters] = None + + name: Optional[str] = None + """The variable name for this feature in the rule function signature""" + + +RuleFeature: TypeAlias = Union[ + AuthorizationFeature, + AuthenticationFeature, + TokenizationFeature, + ACHReceiptFeature, + CardFeature, + AccountHolderFeature, + IPMetadataFeature, + SpendVelocityFeature, +] diff --git a/src/lithic/types/auth_rules/rule_feature_param.py b/src/lithic/types/auth_rules/rule_feature_param.py new file mode 100644 index 00000000..0d32b726 --- /dev/null +++ b/src/lithic/types/auth_rules/rule_feature_param.py @@ -0,0 +1,97 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from typing_extensions import Literal, Required, TypeAlias, TypedDict + +from .velocity_limit_period_param import VelocityLimitPeriodParam +from .velocity_limit_filters_param import VelocityLimitFiltersParam + +__all__ = [ + "RuleFeatureParam", + "AuthorizationFeature", + "AuthenticationFeature", + "TokenizationFeature", + "ACHReceiptFeature", + "CardFeature", + "AccountHolderFeature", + "IPMetadataFeature", + "SpendVelocityFeature", +] + + +class AuthorizationFeature(TypedDict, total=False): + type: Required[Literal["AUTHORIZATION"]] + + name: str + """The variable name for this feature in the rule function signature""" + + +class AuthenticationFeature(TypedDict, total=False): + type: Required[Literal["AUTHENTICATION"]] + + name: str + """The variable name for this feature in the rule function signature""" + + +class TokenizationFeature(TypedDict, total=False): + type: Required[Literal["TOKENIZATION"]] + + name: str + """The variable name for this feature in the rule function signature""" + + +class ACHReceiptFeature(TypedDict, total=False): + type: Required[Literal["ACH_RECEIPT"]] + + name: str + """The variable name for this feature in the rule function signature""" + + +class CardFeature(TypedDict, total=False): + type: Required[Literal["CARD"]] + + name: str + """The variable name for this feature in the rule function signature""" + + +class AccountHolderFeature(TypedDict, total=False): + type: Required[Literal["ACCOUNT_HOLDER"]] + + name: str + """The variable name for this feature in the rule function signature""" + + +class IPMetadataFeature(TypedDict, total=False): + type: Required[Literal["IP_METADATA"]] + + name: str + """The variable name for this feature in the rule function signature""" + + +class SpendVelocityFeature(TypedDict, total=False): + period: Required[VelocityLimitPeriodParam] + """Velocity over the current day since 00:00 / 12 AM in Eastern Time""" + + scope: Required[Literal["CARD", "ACCOUNT"]] + """The scope the velocity is calculated for""" + + type: Required[Literal["SPEND_VELOCITY"]] + + filters: VelocityLimitFiltersParam + + name: str + """The variable name for this feature in the rule function signature""" + + +RuleFeatureParam: TypeAlias = Union[ + AuthorizationFeature, + AuthenticationFeature, + TokenizationFeature, + ACHReceiptFeature, + CardFeature, + AccountHolderFeature, + IPMetadataFeature, + SpendVelocityFeature, +] diff --git a/src/lithic/types/auth_rules/typescript_code_parameters.py b/src/lithic/types/auth_rules/typescript_code_parameters.py new file mode 100644 index 00000000..d80a49db --- /dev/null +++ b/src/lithic/types/auth_rules/typescript_code_parameters.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ..._models import BaseModel +from .rule_feature import RuleFeature + +__all__ = ["TypescriptCodeParameters"] + + +class TypescriptCodeParameters(BaseModel): + """Parameters for defining a TypeScript code rule""" + + code: str + """The TypeScript source code of the rule. + + Must define a `rule()` function that accepts the declared features as positional + arguments (in the same order as the `features` array) and returns an array of + actions. + """ + + features: List[RuleFeature] + """Features available to the TypeScript code at evaluation time""" diff --git a/src/lithic/types/auth_rules/typescript_code_parameters_param.py b/src/lithic/types/auth_rules/typescript_code_parameters_param.py new file mode 100644 index 00000000..3871954d --- /dev/null +++ b/src/lithic/types/auth_rules/typescript_code_parameters_param.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Required, TypedDict + +from .rule_feature_param import RuleFeatureParam + +__all__ = ["TypescriptCodeParametersParam"] + + +class TypescriptCodeParametersParam(TypedDict, total=False): + """Parameters for defining a TypeScript code rule""" + + code: Required[str] + """The TypeScript source code of the rule. + + Must define a `rule()` function that accepts the declared features as positional + arguments (in the same order as the `features` array) and returns an array of + actions. + """ + + features: Required[Iterable[RuleFeatureParam]] + """Features available to the TypeScript code at evaluation time""" diff --git a/src/lithic/types/auth_rules/v2/backtest_results.py b/src/lithic/types/auth_rules/v2/backtest_results.py index 54314cc0..dc62b834 100644 --- a/src/lithic/types/auth_rules/v2/backtest_results.py +++ b/src/lithic/types/auth_rules/v2/backtest_results.py @@ -16,14 +16,11 @@ class Results(BaseModel): class SimulationParameters(BaseModel): - auth_rule_token: Optional[str] = None - """Auth Rule Token""" + end: datetime + """The end time of the simulation""" - end: Optional[datetime] = None - """The end time of the simulation.""" - - start: Optional[datetime] = None - """The start time of the simulation.""" + start: datetime + """The start time of the simulation""" class BacktestResults(BaseModel): diff --git a/src/lithic/types/auth_rules/v2_create_params.py b/src/lithic/types/auth_rules/v2_create_params.py index 2af4efd9..6c8c7fd8 100644 --- a/src/lithic/types/auth_rules/v2_create_params.py +++ b/src/lithic/types/auth_rules/v2_create_params.py @@ -9,6 +9,7 @@ from .event_stream import EventStream from .velocity_limit_params_param import VelocityLimitParamsParam from .merchant_lock_parameters_param import MerchantLockParametersParam +from .typescript_code_parameters_param import TypescriptCodeParametersParam from .conditional_block_parameters_param import ConditionalBlockParametersParam from .conditional_3ds_action_parameters_param import Conditional3DSActionParametersParam from .conditional_ach_action_parameters_param import ConditionalACHActionParametersParam @@ -30,7 +31,9 @@ class AccountLevelRule(TypedDict, total=False): parameters: Required[AccountLevelRuleParameters] """Parameters for the Auth Rule""" - type: Required[Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"]] + type: Required[ + Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"] + ] """The type of Auth Rule. For certain rule types, this determines the event stream during which it will be @@ -43,6 +46,8 @@ class AccountLevelRule(TypedDict, total=False): - `MERCHANT_LOCK`: AUTHORIZATION event stream. - `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. + - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, + ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. """ account_tokens: SequenceNotStr[str] @@ -66,6 +71,7 @@ class AccountLevelRule(TypedDict, total=False): ConditionalAuthorizationActionParametersParam, ConditionalACHActionParametersParam, ConditionalTokenizationActionParametersParam, + TypescriptCodeParametersParam, ] @@ -76,7 +82,9 @@ class CardLevelRule(TypedDict, total=False): parameters: Required[CardLevelRuleParameters] """Parameters for the Auth Rule""" - type: Required[Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"]] + type: Required[ + Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"] + ] """The type of Auth Rule. For certain rule types, this determines the event stream during which it will be @@ -89,6 +97,8 @@ class CardLevelRule(TypedDict, total=False): - `MERCHANT_LOCK`: AUTHORIZATION event stream. - `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. + - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, + ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. """ event_stream: EventStream @@ -106,6 +116,7 @@ class CardLevelRule(TypedDict, total=False): ConditionalAuthorizationActionParametersParam, ConditionalACHActionParametersParam, ConditionalTokenizationActionParametersParam, + TypescriptCodeParametersParam, ] @@ -116,7 +127,9 @@ class ProgramLevelRule(TypedDict, total=False): program_level: Required[bool] """Whether the Auth Rule applies to all authorizations on the card program.""" - type: Required[Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"]] + type: Required[ + Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"] + ] """The type of Auth Rule. For certain rule types, this determines the event stream during which it will be @@ -129,11 +142,19 @@ class ProgramLevelRule(TypedDict, total=False): - `MERCHANT_LOCK`: AUTHORIZATION event stream. - `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. + - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, + ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream. """ event_stream: EventStream """The event stream during which the rule will be evaluated.""" + excluded_account_tokens: SequenceNotStr[str] + """Account tokens to which the Auth Rule does not apply.""" + + excluded_business_account_tokens: SequenceNotStr[str] + """Business account tokens to which the Auth Rule does not apply.""" + excluded_card_tokens: SequenceNotStr[str] """Card tokens to which the Auth Rule does not apply.""" @@ -149,6 +170,7 @@ class ProgramLevelRule(TypedDict, total=False): ConditionalAuthorizationActionParametersParam, ConditionalACHActionParametersParam, ConditionalTokenizationActionParametersParam, + TypescriptCodeParametersParam, ] V2CreateParams: TypeAlias = Union[AccountLevelRule, CardLevelRule, ProgramLevelRule] diff --git a/src/lithic/types/auth_rules/v2_draft_params.py b/src/lithic/types/auth_rules/v2_draft_params.py index 2352a6b7..2b0d4363 100644 --- a/src/lithic/types/auth_rules/v2_draft_params.py +++ b/src/lithic/types/auth_rules/v2_draft_params.py @@ -7,6 +7,7 @@ from .velocity_limit_params_param import VelocityLimitParamsParam from .merchant_lock_parameters_param import MerchantLockParametersParam +from .typescript_code_parameters_param import TypescriptCodeParametersParam from .conditional_block_parameters_param import ConditionalBlockParametersParam from .conditional_3ds_action_parameters_param import Conditional3DSActionParametersParam from .conditional_ach_action_parameters_param import ConditionalACHActionParametersParam @@ -29,4 +30,5 @@ class V2DraftParams(TypedDict, total=False): ConditionalAuthorizationActionParametersParam, ConditionalACHActionParametersParam, ConditionalTokenizationActionParametersParam, + TypescriptCodeParametersParam, ] diff --git a/src/lithic/types/auth_rules/v2_list_versions_response.py b/src/lithic/types/auth_rules/v2_list_versions_response.py new file mode 100644 index 00000000..b6aeba34 --- /dev/null +++ b/src/lithic/types/auth_rules/v2_list_versions_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ..._models import BaseModel +from .auth_rule_version import AuthRuleVersion + +__all__ = ["V2ListVersionsResponse"] + + +class V2ListVersionsResponse(BaseModel): + data: List[AuthRuleVersion] diff --git a/src/lithic/types/auth_rules/v2_retrieve_features_response.py b/src/lithic/types/auth_rules/v2_retrieve_features_response.py index 708a3fdc..4bfe4037 100644 --- a/src/lithic/types/auth_rules/v2_retrieve_features_response.py +++ b/src/lithic/types/auth_rules/v2_retrieve_features_response.py @@ -1,69 +1,14 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import List from datetime import datetime from typing_extensions import Literal from ..._models import BaseModel from .velocity_limit_period import VelocityLimitPeriod +from .velocity_limit_filters import VelocityLimitFilters -__all__ = ["V2RetrieveFeaturesResponse", "Feature", "FeatureFilters", "FeatureValue"] - - -class FeatureFilters(BaseModel): - exclude_countries: Optional[List[str]] = None - """ISO-3166-1 alpha-3 Country Codes to exclude from the velocity calculation. - - Transactions matching any of the provided will be excluded from the calculated - velocity. - """ - - exclude_mccs: Optional[List[str]] = None - """Merchant Category Codes to exclude from the velocity calculation. - - Transactions matching this MCC will be excluded from the calculated velocity. - """ - - include_countries: Optional[List[str]] = None - """ISO-3166-1 alpha-3 Country Codes to include in the velocity calculation. - - Transactions not matching any of the provided will not be included in the - calculated velocity. - """ - - include_mccs: Optional[List[str]] = None - """Merchant Category Codes to include in the velocity calculation. - - Transactions not matching this MCC will not be included in the calculated - velocity. - """ - - include_pan_entry_modes: Optional[ - List[ - Literal[ - "AUTO_ENTRY", - "BAR_CODE", - "CONTACTLESS", - "CREDENTIAL_ON_FILE", - "ECOMMERCE", - "ERROR_KEYED", - "ERROR_MAGNETIC_STRIPE", - "ICC", - "KEY_ENTERED", - "MAGNETIC_STRIPE", - "MANUAL", - "OCR", - "SECURE_CARDLESS", - "UNSPECIFIED", - "UNKNOWN", - ] - ] - ] = None - """PAN entry modes to include in the velocity calculation. - - Transactions not matching any of the provided will not be included in the - calculated velocity. - """ +__all__ = ["V2RetrieveFeaturesResponse", "Feature", "FeatureValue"] class FeatureValue(BaseModel): @@ -82,7 +27,7 @@ class FeatureValue(BaseModel): class Feature(BaseModel): - filters: FeatureFilters + filters: VelocityLimitFilters period: VelocityLimitPeriod """Velocity over the current day since 00:00 / 12 AM in Eastern Time""" diff --git a/src/lithic/types/auth_rules/v2_retrieve_report_response.py b/src/lithic/types/auth_rules/v2_retrieve_report_response.py index 9545791e..6e4860ce 100644 --- a/src/lithic/types/auth_rules/v2_retrieve_report_response.py +++ b/src/lithic/types/auth_rules/v2_retrieve_report_response.py @@ -1,12 +1,278 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import datetime -from typing import List, Optional +from typing import Dict, List, Union, Optional +from typing_extensions import Literal, TypeAlias from ..._models import BaseModel from .report_stats import ReportStats -__all__ = ["V2RetrieveReportResponse", "DailyStatistic"] +__all__ = [ + "V2RetrieveReportResponse", + "DailyStatistic", + "DailyStatisticVersion", + "DailyStatisticVersionExample", + "DailyStatisticVersionExampleAction", + "DailyStatisticVersionExampleActionDeclineActionAuthorization", + "DailyStatisticVersionExampleActionChallengeActionAuthorization", + "DailyStatisticVersionExampleActionResultAuthentication3DSAction", + "DailyStatisticVersionExampleActionDeclineActionTokenization", + "DailyStatisticVersionExampleActionRequireTfaAction", + "DailyStatisticVersionExampleActionApproveActionACH", + "DailyStatisticVersionExampleActionReturnAction", +] + + +class DailyStatisticVersionExampleActionDeclineActionAuthorization(BaseModel): + code: Literal[ + "ACCOUNT_DAILY_SPEND_LIMIT_EXCEEDED", + "ACCOUNT_DELINQUENT", + "ACCOUNT_INACTIVE", + "ACCOUNT_LIFETIME_SPEND_LIMIT_EXCEEDED", + "ACCOUNT_MONTHLY_SPEND_LIMIT_EXCEEDED", + "ACCOUNT_PAUSED", + "ACCOUNT_UNDER_REVIEW", + "ADDRESS_INCORRECT", + "APPROVED", + "AUTH_RULE_ALLOWED_COUNTRY", + "AUTH_RULE_ALLOWED_MCC", + "AUTH_RULE_BLOCKED_COUNTRY", + "AUTH_RULE_BLOCKED_MCC", + "AUTH_RULE", + "CARD_CLOSED", + "CARD_CRYPTOGRAM_VALIDATION_FAILURE", + "CARD_EXPIRED", + "CARD_EXPIRY_DATE_INCORRECT", + "CARD_INVALID", + "CARD_NOT_ACTIVATED", + "CARD_PAUSED", + "CARD_PIN_INCORRECT", + "CARD_RESTRICTED", + "CARD_SECURITY_CODE_INCORRECT", + "CARD_SPEND_LIMIT_EXCEEDED", + "CONTACT_CARD_ISSUER", + "CUSTOMER_ASA_TIMEOUT", + "CUSTOM_ASA_RESULT", + "DECLINED", + "DO_NOT_HONOR", + "DRIVER_NUMBER_INVALID", + "FORMAT_ERROR", + "INSUFFICIENT_FUNDING_SOURCE_BALANCE", + "INSUFFICIENT_FUNDS", + "LITHIC_SYSTEM_ERROR", + "LITHIC_SYSTEM_RATE_LIMIT", + "MALFORMED_ASA_RESPONSE", + "MERCHANT_INVALID", + "MERCHANT_LOCKED_CARD_ATTEMPTED_ELSEWHERE", + "MERCHANT_NOT_PERMITTED", + "OVER_REVERSAL_ATTEMPTED", + "PIN_BLOCKED", + "PROGRAM_CARD_SPEND_LIMIT_EXCEEDED", + "PROGRAM_SUSPENDED", + "PROGRAM_USAGE_RESTRICTION", + "REVERSAL_UNMATCHED", + "SECURITY_VIOLATION", + "SINGLE_USE_CARD_REATTEMPTED", + "SUSPECTED_FRAUD", + "TRANSACTION_INVALID", + "TRANSACTION_NOT_PERMITTED_TO_ACQUIRER_OR_TERMINAL", + "TRANSACTION_NOT_PERMITTED_TO_ISSUER_OR_CARDHOLDER", + "TRANSACTION_PREVIOUSLY_COMPLETED", + "UNAUTHORIZED_MERCHANT", + "VEHICLE_NUMBER_INVALID", + "CARDHOLDER_CHALLENGED", + "CARDHOLDER_CHALLENGE_FAILED", + ] + """The detailed result code explaining the specific reason for the decline""" + + type: Literal["DECLINE"] + + +class DailyStatisticVersionExampleActionChallengeActionAuthorization(BaseModel): + type: Literal["CHALLENGE"] + + +class DailyStatisticVersionExampleActionResultAuthentication3DSAction(BaseModel): + type: Literal["DECLINE", "CHALLENGE"] + + +class DailyStatisticVersionExampleActionDeclineActionTokenization(BaseModel): + type: Literal["DECLINE"] + """Decline the tokenization request""" + + reason: Optional[ + Literal[ + "ACCOUNT_SCORE_1", + "DEVICE_SCORE_1", + "ALL_WALLET_DECLINE_REASONS_PRESENT", + "WALLET_RECOMMENDED_DECISION_RED", + "CVC_MISMATCH", + "CARD_EXPIRY_MONTH_MISMATCH", + "CARD_EXPIRY_YEAR_MISMATCH", + "CARD_INVALID_STATE", + "CUSTOMER_RED_PATH", + "INVALID_CUSTOMER_RESPONSE", + "NETWORK_FAILURE", + "GENERIC_DECLINE", + "DIGITAL_CARD_ART_REQUIRED", + ] + ] = None + """Reason code for declining the tokenization request""" + + +class DailyStatisticVersionExampleActionRequireTfaAction(BaseModel): + type: Literal["REQUIRE_TFA"] + """Require two-factor authentication for the tokenization request""" + + reason: Optional[ + Literal[ + "WALLET_RECOMMENDED_TFA", + "SUSPICIOUS_ACTIVITY", + "DEVICE_RECENTLY_LOST", + "TOO_MANY_RECENT_ATTEMPTS", + "TOO_MANY_RECENT_TOKENS", + "TOO_MANY_DIFFERENT_CARDHOLDERS", + "OUTSIDE_HOME_TERRITORY", + "HAS_SUSPENDED_TOKENS", + "HIGH_RISK", + "ACCOUNT_SCORE_LOW", + "DEVICE_SCORE_LOW", + "CARD_STATE_TFA", + "HARDCODED_TFA", + "CUSTOMER_RULE_TFA", + "DEVICE_HOST_CARD_EMULATION", + ] + ] = None + """Reason code for requiring two-factor authentication""" + + +class DailyStatisticVersionExampleActionApproveActionACH(BaseModel): + type: Literal["APPROVE"] + """Approve the ACH transaction""" + + +class DailyStatisticVersionExampleActionReturnAction(BaseModel): + code: Literal[ + "R01", + "R02", + "R03", + "R04", + "R05", + "R06", + "R07", + "R08", + "R09", + "R10", + "R11", + "R12", + "R13", + "R14", + "R15", + "R16", + "R17", + "R18", + "R19", + "R20", + "R21", + "R22", + "R23", + "R24", + "R25", + "R26", + "R27", + "R28", + "R29", + "R30", + "R31", + "R32", + "R33", + "R34", + "R35", + "R36", + "R37", + "R38", + "R39", + "R40", + "R41", + "R42", + "R43", + "R44", + "R45", + "R46", + "R47", + "R50", + "R51", + "R52", + "R53", + "R61", + "R62", + "R67", + "R68", + "R69", + "R70", + "R71", + "R72", + "R73", + "R74", + "R75", + "R76", + "R77", + "R80", + "R81", + "R82", + "R83", + "R84", + "R85", + ] + """NACHA return code to use when returning the transaction. + + Note that the list of available return codes is subject to an allowlist + configured at the program level + """ + + type: Literal["RETURN"] + """Return the ACH transaction""" + + +DailyStatisticVersionExampleAction: TypeAlias = Union[ + DailyStatisticVersionExampleActionDeclineActionAuthorization, + DailyStatisticVersionExampleActionChallengeActionAuthorization, + DailyStatisticVersionExampleActionResultAuthentication3DSAction, + DailyStatisticVersionExampleActionDeclineActionTokenization, + DailyStatisticVersionExampleActionRequireTfaAction, + DailyStatisticVersionExampleActionApproveActionACH, + DailyStatisticVersionExampleActionReturnAction, +] + + +class DailyStatisticVersionExample(BaseModel): + actions: List[DailyStatisticVersionExampleAction] + """The actions taken by this version for this event.""" + + event_token: str + """The event token.""" + + timestamp: datetime.datetime + """The timestamp of the event.""" + + +class DailyStatisticVersion(BaseModel): + action_counts: Dict[str, int] + """ + A mapping of action types to the number of times that action was returned by + this version during the relevant period. Actions are the possible outcomes of a + rule evaluation, such as DECLINE, CHALLENGE, REQUIRE_TFA, etc. In case rule + didn't trigger any action, it's counted under NO_ACTION key. + """ + + examples: List[DailyStatisticVersionExample] + """Example events and their outcomes for this version.""" + + state: Literal["ACTIVE", "SHADOW", "INACTIVE"] + """The evaluation mode of this version during the reported period.""" + + version: int + """The rule version number.""" class DailyStatistic(BaseModel): @@ -19,6 +285,12 @@ class DailyStatistic(BaseModel): draft_version_statistics: Optional[ReportStats] = None """Detailed statistics for the draft version of the rule.""" + versions: List[DailyStatisticVersion] + """ + Statistics for each version of the rule that was evaluated during the reported + day. + """ + class V2RetrieveReportResponse(BaseModel): auth_rule_token: str diff --git a/src/lithic/types/auth_rules/v2_update_params.py b/src/lithic/types/auth_rules/v2_update_params.py index 6694505a..6363546e 100644 --- a/src/lithic/types/auth_rules/v2_update_params.py +++ b/src/lithic/types/auth_rules/v2_update_params.py @@ -46,6 +46,12 @@ class CardLevelRule(TypedDict, total=False): class ProgramLevelRule(TypedDict, total=False): + excluded_account_tokens: SequenceNotStr[str] + """Account tokens to which the Auth Rule does not apply.""" + + excluded_business_account_tokens: SequenceNotStr[str] + """Business account tokens to which the Auth Rule does not apply.""" + excluded_card_tokens: SequenceNotStr[str] """Card tokens to which the Auth Rule does not apply.""" diff --git a/src/lithic/types/auth_rules/velocity_limit_filters.py b/src/lithic/types/auth_rules/velocity_limit_filters.py new file mode 100644 index 00000000..97bded04 --- /dev/null +++ b/src/lithic/types/auth_rules/velocity_limit_filters.py @@ -0,0 +1,64 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["VelocityLimitFilters"] + + +class VelocityLimitFilters(BaseModel): + exclude_countries: Optional[List[str]] = None + """ISO-3166-1 alpha-3 Country Codes to exclude from the velocity calculation. + + Transactions matching any of the provided will be excluded from the calculated + velocity. + """ + + exclude_mccs: Optional[List[str]] = None + """Merchant Category Codes to exclude from the velocity calculation. + + Transactions matching this MCC will be excluded from the calculated velocity. + """ + + include_countries: Optional[List[str]] = None + """ISO-3166-1 alpha-3 Country Codes to include in the velocity calculation. + + Transactions not matching any of the provided will not be included in the + calculated velocity. + """ + + include_mccs: Optional[List[str]] = None + """Merchant Category Codes to include in the velocity calculation. + + Transactions not matching this MCC will not be included in the calculated + velocity. + """ + + include_pan_entry_modes: Optional[ + List[ + Literal[ + "AUTO_ENTRY", + "BAR_CODE", + "CONTACTLESS", + "CREDENTIAL_ON_FILE", + "ECOMMERCE", + "ERROR_KEYED", + "ERROR_MAGNETIC_STRIPE", + "ICC", + "KEY_ENTERED", + "MAGNETIC_STRIPE", + "MANUAL", + "OCR", + "SECURE_CARDLESS", + "UNSPECIFIED", + "UNKNOWN", + ] + ] + ] = None + """PAN entry modes to include in the velocity calculation. + + Transactions not matching any of the provided will not be included in the + calculated velocity. + """ diff --git a/src/lithic/types/auth_rules/velocity_limit_filters_param.py b/src/lithic/types/auth_rules/velocity_limit_filters_param.py new file mode 100644 index 00000000..e9a3498b --- /dev/null +++ b/src/lithic/types/auth_rules/velocity_limit_filters_param.py @@ -0,0 +1,66 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List, Optional +from typing_extensions import Literal, TypedDict + +from ..._types import SequenceNotStr + +__all__ = ["VelocityLimitFiltersParam"] + + +class VelocityLimitFiltersParam(TypedDict, total=False): + exclude_countries: Optional[SequenceNotStr[str]] + """ISO-3166-1 alpha-3 Country Codes to exclude from the velocity calculation. + + Transactions matching any of the provided will be excluded from the calculated + velocity. + """ + + exclude_mccs: Optional[SequenceNotStr[str]] + """Merchant Category Codes to exclude from the velocity calculation. + + Transactions matching this MCC will be excluded from the calculated velocity. + """ + + include_countries: Optional[SequenceNotStr[str]] + """ISO-3166-1 alpha-3 Country Codes to include in the velocity calculation. + + Transactions not matching any of the provided will not be included in the + calculated velocity. + """ + + include_mccs: Optional[SequenceNotStr[str]] + """Merchant Category Codes to include in the velocity calculation. + + Transactions not matching this MCC will not be included in the calculated + velocity. + """ + + include_pan_entry_modes: Optional[ + List[ + Literal[ + "AUTO_ENTRY", + "BAR_CODE", + "CONTACTLESS", + "CREDENTIAL_ON_FILE", + "ECOMMERCE", + "ERROR_KEYED", + "ERROR_MAGNETIC_STRIPE", + "ICC", + "KEY_ENTERED", + "MAGNETIC_STRIPE", + "MANUAL", + "OCR", + "SECURE_CARDLESS", + "UNSPECIFIED", + "UNKNOWN", + ] + ] + ] + """PAN entry modes to include in the velocity calculation. + + Transactions not matching any of the provided will not be included in the + calculated velocity. + """ diff --git a/src/lithic/types/auth_rules/velocity_limit_params.py b/src/lithic/types/auth_rules/velocity_limit_params.py index fbbe32c9..061a8de7 100644 --- a/src/lithic/types/auth_rules/velocity_limit_params.py +++ b/src/lithic/types/auth_rules/velocity_limit_params.py @@ -1,68 +1,13 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Optional from typing_extensions import Literal from ..._models import BaseModel from .velocity_limit_period import VelocityLimitPeriod +from .velocity_limit_filters import VelocityLimitFilters -__all__ = ["VelocityLimitParams", "Filters"] - - -class Filters(BaseModel): - exclude_countries: Optional[List[str]] = None - """ISO-3166-1 alpha-3 Country Codes to exclude from the velocity calculation. - - Transactions matching any of the provided will be excluded from the calculated - velocity. - """ - - exclude_mccs: Optional[List[str]] = None - """Merchant Category Codes to exclude from the velocity calculation. - - Transactions matching this MCC will be excluded from the calculated velocity. - """ - - include_countries: Optional[List[str]] = None - """ISO-3166-1 alpha-3 Country Codes to include in the velocity calculation. - - Transactions not matching any of the provided will not be included in the - calculated velocity. - """ - - include_mccs: Optional[List[str]] = None - """Merchant Category Codes to include in the velocity calculation. - - Transactions not matching this MCC will not be included in the calculated - velocity. - """ - - include_pan_entry_modes: Optional[ - List[ - Literal[ - "AUTO_ENTRY", - "BAR_CODE", - "CONTACTLESS", - "CREDENTIAL_ON_FILE", - "ECOMMERCE", - "ERROR_KEYED", - "ERROR_MAGNETIC_STRIPE", - "ICC", - "KEY_ENTERED", - "MAGNETIC_STRIPE", - "MANUAL", - "OCR", - "SECURE_CARDLESS", - "UNSPECIFIED", - "UNKNOWN", - ] - ] - ] = None - """PAN entry modes to include in the velocity calculation. - - Transactions not matching any of the provided will not be included in the - calculated velocity. - """ +__all__ = ["VelocityLimitParams"] class VelocityLimitParams(BaseModel): @@ -72,7 +17,7 @@ class VelocityLimitParams(BaseModel): scope: Literal["CARD", "ACCOUNT"] """The scope the velocity is calculated for""" - filters: Optional[Filters] = None + filters: Optional[VelocityLimitFilters] = None limit_amount: Optional[int] = None """ diff --git a/src/lithic/types/auth_rules/velocity_limit_params_param.py b/src/lithic/types/auth_rules/velocity_limit_params_param.py index 1bee3cbb..e91557fa 100644 --- a/src/lithic/types/auth_rules/velocity_limit_params_param.py +++ b/src/lithic/types/auth_rules/velocity_limit_params_param.py @@ -2,69 +2,13 @@ from __future__ import annotations -from typing import List, Optional +from typing import Optional from typing_extensions import Literal, Required, TypedDict -from ..._types import SequenceNotStr from .velocity_limit_period_param import VelocityLimitPeriodParam +from .velocity_limit_filters_param import VelocityLimitFiltersParam -__all__ = ["VelocityLimitParamsParam", "Filters"] - - -class Filters(TypedDict, total=False): - exclude_countries: Optional[SequenceNotStr[str]] - """ISO-3166-1 alpha-3 Country Codes to exclude from the velocity calculation. - - Transactions matching any of the provided will be excluded from the calculated - velocity. - """ - - exclude_mccs: Optional[SequenceNotStr[str]] - """Merchant Category Codes to exclude from the velocity calculation. - - Transactions matching this MCC will be excluded from the calculated velocity. - """ - - include_countries: Optional[SequenceNotStr[str]] - """ISO-3166-1 alpha-3 Country Codes to include in the velocity calculation. - - Transactions not matching any of the provided will not be included in the - calculated velocity. - """ - - include_mccs: Optional[SequenceNotStr[str]] - """Merchant Category Codes to include in the velocity calculation. - - Transactions not matching this MCC will not be included in the calculated - velocity. - """ - - include_pan_entry_modes: Optional[ - List[ - Literal[ - "AUTO_ENTRY", - "BAR_CODE", - "CONTACTLESS", - "CREDENTIAL_ON_FILE", - "ECOMMERCE", - "ERROR_KEYED", - "ERROR_MAGNETIC_STRIPE", - "ICC", - "KEY_ENTERED", - "MAGNETIC_STRIPE", - "MANUAL", - "OCR", - "SECURE_CARDLESS", - "UNSPECIFIED", - "UNKNOWN", - ] - ] - ] - """PAN entry modes to include in the velocity calculation. - - Transactions not matching any of the provided will not be included in the - calculated velocity. - """ +__all__ = ["VelocityLimitParamsParam"] class VelocityLimitParamsParam(TypedDict, total=False): @@ -74,7 +18,7 @@ class VelocityLimitParamsParam(TypedDict, total=False): scope: Required[Literal["CARD", "ACCOUNT"]] """The scope the velocity is calculated for""" - filters: Filters + filters: VelocityLimitFiltersParam limit_amount: Optional[int] """ diff --git a/src/lithic/types/digital_wallet_tokenization_approval_request_webhook_event.py b/src/lithic/types/digital_wallet_tokenization_approval_request_webhook_event.py index 16e99491..c5ed8882 100644 --- a/src/lithic/types/digital_wallet_tokenization_approval_request_webhook_event.py +++ b/src/lithic/types/digital_wallet_tokenization_approval_request_webhook_event.py @@ -34,6 +34,11 @@ class CustomerTokenizationDecision(BaseModel): class DigitalWalletTokenizationApprovalRequestWebhookEvent(BaseModel): + """Payload for digital wallet tokenization approval requests. + + Used for both the decisioning responder request (sent to the customer's endpoint for a real-time decision) and the subsequent webhook event (sent after the decision is made). Fields like customer_tokenization_decision, tokenization_decline_reasons, tokenization_tfa_reasons, and rule_results are only populated in the webhook event, not in the initial decisioning request. + """ + account_token: str """Unique identifier for the user tokenizing a card""" @@ -43,9 +48,6 @@ class DigitalWalletTokenizationApprovalRequestWebhookEvent(BaseModel): created: datetime """Indicate when the request was received from Mastercard or Visa""" - customer_tokenization_decision: Optional[CustomerTokenizationDecision] = None - """Contains the metadata for the customer tokenization decision.""" - digital_wallet_token_metadata: TokenMetadata """Contains the metadata for the digital wallet being tokenized.""" @@ -66,13 +68,22 @@ class DigitalWalletTokenizationApprovalRequestWebhookEvent(BaseModel): wallet_decisioning_info: WalletDecisioningInfo + customer_tokenization_decision: Optional[CustomerTokenizationDecision] = None + """Contains the metadata for the customer tokenization decision.""" + device: Optional[Device] = None rule_results: Optional[List[TokenizationRuleResult]] = None - """Results from rules that were evaluated for this tokenization""" + """Results from rules that were evaluated for this tokenization. + + Only populated in webhook events, not in the initial decisioning request + """ tokenization_decline_reasons: Optional[List[TokenizationDeclineReason]] = None - """List of reasons why the tokenization was declined""" + """List of reasons why the tokenization was declined. + + Only populated in webhook events, not in the initial decisioning request + """ tokenization_source: Optional[ Literal["ACCOUNT_ON_FILE", "CONTACTLESS_TAP", "MANUAL_PROVISION", "PUSH_PROVISION", "TOKEN", "UNKNOWN"] @@ -80,4 +91,7 @@ class DigitalWalletTokenizationApprovalRequestWebhookEvent(BaseModel): """The source of the tokenization.""" tokenization_tfa_reasons: Optional[List[TokenizationTfaReason]] = None - """List of reasons why two-factor authentication was required""" + """List of reasons why two-factor authentication was required. + + Only populated in webhook events, not in the initial decisioning request + """ diff --git a/src/lithic/types/dispute_create_params.py b/src/lithic/types/dispute_create_params.py index d515813b..63082223 100644 --- a/src/lithic/types/dispute_create_params.py +++ b/src/lithic/types/dispute_create_params.py @@ -13,7 +13,7 @@ class DisputeCreateParams(TypedDict, total=False): amount: Required[int] - """Amount to dispute""" + """Amount for chargeback""" reason: Required[ Literal[ @@ -33,13 +33,13 @@ class DisputeCreateParams(TypedDict, total=False): "REFUND_NOT_PROCESSED", ] ] - """Reason for dispute""" + """Reason for chargeback""" transaction_token: Required[str] - """Transaction to dispute""" + """Transaction for chargeback""" customer_filed_date: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """Date the customer filed the dispute""" + """Date the customer filed the chargeback request""" customer_note: str - """Customer description of dispute""" + """Customer description""" diff --git a/src/lithic/types/dispute_list_params.py b/src/lithic/types/dispute_list_params.py index f83e42ab..1aca832f 100644 --- a/src/lithic/types/dispute_list_params.py +++ b/src/lithic/types/dispute_list_params.py @@ -51,7 +51,7 @@ class DisputeListParams(TypedDict, total=False): "REPRESENTMENT", "SUBMITTED", ] - """List disputes of a specific status.""" + """Filter by status.""" transaction_tokens: SequenceNotStr[str] """Transaction tokens to filter by.""" diff --git a/src/lithic/types/dispute_update_params.py b/src/lithic/types/dispute_update_params.py index de0b45aa..7a846a9a 100644 --- a/src/lithic/types/dispute_update_params.py +++ b/src/lithic/types/dispute_update_params.py @@ -13,13 +13,13 @@ class DisputeUpdateParams(TypedDict, total=False): amount: int - """Amount to dispute""" + """Amount for chargeback""" customer_filed_date: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """Date the customer filed the dispute""" + """Date the customer filed the chargeback request""" customer_note: str - """Customer description of dispute""" + """Customer description""" reason: Literal[ "ATM_CASH_MISDISPENSE", @@ -37,4 +37,4 @@ class DisputeUpdateParams(TypedDict, total=False): "RECURRING_TRANSACTION_NOT_CANCELLED", "REFUND_NOT_PROCESSED", ] - """Reason for dispute""" + """Reason for chargeback""" diff --git a/src/lithic/types/event.py b/src/lithic/types/event.py index a573f000..188a46d8 100644 --- a/src/lithic/types/event.py +++ b/src/lithic/types/event.py @@ -39,7 +39,6 @@ class Event(BaseModel): "card.renewed", "card.shipped", "card.updated", - "digital_wallet.tokenization_approval_request", "digital_wallet.tokenization_result", "digital_wallet.tokenization_two_factor_authentication_code", "digital_wallet.tokenization_two_factor_authentication_code_sent", @@ -102,9 +101,6 @@ class Event(BaseModel): - card.renewed: Occurs when a card is renewed. - card.shipped: Occurs when a card is shipped. - card.updated: Occurs when a card is updated. - - digital_wallet.tokenization_approval_request: Occurs when a tokenization - approval request is made. This event will be deprecated in the future. We - recommend using `tokenization.approval_request` instead. - digital_wallet.tokenization_result: Occurs when a tokenization request succeeded or failed. diff --git a/src/lithic/types/event_list_params.py b/src/lithic/types/event_list_params.py index 2074c7a1..24daebfb 100644 --- a/src/lithic/types/event_list_params.py +++ b/src/lithic/types/event_list_params.py @@ -49,7 +49,6 @@ class EventListParams(TypedDict, total=False): "card.renewed", "card.shipped", "card.updated", - "digital_wallet.tokenization_approval_request", "digital_wallet.tokenization_result", "digital_wallet.tokenization_two_factor_authentication_code", "digital_wallet.tokenization_two_factor_authentication_code_sent", diff --git a/src/lithic/types/event_subscription.py b/src/lithic/types/event_subscription.py index db714b0d..2c59189e 100644 --- a/src/lithic/types/event_subscription.py +++ b/src/lithic/types/event_subscription.py @@ -42,7 +42,6 @@ class EventSubscription(BaseModel): "card.renewed", "card.shipped", "card.updated", - "digital_wallet.tokenization_approval_request", "digital_wallet.tokenization_result", "digital_wallet.tokenization_two_factor_authentication_code", "digital_wallet.tokenization_two_factor_authentication_code_sent", diff --git a/src/lithic/types/events/subscription_create_params.py b/src/lithic/types/events/subscription_create_params.py index 8319e85f..7d1caebf 100644 --- a/src/lithic/types/events/subscription_create_params.py +++ b/src/lithic/types/events/subscription_create_params.py @@ -37,7 +37,6 @@ class SubscriptionCreateParams(TypedDict, total=False): "card.renewed", "card.shipped", "card.updated", - "digital_wallet.tokenization_approval_request", "digital_wallet.tokenization_result", "digital_wallet.tokenization_two_factor_authentication_code", "digital_wallet.tokenization_two_factor_authentication_code_sent", diff --git a/src/lithic/types/events/subscription_send_simulated_example_params.py b/src/lithic/types/events/subscription_send_simulated_example_params.py index c665c769..4cdc1f72 100644 --- a/src/lithic/types/events/subscription_send_simulated_example_params.py +++ b/src/lithic/types/events/subscription_send_simulated_example_params.py @@ -26,7 +26,6 @@ class SubscriptionSendSimulatedExampleParams(TypedDict, total=False): "card.renewed", "card.shipped", "card.updated", - "digital_wallet.tokenization_approval_request", "digital_wallet.tokenization_result", "digital_wallet.tokenization_two_factor_authentication_code", "digital_wallet.tokenization_two_factor_authentication_code_sent", diff --git a/src/lithic/types/events/subscription_update_params.py b/src/lithic/types/events/subscription_update_params.py index babd5fdc..dac70887 100644 --- a/src/lithic/types/events/subscription_update_params.py +++ b/src/lithic/types/events/subscription_update_params.py @@ -37,7 +37,6 @@ class SubscriptionUpdateParams(TypedDict, total=False): "card.renewed", "card.shipped", "card.updated", - "digital_wallet.tokenization_approval_request", "digital_wallet.tokenization_result", "digital_wallet.tokenization_two_factor_authentication_code", "digital_wallet.tokenization_two_factor_authentication_code_sent", diff --git a/src/lithic/types/financial_account.py b/src/lithic/types/financial_account.py index 92e7ddd4..f15dfccd 100644 --- a/src/lithic/types/financial_account.py +++ b/src/lithic/types/financial_account.py @@ -69,6 +69,7 @@ class FinancialAccount(BaseModel): "PROGRAM_RECEIVABLES", "COLLECTION", "PROGRAM_BANK_ACCOUNTS_PAYABLE", + "EARLY_DIRECT_DEPOSIT_FLOAT", ] updated: datetime diff --git a/src/lithic/types/financial_account_list_params.py b/src/lithic/types/financial_account_list_params.py index 0228f2b6..20b2605f 100644 --- a/src/lithic/types/financial_account_list_params.py +++ b/src/lithic/types/financial_account_list_params.py @@ -14,5 +14,5 @@ class FinancialAccountListParams(TypedDict, total=False): business_account_token: str """List financial accounts for a given business_account_token""" - type: Literal["ISSUING", "OPERATING", "RESERVE", "SECURITY"] + type: Literal["ISSUING", "OPERATING", "RESERVE", "SECURITY", "EARLY_DIRECT_DEPOSIT_FLOAT"] """List financial accounts of a given type""" diff --git a/src/lithic/types/financial_accounts/interest_tier_schedule.py b/src/lithic/types/financial_accounts/interest_tier_schedule.py index de815562..dfdd9000 100644 --- a/src/lithic/types/financial_accounts/interest_tier_schedule.py +++ b/src/lithic/types/financial_accounts/interest_tier_schedule.py @@ -17,6 +17,9 @@ class InterestTierSchedule(BaseModel): effective_date: date """Date the tier should be effective in YYYY-MM-DD format""" + penalty_rates: Optional[object] = None + """Custom rates per category for penalties""" + tier_name: Optional[str] = None """Name of a tier contained in the credit product. diff --git a/src/lithic/types/financial_accounts/interest_tier_schedule_create_params.py b/src/lithic/types/financial_accounts/interest_tier_schedule_create_params.py index dc7c11e9..ce016a89 100644 --- a/src/lithic/types/financial_accounts/interest_tier_schedule_create_params.py +++ b/src/lithic/types/financial_accounts/interest_tier_schedule_create_params.py @@ -18,6 +18,9 @@ class InterestTierScheduleCreateParams(TypedDict, total=False): effective_date: Required[Annotated[Union[str, date], PropertyInfo(format="iso8601")]] """Date the tier should be effective in YYYY-MM-DD format""" + penalty_rates: object + """Custom rates per category for penalties""" + tier_name: str """Name of a tier contained in the credit product. diff --git a/src/lithic/types/financial_accounts/interest_tier_schedule_update_params.py b/src/lithic/types/financial_accounts/interest_tier_schedule_update_params.py index dd1cd9c0..e2198378 100644 --- a/src/lithic/types/financial_accounts/interest_tier_schedule_update_params.py +++ b/src/lithic/types/financial_accounts/interest_tier_schedule_update_params.py @@ -10,6 +10,9 @@ class InterestTierScheduleUpdateParams(TypedDict, total=False): financial_account_token: Required[str] + penalty_rates: object + """Custom rates per category for penalties""" + tier_name: str """Name of a tier contained in the credit product. 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 c1816c30..65967a2d 100644 --- a/src/lithic/types/financial_accounts/statements/statement_line_items.py +++ b/src/lithic/types/financial_accounts/statements/statement_line_items.py @@ -18,6 +18,7 @@ class Data(BaseModel): category: Literal[ "ACH", + "WIRE", "BALANCE_OR_FUNDING", "FEE", "REWARD", @@ -36,8 +37,14 @@ class Data(BaseModel): "MANAGEMENT_FEE", "MANAGEMENT_REWARD", "MANAGEMENT_DISBURSEMENT", + "HOLD", "PROGRAM_FUNDING", ] + """ + Note: Inbound wire transfers are coming soon (availability varies by partner + bank). The WIRE category is a preview. To learn more, contact your customer + success manager. + """ created: datetime """Timestamp of when the line item was generated""" @@ -155,6 +162,12 @@ class Data(BaseModel): descriptor: Optional[str] = None + event_subtype: Optional[str] = None + """Subtype of the event that generated the line items""" + + loan_tape_date: Optional[date] = None + """Date of the loan tape that generated this line item""" + class StatementLineItems(BaseModel): data: List[Data] diff --git a/src/lithic/types/hold.py b/src/lithic/types/hold.py new file mode 100644 index 00000000..448da4cc --- /dev/null +++ b/src/lithic/types/hold.py @@ -0,0 +1,48 @@ +# 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 +from .hold_event import HoldEvent + +__all__ = ["Hold"] + + +class Hold(BaseModel): + """A hold transaction representing reserved funds on a financial account. + + Holds move funds from available to pending balance in anticipation of future payments. They can be resolved via settlement (linked to payment), manual release, or expiration. + """ + + token: str + """Unique identifier for the transaction""" + + created: datetime + """ISO 8601 timestamp of when the transaction was created""" + + status: Literal["PENDING", "SETTLED", "EXPIRED", "VOIDED", "DECLINED", "REVERSED", "CANCELED", "RETURNED"] + """Status of a hold transaction""" + + updated: datetime + """ISO 8601 timestamp of when the transaction was last updated""" + + currency: Optional[str] = None + + events: Optional[List[HoldEvent]] = None + + expiration_datetime: Optional[datetime] = None + """When the hold will auto-expire if not resolved""" + + family: Optional[Literal["HOLD"]] = None + """HOLD - Hold Transaction""" + + financial_account_token: Optional[str] = None + + pending_amount: Optional[int] = None + """Current pending amount (0 when resolved)""" + + result: Optional[Literal["APPROVED", "DECLINED"]] = None + + user_defined_id: Optional[str] = None diff --git a/src/lithic/types/hold_create_params.py b/src/lithic/types/hold_create_params.py new file mode 100644 index 00000000..fb68d3de --- /dev/null +++ b/src/lithic/types/hold_create_params.py @@ -0,0 +1,28 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union, Optional +from datetime import datetime +from typing_extensions import Required, Annotated, TypedDict + +from .._utils import PropertyInfo + +__all__ = ["HoldCreateParams"] + + +class HoldCreateParams(TypedDict, total=False): + amount: Required[int] + """Amount to hold in cents""" + + token: str + """Customer-provided token for idempotency. Becomes the hold token.""" + + expiration_datetime: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """When the hold should auto-expire""" + + memo: Optional[str] + """Reason for the hold""" + + user_defined_id: str + """User-provided identifier for the hold""" diff --git a/src/lithic/types/hold_event.py b/src/lithic/types/hold_event.py new file mode 100644 index 00000000..b0c8d0ba --- /dev/null +++ b/src/lithic/types/hold_event.py @@ -0,0 +1,35 @@ +# 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__ = ["HoldEvent"] + + +class HoldEvent(BaseModel): + """Event representing a lifecycle change to a hold""" + + token: str + + amount: int + """Amount in cents""" + + created: datetime + + detailed_results: List[Literal["APPROVED", "INSUFFICIENT_FUNDS"]] + + memo: Optional[str] = None + + result: Literal["APPROVED", "DECLINED"] + + settling_transaction_token: Optional[str] = None + """ + Transaction token of the payment that settled this hold (only populated for + HOLD_SETTLED events) + """ + + type: Literal["HOLD_INITIATED", "HOLD_VOIDED", "HOLD_EXPIRED", "HOLD_SETTLED"] + """Type of hold lifecycle event""" diff --git a/src/lithic/types/hold_list_params.py b/src/lithic/types/hold_list_params.py new file mode 100644 index 00000000..3a7cf534 --- /dev/null +++ b/src/lithic/types/hold_list_params.py @@ -0,0 +1,44 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime +from typing_extensions import Literal, Annotated, TypedDict + +from .._utils import PropertyInfo + +__all__ = ["HoldListParams"] + + +class HoldListParams(TypedDict, total=False): + begin: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """Date string in RFC 3339 format. + + Only entries created after the specified time will be included. UTC time zone. + """ + + end: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """Date string in RFC 3339 format. + + Only entries created before the specified time will be included. UTC time zone. + """ + + ending_before: str + """A cursor representing an item's token before which a page of results should end. + + Used to retrieve the previous page of results before this item. + """ + + page_size: int + """Page size (for pagination).""" + + starting_after: str + """A cursor representing an item's token after which a page of results should + begin. + + Used to retrieve the next page of results after this item. + """ + + status: Literal["PENDING", "SETTLED", "EXPIRED", "VOIDED"] + """Hold status to filter by.""" diff --git a/src/lithic/types/hold_void_params.py b/src/lithic/types/hold_void_params.py new file mode 100644 index 00000000..c01ce288 --- /dev/null +++ b/src/lithic/types/hold_void_params.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import TypedDict + +__all__ = ["HoldVoidParams"] + + +class HoldVoidParams(TypedDict, total=False): + memo: Optional[str] + """Reason for voiding the hold""" diff --git a/src/lithic/types/parsed_webhook_event.py b/src/lithic/types/parsed_webhook_event.py index 1ce1f75f..2bd28e21 100644 --- a/src/lithic/types/parsed_webhook_event.py +++ b/src/lithic/types/parsed_webhook_event.py @@ -45,7 +45,6 @@ from .account_holder_document_updated_webhook_event import AccountHolderDocumentUpdatedWebhookEvent from .three_ds_authentication_created_webhook_event import ThreeDSAuthenticationCreatedWebhookEvent from .three_ds_authentication_updated_webhook_event import ThreeDSAuthenticationUpdatedWebhookEvent -from .tokenization_decisioning_request_webhook_event import TokenizationDecisioningRequestWebhookEvent from .book_transfer_transaction_created_webhook_event import BookTransferTransactionCreatedWebhookEvent from .book_transfer_transaction_updated_webhook_event import BookTransferTransactionUpdatedWebhookEvent from .three_ds_authentication_challenge_webhook_event import ThreeDSAuthenticationChallengeWebhookEvent @@ -431,7 +430,6 @@ class LegacyPayload(BaseModel): AccountHolderVerificationWebhookEvent, AccountHolderDocumentUpdatedWebhookEvent, CardAuthorizationApprovalRequestWebhookEvent, - TokenizationDecisioningRequestWebhookEvent, AuthRulesBacktestReportCreatedWebhookEvent, BalanceUpdatedWebhookEvent, BookTransferTransactionCreatedWebhookEvent, diff --git a/src/lithic/types/payment.py b/src/lithic/types/payment.py index 686f8978..cec6116f 100644 --- a/src/lithic/types/payment.py +++ b/src/lithic/types/payment.py @@ -18,7 +18,11 @@ class Event(BaseModel): - """Payment Event""" + """ + Note: Inbound wire transfers are coming soon (availability varies by partner bank). Wire-related fields below are a preview. To learn more, contact your customer success manager. + + Payment Event + """ token: str """Globally unique identifier.""" @@ -48,13 +52,28 @@ class Event(BaseModel): "ACH_ORIGINATION_SETTLED", "ACH_RECEIPT_PROCESSED", "ACH_RECEIPT_RELEASED", + "ACH_RECEIPT_RELEASED_EARLY", "ACH_RECEIPT_SETTLED", "ACH_RETURN_INITIATED", "ACH_RETURN_PROCESSED", "ACH_RETURN_REJECTED", "ACH_RETURN_SETTLED", + "WIRE_TRANSFER_INBOUND_RECEIVED", + "WIRE_TRANSFER_INBOUND_SETTLED", + "WIRE_TRANSFER_INBOUND_BLOCKED", + "WIRE_RETURN_OUTBOUND_INITIATED", + "WIRE_RETURN_OUTBOUND_SENT", + "WIRE_RETURN_OUTBOUND_SETTLED", + "WIRE_RETURN_OUTBOUND_REJECTED", ] - """Event types: + """ + Note: Inbound wire transfers are coming soon (availability varies by partner + bank). Wire-related event types below are a preview. To learn more, contact your + customer success manager. + + Event types: + + ACH events: - `ACH_ORIGINATION_INITIATED` - ACH origination received and pending approval/release from an ACH hold. @@ -71,6 +90,8 @@ class Event(BaseModel): - `ACH_RECEIPT_SETTLED` - ACH receipt funds have settled. - `ACH_RECEIPT_RELEASED` - ACH receipt released from pending to available balance. + - `ACH_RECEIPT_RELEASED_EARLY` - ACH receipt released early from pending to + available balance. - `ACH_RETURN_INITIATED` - ACH initiated return for an ACH receipt. - `ACH_RETURN_PROCESSED` - ACH receipt returned by the Receiving Depository Financial Institution. @@ -78,6 +99,26 @@ class Event(BaseModel): Financial Institution. - `ACH_RETURN_REJECTED` - ACH return was rejected by the Receiving Depository Financial Institution. + + Wire transfer events: + + - `WIRE_TRANSFER_INBOUND_RECEIVED` - Inbound wire transfer received from the + Federal Reserve and pending release to available balance. + - `WIRE_TRANSFER_INBOUND_SETTLED` - Inbound wire transfer funds released from + pending to available balance. + - `WIRE_TRANSFER_INBOUND_BLOCKED` - Inbound wire transfer blocked and funds + frozen for regulatory review. + + Wire return events: + + - `WIRE_RETURN_OUTBOUND_INITIATED` - Outbound wire return initiated to return + funds from an inbound wire transfer. + - `WIRE_RETURN_OUTBOUND_SENT` - Outbound wire return sent to the Federal Reserve + and pending acceptance. + - `WIRE_RETURN_OUTBOUND_SETTLED` - Outbound wire return accepted by the Federal + Reserve and funds returned to sender. + - `WIRE_RETURN_OUTBOUND_REJECTED` - Outbound wire return rejected by the Federal + Reserve. """ detailed_results: Optional[ @@ -96,7 +137,11 @@ class Event(BaseModel): """More detailed reasons for the event""" external_id: Optional[str] = None - """Payment event external ID, for example, ACH trace number.""" + """Payment event external ID. + + For ACH transactions, this is the ACH trace number. For inbound wire transfers, + this is the IMAD (Input Message Accountability Data). + """ class MethodAttributesACHMethodAttributes(BaseModel): @@ -142,9 +187,6 @@ class MethodAttributesWireMethodAttributes(BaseModel): for tracking the message through the Fedwire system """ - remittance_information: Optional[str] = None - """Payment details or invoice reference""" - MethodAttributes: TypeAlias = Union[MethodAttributesACHMethodAttributes, MethodAttributesWireMethodAttributes] @@ -167,6 +209,7 @@ class Payment(BaseModel): category: Literal[ "ACH", + "WIRE", "BALANCE_OR_FUNDING", "FEE", "REWARD", @@ -185,6 +228,7 @@ class Payment(BaseModel): "MANAGEMENT_FEE", "MANAGEMENT_REWARD", "MANAGEMENT_DISBURSEMENT", + "HOLD", "PROGRAM_FUNDING", ] """Transaction category""" diff --git a/src/lithic/types/payment_simulate_action_params.py b/src/lithic/types/payment_simulate_action_params.py index 1f242232..b5500957 100644 --- a/src/lithic/types/payment_simulate_action_params.py +++ b/src/lithic/types/payment_simulate_action_params.py @@ -20,6 +20,7 @@ class PaymentSimulateActionParams(TypedDict, total=False): "ACH_ORIGINATION_SETTLED", "ACH_RECEIPT_SETTLED", "ACH_RECEIPT_RELEASED", + "ACH_RECEIPT_RELEASED_EARLY", "ACH_RETURN_INITIATED", "ACH_RETURN_PROCESSED", "ACH_RETURN_SETTLED", diff --git a/src/lithic/types/shared/instance_financial_account_type.py b/src/lithic/types/shared/instance_financial_account_type.py index 72a4a348..4cd1bd35 100644 --- a/src/lithic/types/shared/instance_financial_account_type.py +++ b/src/lithic/types/shared/instance_financial_account_type.py @@ -15,4 +15,5 @@ "PROGRAM_RECEIVABLES", "COLLECTION", "PROGRAM_BANK_ACCOUNTS_PAYABLE", + "EARLY_DIRECT_DEPOSIT_FLOAT", ] diff --git a/src/lithic/types/tokenization_decisioning_request_webhook_event.py b/src/lithic/types/tokenization_decisioning_request_webhook_event.py deleted file mode 100644 index c44df2dc..00000000 --- a/src/lithic/types/tokenization_decisioning_request_webhook_event.py +++ /dev/null @@ -1,54 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Optional -from datetime import datetime -from typing_extensions import Literal - -from .device import Device -from .._models import BaseModel -from .token_metadata import TokenMetadata -from .wallet_decisioning_info import WalletDecisioningInfo - -__all__ = ["TokenizationDecisioningRequestWebhookEvent"] - - -class TokenizationDecisioningRequestWebhookEvent(BaseModel): - """ - A webhook for tokenization decisioning sent to the customer's responder endpoint - """ - - account_token: str - """Unique identifier for the user tokenizing a card""" - - card_token: str - """Unique identifier for the card being tokenized""" - - created: datetime - """Indicate when the request was received from Mastercard or Visa""" - - digital_wallet_token_metadata: TokenMetadata - """Contains the metadata for the digital wallet being tokenized.""" - - event_type: Literal["digital_wallet.tokenization_approval_request"] - """The name of this event""" - - issuer_decision: Literal["APPROVED", "DENIED", "VERIFICATION_REQUIRED"] - """Whether Lithic decisioned on the token, and if so, what the decision was. - - APPROVED/VERIFICATION_REQUIRED/DENIED. - """ - - tokenization_channel: Literal["DIGITAL_WALLET", "MERCHANT"] - """The channel through which the tokenization was made.""" - - tokenization_token: str - """Unique identifier for the digital wallet token attempt""" - - wallet_decisioning_info: WalletDecisioningInfo - - device: Optional[Device] = None - - tokenization_source: Optional[ - Literal["ACCOUNT_ON_FILE", "CONTACTLESS_TAP", "MANUAL_PROVISION", "PUSH_PROVISION", "TOKEN", "UNKNOWN"] - ] = None - """The source of the tokenization.""" diff --git a/tests/api_resources/auth_rules/test_v2.py b/tests/api_resources/auth_rules/test_v2.py index c59bac30..86a9cc74 100644 --- a/tests/api_resources/auth_rules/test_v2.py +++ b/tests/api_resources/auth_rules/test_v2.py @@ -14,6 +14,7 @@ from lithic.types.auth_rules import ( AuthRule, V2ListResultsResponse, + V2ListVersionsResponse, V2RetrieveReportResponse, V2RetrieveFeaturesResponse, ) @@ -214,6 +215,8 @@ def test_method_create_with_all_params_overload_3(self, client: Lithic) -> None: program_level=True, type="CONDITIONAL_BLOCK", event_stream="AUTHORIZATION", + excluded_account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + excluded_business_account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], excluded_card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], name="name", ) @@ -409,6 +412,8 @@ def test_method_update_overload_3(self, client: Lithic) -> None: def test_method_update_with_all_params_overload_3(self, client: Lithic) -> None: v2 = client.auth_rules.v2.update( auth_rule_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + excluded_account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + excluded_business_account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], excluded_card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], name="name", program_level=True, @@ -618,6 +623,44 @@ def test_streaming_response_list_results(self, client: Lithic) -> None: assert cast(Any, response.is_closed) is True + @parametrize + def test_method_list_versions(self, client: Lithic) -> None: + v2 = client.auth_rules.v2.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(V2ListVersionsResponse, v2, path=["response"]) + + @parametrize + def test_raw_response_list_versions(self, client: Lithic) -> None: + response = client.auth_rules.v2.with_raw_response.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + v2 = response.parse() + assert_matches_type(V2ListVersionsResponse, v2, path=["response"]) + + @parametrize + def test_streaming_response_list_versions(self, client: Lithic) -> None: + with client.auth_rules.v2.with_streaming_response.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + v2 = response.parse() + assert_matches_type(V2ListVersionsResponse, v2, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list_versions(self, client: Lithic) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `auth_rule_token` but received ''"): + client.auth_rules.v2.with_raw_response.list_versions( + "", + ) + @parametrize def test_method_promote(self, client: Lithic) -> None: v2 = client.auth_rules.v2.promote( @@ -945,6 +988,8 @@ async def test_method_create_with_all_params_overload_3(self, async_client: Asyn program_level=True, type="CONDITIONAL_BLOCK", event_stream="AUTHORIZATION", + excluded_account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + excluded_business_account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], excluded_card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], name="name", ) @@ -1140,6 +1185,8 @@ async def test_method_update_overload_3(self, async_client: AsyncLithic) -> None async def test_method_update_with_all_params_overload_3(self, async_client: AsyncLithic) -> None: v2 = await async_client.auth_rules.v2.update( auth_rule_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + excluded_account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + excluded_business_account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], excluded_card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], name="name", program_level=True, @@ -1349,6 +1396,44 @@ async def test_streaming_response_list_results(self, async_client: AsyncLithic) assert cast(Any, response.is_closed) is True + @parametrize + async def test_method_list_versions(self, async_client: AsyncLithic) -> None: + v2 = await async_client.auth_rules.v2.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(V2ListVersionsResponse, v2, path=["response"]) + + @parametrize + async def test_raw_response_list_versions(self, async_client: AsyncLithic) -> None: + response = await async_client.auth_rules.v2.with_raw_response.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + v2 = response.parse() + assert_matches_type(V2ListVersionsResponse, v2, path=["response"]) + + @parametrize + async def test_streaming_response_list_versions(self, async_client: AsyncLithic) -> None: + async with async_client.auth_rules.v2.with_streaming_response.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + v2 = await response.parse() + assert_matches_type(V2ListVersionsResponse, v2, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list_versions(self, async_client: AsyncLithic) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `auth_rule_token` but received ''"): + await async_client.auth_rules.v2.with_raw_response.list_versions( + "", + ) + @parametrize async def test_method_promote(self, async_client: AsyncLithic) -> None: v2 = await async_client.auth_rules.v2.promote( diff --git a/tests/api_resources/financial_accounts/test_interest_tier_schedule.py b/tests/api_resources/financial_accounts/test_interest_tier_schedule.py index fcac228d..b0bf8be4 100644 --- a/tests/api_resources/financial_accounts/test_interest_tier_schedule.py +++ b/tests/api_resources/financial_accounts/test_interest_tier_schedule.py @@ -36,6 +36,7 @@ def test_method_create_with_all_params(self, client: Lithic) -> None: financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", credit_product_token="credit_product_token", effective_date=parse_date("2019-12-27"), + penalty_rates={}, tier_name="tier_name", tier_rates={}, ) @@ -143,6 +144,7 @@ def test_method_update_with_all_params(self, client: Lithic) -> None: interest_tier_schedule = client.financial_accounts.interest_tier_schedule.update( effective_date=parse_date("2019-12-27"), financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + penalty_rates={}, tier_name="tier_name", tier_rates={}, ) @@ -311,6 +313,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncLithic) -> financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", credit_product_token="credit_product_token", effective_date=parse_date("2019-12-27"), + penalty_rates={}, tier_name="tier_name", tier_rates={}, ) @@ -418,6 +421,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncLithic) -> interest_tier_schedule = await async_client.financial_accounts.interest_tier_schedule.update( effective_date=parse_date("2019-12-27"), financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + penalty_rates={}, tier_name="tier_name", tier_rates={}, ) diff --git a/tests/api_resources/test_holds.py b/tests/api_resources/test_holds.py new file mode 100644 index 00000000..c2bf4f08 --- /dev/null +++ b/tests/api_resources/test_holds.py @@ -0,0 +1,412 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from lithic import Lithic, AsyncLithic +from tests.utils import assert_matches_type +from lithic.types import Hold +from lithic._utils import parse_datetime +from lithic.pagination import SyncCursorPage, AsyncCursorPage + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestHolds: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Lithic) -> None: + hold = client.holds.create( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + amount=1, + ) + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Lithic) -> None: + hold = client.holds.create( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + amount=1, + token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + expiration_datetime=parse_datetime("2019-12-27T18:11:19.117Z"), + memo="memo", + user_defined_id="user_defined_id", + ) + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Lithic) -> None: + response = client.holds.with_raw_response.create( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + amount=1, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + hold = response.parse() + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Lithic) -> None: + with client.holds.with_streaming_response.create( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + amount=1, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + hold = response.parse() + assert_matches_type(Hold, hold, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Lithic) -> None: + with pytest.raises( + ValueError, match=r"Expected a non-empty value for `financial_account_token` but received ''" + ): + client.holds.with_raw_response.create( + financial_account_token="", + amount=1, + ) + + @parametrize + def test_method_retrieve(self, client: Lithic) -> None: + hold = client.holds.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: Lithic) -> None: + response = client.holds.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + hold = response.parse() + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + def test_streaming_response_retrieve(self, client: Lithic) -> None: + with client.holds.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + hold = response.parse() + assert_matches_type(Hold, hold, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_retrieve(self, client: Lithic) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `hold_token` but received ''"): + client.holds.with_raw_response.retrieve( + "", + ) + + @parametrize + def test_method_list(self, client: Lithic) -> None: + hold = client.holds.list( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(SyncCursorPage[Hold], hold, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Lithic) -> None: + hold = client.holds.list( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + begin=parse_datetime("2019-12-27T18:11:19.117Z"), + end=parse_datetime("2019-12-27T18:11:19.117Z"), + ending_before="ending_before", + page_size=1, + starting_after="starting_after", + status="PENDING", + ) + assert_matches_type(SyncCursorPage[Hold], hold, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Lithic) -> None: + response = client.holds.with_raw_response.list( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + hold = response.parse() + assert_matches_type(SyncCursorPage[Hold], hold, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Lithic) -> None: + with client.holds.with_streaming_response.list( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + hold = response.parse() + assert_matches_type(SyncCursorPage[Hold], hold, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Lithic) -> None: + with pytest.raises( + ValueError, match=r"Expected a non-empty value for `financial_account_token` but received ''" + ): + client.holds.with_raw_response.list( + financial_account_token="", + ) + + @parametrize + def test_method_void(self, client: Lithic) -> None: + hold = client.holds.void( + hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + def test_method_void_with_all_params(self, client: Lithic) -> None: + hold = client.holds.void( + hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + memo="memo", + ) + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + def test_raw_response_void(self, client: Lithic) -> None: + response = client.holds.with_raw_response.void( + hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + hold = response.parse() + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + def test_streaming_response_void(self, client: Lithic) -> None: + with client.holds.with_streaming_response.void( + hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + hold = response.parse() + assert_matches_type(Hold, hold, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_void(self, client: Lithic) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `hold_token` but received ''"): + client.holds.with_raw_response.void( + hold_token="", + ) + + +class TestAsyncHolds: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_create(self, async_client: AsyncLithic) -> None: + hold = await async_client.holds.create( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + amount=1, + ) + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncLithic) -> None: + hold = await async_client.holds.create( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + amount=1, + token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + expiration_datetime=parse_datetime("2019-12-27T18:11:19.117Z"), + memo="memo", + user_defined_id="user_defined_id", + ) + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncLithic) -> None: + response = await async_client.holds.with_raw_response.create( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + amount=1, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + hold = response.parse() + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncLithic) -> None: + async with async_client.holds.with_streaming_response.create( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + amount=1, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + hold = await response.parse() + assert_matches_type(Hold, hold, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncLithic) -> None: + with pytest.raises( + ValueError, match=r"Expected a non-empty value for `financial_account_token` but received ''" + ): + await async_client.holds.with_raw_response.create( + financial_account_token="", + amount=1, + ) + + @parametrize + async def test_method_retrieve(self, async_client: AsyncLithic) -> None: + hold = await async_client.holds.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncLithic) -> None: + response = await async_client.holds.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + hold = response.parse() + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncLithic) -> None: + async with async_client.holds.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + hold = await response.parse() + assert_matches_type(Hold, hold, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncLithic) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `hold_token` but received ''"): + await async_client.holds.with_raw_response.retrieve( + "", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncLithic) -> None: + hold = await async_client.holds.list( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(AsyncCursorPage[Hold], hold, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncLithic) -> None: + hold = await async_client.holds.list( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + begin=parse_datetime("2019-12-27T18:11:19.117Z"), + end=parse_datetime("2019-12-27T18:11:19.117Z"), + ending_before="ending_before", + page_size=1, + starting_after="starting_after", + status="PENDING", + ) + assert_matches_type(AsyncCursorPage[Hold], hold, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncLithic) -> None: + response = await async_client.holds.with_raw_response.list( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + hold = response.parse() + assert_matches_type(AsyncCursorPage[Hold], hold, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncLithic) -> None: + async with async_client.holds.with_streaming_response.list( + financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + hold = await response.parse() + assert_matches_type(AsyncCursorPage[Hold], hold, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncLithic) -> None: + with pytest.raises( + ValueError, match=r"Expected a non-empty value for `financial_account_token` but received ''" + ): + await async_client.holds.with_raw_response.list( + financial_account_token="", + ) + + @parametrize + async def test_method_void(self, async_client: AsyncLithic) -> None: + hold = await async_client.holds.void( + hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + async def test_method_void_with_all_params(self, async_client: AsyncLithic) -> None: + hold = await async_client.holds.void( + hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + memo="memo", + ) + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + async def test_raw_response_void(self, async_client: AsyncLithic) -> None: + response = await async_client.holds.with_raw_response.void( + hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + hold = response.parse() + assert_matches_type(Hold, hold, path=["response"]) + + @parametrize + async def test_streaming_response_void(self, async_client: AsyncLithic) -> None: + async with async_client.holds.with_streaming_response.void( + hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + hold = await response.parse() + assert_matches_type(Hold, hold, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_void(self, async_client: AsyncLithic) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `hold_token` but received ''"): + await async_client.holds.with_raw_response.void( + hold_token="", + )