From 3f0a148adc95e092aa25c9e569bbda518bbe3f54 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 1 Sep 2026 12:53:15 +0000 Subject: [PATCH 01/14] feat(api): add OTHER enum value to auth_rules v2 type field --- .stats.yml | 4 +- src/lithic/resources/auth_rules/v2/v2.py | 44 +++++++++++++++---- src/lithic/types/auth_rules/auth_rule.py | 6 ++- .../types/auth_rules/v2_create_params.py | 18 ++++++-- 4 files changed, 58 insertions(+), 14 deletions(-) diff --git a/.stats.yml b/.stats.yml index 50060d6a..3961ab04 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 215 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-38a020a15ab14f79c7fea3290822406cf80a9d43d46ab3295632a9723f5e42cd.yml -openapi_spec_hash: 5a7357a17c5119bc91d8f5e42297fac3 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-9a4064ca9be1efe3e33d922cae77a5d186b6a0119ef1d3601b5ded1447feb7f7.yml +openapi_spec_hash: bff457821129b2eb4fc5150e23efa197 config_hash: 27fa50e251754c8982e3dc615ef6da41 diff --git a/src/lithic/resources/auth_rules/v2/v2.py b/src/lithic/resources/auth_rules/v2/v2.py index 427f1c86..7365c837 100644 --- a/src/lithic/resources/auth_rules/v2/v2.py +++ b/src/lithic/resources/auth_rules/v2/v2.py @@ -73,7 +73,9 @@ def create( self, *, parameters: v2_create_params.AccountLevelRuleParameters, - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"], + type: Literal[ + "CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE", "OTHER" + ], account_tokens: SequenceNotStr[str] | Omit = omit, business_account_tokens: SequenceNotStr[str] | Omit = omit, event_stream: EventStream | Omit = omit, @@ -106,6 +108,8 @@ def create( - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, ACH_DEBIT_RECEIPT, CARD_TRANSACTION_UPDATE, or ACH_PAYMENT_UPDATE event stream. + - `OTHER`: A rule whose type is not exposed through this API. Rules of this type + are read-only; `OTHER` cannot be used when creating a rule. account_tokens: Account tokens to which the Auth Rule applies. @@ -131,7 +135,9 @@ def create( *, card_tokens: SequenceNotStr[str], parameters: v2_create_params.CardLevelRuleParameters, - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"], + type: Literal[ + "CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE", "OTHER" + ], 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. @@ -164,6 +170,8 @@ def create( - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, ACH_DEBIT_RECEIPT, CARD_TRANSACTION_UPDATE, or ACH_PAYMENT_UPDATE event stream. + - `OTHER`: A rule whose type is not exposed through this API. Rules of this type + are read-only; `OTHER` cannot be used when creating a rule. event_stream: The event stream during which the rule will be evaluated. @@ -185,7 +193,9 @@ def create( *, parameters: v2_create_params.ProgramLevelRuleParameters, program_level: bool, - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"], + type: Literal[ + "CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE", "OTHER" + ], event_stream: EventStream | Omit = omit, excluded_account_tokens: SequenceNotStr[str] | Omit = omit, excluded_business_account_tokens: SequenceNotStr[str] | Omit = omit, @@ -221,6 +231,8 @@ def create( - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, ACH_DEBIT_RECEIPT, CARD_TRANSACTION_UPDATE, or ACH_PAYMENT_UPDATE event stream. + - `OTHER`: A rule whose type is not exposed through this API. Rules of this type + are read-only; `OTHER` cannot be used when creating a rule. event_stream: The event stream during which the rule will be evaluated. @@ -251,7 +263,9 @@ 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", "TYPESCRIPT_CODE"], + type: Literal[ + "CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE", "OTHER" + ], account_tokens: SequenceNotStr[str] | Omit = omit, business_account_tokens: SequenceNotStr[str] | Omit = omit, event_stream: EventStream | Omit = omit, @@ -957,7 +971,9 @@ async def create( self, *, parameters: v2_create_params.AccountLevelRuleParameters, - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"], + type: Literal[ + "CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE", "OTHER" + ], account_tokens: SequenceNotStr[str] | Omit = omit, business_account_tokens: SequenceNotStr[str] | Omit = omit, event_stream: EventStream | Omit = omit, @@ -990,6 +1006,8 @@ async def create( - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, ACH_DEBIT_RECEIPT, CARD_TRANSACTION_UPDATE, or ACH_PAYMENT_UPDATE event stream. + - `OTHER`: A rule whose type is not exposed through this API. Rules of this type + are read-only; `OTHER` cannot be used when creating a rule. account_tokens: Account tokens to which the Auth Rule applies. @@ -1015,7 +1033,9 @@ async def create( *, card_tokens: SequenceNotStr[str], parameters: v2_create_params.CardLevelRuleParameters, - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"], + type: Literal[ + "CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE", "OTHER" + ], 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. @@ -1048,6 +1068,8 @@ async def create( - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, ACH_DEBIT_RECEIPT, CARD_TRANSACTION_UPDATE, or ACH_PAYMENT_UPDATE event stream. + - `OTHER`: A rule whose type is not exposed through this API. Rules of this type + are read-only; `OTHER` cannot be used when creating a rule. event_stream: The event stream during which the rule will be evaluated. @@ -1069,7 +1091,9 @@ async def create( *, parameters: v2_create_params.ProgramLevelRuleParameters, program_level: bool, - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"], + type: Literal[ + "CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE", "OTHER" + ], event_stream: EventStream | Omit = omit, excluded_account_tokens: SequenceNotStr[str] | Omit = omit, excluded_business_account_tokens: SequenceNotStr[str] | Omit = omit, @@ -1105,6 +1129,8 @@ async def create( - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, ACH_DEBIT_RECEIPT, CARD_TRANSACTION_UPDATE, or ACH_PAYMENT_UPDATE event stream. + - `OTHER`: A rule whose type is not exposed through this API. Rules of this type + are read-only; `OTHER` cannot be used when creating a rule. event_stream: The event stream during which the rule will be evaluated. @@ -1135,7 +1161,9 @@ 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", "TYPESCRIPT_CODE"], + type: Literal[ + "CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE", "OTHER" + ], account_tokens: SequenceNotStr[str] | Omit = omit, business_account_tokens: SequenceNotStr[str] | Omit = omit, event_stream: EventStream | Omit = omit, diff --git a/src/lithic/types/auth_rules/auth_rule.py b/src/lithic/types/auth_rules/auth_rule.py index c3ab6ff8..961f14b2 100644 --- a/src/lithic/types/auth_rules/auth_rule.py +++ b/src/lithic/types/auth_rules/auth_rule.py @@ -126,7 +126,9 @@ class AuthRule(BaseModel): state: Literal["ACTIVE", "INACTIVE"] """The state of the Auth Rule""" - type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"] + type: Literal[ + "CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE", "OTHER" + ] """The type of Auth Rule. For certain rule types, this determines the event stream during which it will be @@ -143,6 +145,8 @@ class AuthRule(BaseModel): - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, ACH_DEBIT_RECEIPT, CARD_TRANSACTION_UPDATE, or ACH_PAYMENT_UPDATE event stream. + - `OTHER`: A rule whose type is not exposed through this API. Rules of this type + are read-only; `OTHER` cannot be used when creating a rule. """ excluded_account_tokens: Optional[List[str]] = None diff --git a/src/lithic/types/auth_rules/v2_create_params.py b/src/lithic/types/auth_rules/v2_create_params.py index bb4cfaee..924f3eb8 100644 --- a/src/lithic/types/auth_rules/v2_create_params.py +++ b/src/lithic/types/auth_rules/v2_create_params.py @@ -37,7 +37,9 @@ class AccountLevelRule(TypedDict, total=False): """Parameters for the Auth Rule""" type: Required[ - Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"] + Literal[ + "CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE", "OTHER" + ] ] """The type of Auth Rule. @@ -55,6 +57,8 @@ class AccountLevelRule(TypedDict, total=False): - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, ACH_DEBIT_RECEIPT, CARD_TRANSACTION_UPDATE, or ACH_PAYMENT_UPDATE event stream. + - `OTHER`: A rule whose type is not exposed through this API. Rules of this type + are read-only; `OTHER` cannot be used when creating a rule. """ account_tokens: SequenceNotStr[str] @@ -93,7 +97,9 @@ class CardLevelRule(TypedDict, total=False): """Parameters for the Auth Rule""" type: Required[ - Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"] + Literal[ + "CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE", "OTHER" + ] ] """The type of Auth Rule. @@ -111,6 +117,8 @@ class CardLevelRule(TypedDict, total=False): - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, ACH_DEBIT_RECEIPT, CARD_TRANSACTION_UPDATE, or ACH_PAYMENT_UPDATE event stream. + - `OTHER`: A rule whose type is not exposed through this API. Rules of this type + are read-only; `OTHER` cannot be used when creating a rule. """ event_stream: EventStream @@ -143,7 +151,9 @@ class ProgramLevelRule(TypedDict, total=False): """Whether the Auth Rule applies to all authorizations on the card program.""" type: Required[ - Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"] + Literal[ + "CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE", "OTHER" + ] ] """The type of Auth Rule. @@ -161,6 +171,8 @@ class ProgramLevelRule(TypedDict, total=False): - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION, ACH_CREDIT_RECEIPT, ACH_DEBIT_RECEIPT, CARD_TRANSACTION_UPDATE, or ACH_PAYMENT_UPDATE event stream. + - `OTHER`: A rule whose type is not exposed through this API. Rules of this type + are read-only; `OTHER` cannot be used when creating a rule. """ event_stream: EventStream From 945f5aed2a5ddf72dac4319d65cc0c87c86ca172 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 3 Sep 2026 16:13:18 +0000 Subject: [PATCH 02/14] feat(api): add EXTERNAL_STABLECOIN category and events to external_payments/account_activity --- .stats.yml | 4 +-- src/lithic/resources/account_activity.py | 2 ++ src/lithic/resources/external_payments.py | 32 ++++++++++++++++--- .../types/account_activity_list_params.py | 1 + .../types/account_activity_list_response.py | 1 + ..._activity_retrieve_transaction_response.py | 1 + src/lithic/types/external_payment.py | 13 +++++++- .../types/external_payment_create_params.py | 8 ++++- .../types/external_payment_list_params.py | 8 ++++- .../statements/statement_line_items.py | 6 ++++ src/lithic/types/payment.py | 1 + src/lithic/types/shared/financial_event.py | 5 +++ 12 files changed, 73 insertions(+), 9 deletions(-) diff --git a/.stats.yml b/.stats.yml index 3961ab04..010a2f92 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 215 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-9a4064ca9be1efe3e33d922cae77a5d186b6a0119ef1d3601b5ded1447feb7f7.yml -openapi_spec_hash: bff457821129b2eb4fc5150e23efa197 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-61d6a4ff8361065995b3a743d6034b7deb3d307e3f3d0c9ef24010dd1b71d692.yml +openapi_spec_hash: 736b5c82d6b4a14788140fe05e0fbc30 config_hash: 27fa50e251754c8982e3dc615ef6da41 diff --git a/src/lithic/resources/account_activity.py b/src/lithic/resources/account_activity.py index 87fd95b3..ded43c2a 100644 --- a/src/lithic/resources/account_activity.py +++ b/src/lithic/resources/account_activity.py @@ -64,6 +64,7 @@ def list( "EXTERNAL_CHECK", "EXTERNAL_FEDNOW", "EXTERNAL_RTP", + "EXTERNAL_STABLECOIN", "EXTERNAL_TRANSFER", "EXTERNAL_WIRE", "MANAGEMENT_ADJUSTMENT", @@ -238,6 +239,7 @@ def list( "EXTERNAL_CHECK", "EXTERNAL_FEDNOW", "EXTERNAL_RTP", + "EXTERNAL_STABLECOIN", "EXTERNAL_TRANSFER", "EXTERNAL_WIRE", "MANAGEMENT_ADJUSTMENT", diff --git a/src/lithic/resources/external_payments.py b/src/lithic/resources/external_payments.py index 19116fd9..5c7bb388 100644 --- a/src/lithic/resources/external_payments.py +++ b/src/lithic/resources/external_payments.py @@ -54,7 +54,13 @@ def create( *, amount: int, category: Literal[ - "EXTERNAL_WIRE", "EXTERNAL_ACH", "EXTERNAL_CHECK", "EXTERNAL_FEDNOW", "EXTERNAL_RTP", "EXTERNAL_TRANSFER" + "EXTERNAL_WIRE", + "EXTERNAL_ACH", + "EXTERNAL_CHECK", + "EXTERNAL_FEDNOW", + "EXTERNAL_RTP", + "EXTERNAL_STABLECOIN", + "EXTERNAL_TRANSFER", ], effective_date: Union[str, date], financial_account_token: str, @@ -150,7 +156,13 @@ def list( begin: Union[str, datetime] | Omit = omit, business_account_token: str | Omit = omit, category: Literal[ - "EXTERNAL_WIRE", "EXTERNAL_ACH", "EXTERNAL_CHECK", "EXTERNAL_FEDNOW", "EXTERNAL_RTP", "EXTERNAL_TRANSFER" + "EXTERNAL_WIRE", + "EXTERNAL_ACH", + "EXTERNAL_CHECK", + "EXTERNAL_FEDNOW", + "EXTERNAL_RTP", + "EXTERNAL_STABLECOIN", + "EXTERNAL_TRANSFER", ] | Omit = omit, end: Union[str, datetime] | Omit = omit, @@ -442,7 +454,13 @@ async def create( *, amount: int, category: Literal[ - "EXTERNAL_WIRE", "EXTERNAL_ACH", "EXTERNAL_CHECK", "EXTERNAL_FEDNOW", "EXTERNAL_RTP", "EXTERNAL_TRANSFER" + "EXTERNAL_WIRE", + "EXTERNAL_ACH", + "EXTERNAL_CHECK", + "EXTERNAL_FEDNOW", + "EXTERNAL_RTP", + "EXTERNAL_STABLECOIN", + "EXTERNAL_TRANSFER", ], effective_date: Union[str, date], financial_account_token: str, @@ -538,7 +556,13 @@ def list( begin: Union[str, datetime] | Omit = omit, business_account_token: str | Omit = omit, category: Literal[ - "EXTERNAL_WIRE", "EXTERNAL_ACH", "EXTERNAL_CHECK", "EXTERNAL_FEDNOW", "EXTERNAL_RTP", "EXTERNAL_TRANSFER" + "EXTERNAL_WIRE", + "EXTERNAL_ACH", + "EXTERNAL_CHECK", + "EXTERNAL_FEDNOW", + "EXTERNAL_RTP", + "EXTERNAL_STABLECOIN", + "EXTERNAL_TRANSFER", ] | Omit = omit, end: Union[str, datetime] | Omit = omit, diff --git a/src/lithic/types/account_activity_list_params.py b/src/lithic/types/account_activity_list_params.py index 06ec7459..410e44d9 100644 --- a/src/lithic/types/account_activity_list_params.py +++ b/src/lithic/types/account_activity_list_params.py @@ -39,6 +39,7 @@ class AccountActivityListParams(TypedDict, total=False): "EXTERNAL_CHECK", "EXTERNAL_FEDNOW", "EXTERNAL_RTP", + "EXTERNAL_STABLECOIN", "EXTERNAL_TRANSFER", "EXTERNAL_WIRE", "MANAGEMENT_ADJUSTMENT", diff --git a/src/lithic/types/account_activity_list_response.py b/src/lithic/types/account_activity_list_response.py index 7f5ead1f..e2884279 100644 --- a/src/lithic/types/account_activity_list_response.py +++ b/src/lithic/types/account_activity_list_response.py @@ -38,6 +38,7 @@ class FinancialTransaction(BaseModel): "EXTERNAL_CHECK", "EXTERNAL_FEDNOW", "EXTERNAL_RTP", + "EXTERNAL_STABLECOIN", "EXTERNAL_TRANSFER", "EXTERNAL_WIRE", "MANAGEMENT_ADJUSTMENT", diff --git a/src/lithic/types/account_activity_retrieve_transaction_response.py b/src/lithic/types/account_activity_retrieve_transaction_response.py index ca0b5314..b347e17f 100644 --- a/src/lithic/types/account_activity_retrieve_transaction_response.py +++ b/src/lithic/types/account_activity_retrieve_transaction_response.py @@ -38,6 +38,7 @@ class FinancialTransaction(BaseModel): "EXTERNAL_CHECK", "EXTERNAL_FEDNOW", "EXTERNAL_RTP", + "EXTERNAL_STABLECOIN", "EXTERNAL_TRANSFER", "EXTERNAL_WIRE", "MANAGEMENT_ADJUSTMENT", diff --git a/src/lithic/types/external_payment.py b/src/lithic/types/external_payment.py index 47264c7d..367a184d 100644 --- a/src/lithic/types/external_payment.py +++ b/src/lithic/types/external_payment.py @@ -55,6 +55,11 @@ class Event(BaseModel): "EXTERNAL_RTP_SETTLED", "EXTERNAL_RTP_REVERSED", "EXTERNAL_RTP_RELEASED", + "EXTERNAL_STABLECOIN_INITIATED", + "EXTERNAL_STABLECOIN_CANCELED", + "EXTERNAL_STABLECOIN_SETTLED", + "EXTERNAL_STABLECOIN_REVERSED", + "EXTERNAL_STABLECOIN_RELEASED", ] @@ -73,7 +78,13 @@ class ExternalPayment(BaseModel): category: Optional[ Literal[ - "EXTERNAL_WIRE", "EXTERNAL_ACH", "EXTERNAL_CHECK", "EXTERNAL_FEDNOW", "EXTERNAL_RTP", "EXTERNAL_TRANSFER" + "EXTERNAL_WIRE", + "EXTERNAL_ACH", + "EXTERNAL_CHECK", + "EXTERNAL_FEDNOW", + "EXTERNAL_RTP", + "EXTERNAL_STABLECOIN", + "EXTERNAL_TRANSFER", ] ] = None diff --git a/src/lithic/types/external_payment_create_params.py b/src/lithic/types/external_payment_create_params.py index 294244e9..9ed6d55f 100644 --- a/src/lithic/types/external_payment_create_params.py +++ b/src/lithic/types/external_payment_create_params.py @@ -16,7 +16,13 @@ class ExternalPaymentCreateParams(TypedDict, total=False): category: Required[ Literal[ - "EXTERNAL_WIRE", "EXTERNAL_ACH", "EXTERNAL_CHECK", "EXTERNAL_FEDNOW", "EXTERNAL_RTP", "EXTERNAL_TRANSFER" + "EXTERNAL_WIRE", + "EXTERNAL_ACH", + "EXTERNAL_CHECK", + "EXTERNAL_FEDNOW", + "EXTERNAL_RTP", + "EXTERNAL_STABLECOIN", + "EXTERNAL_TRANSFER", ] ] diff --git a/src/lithic/types/external_payment_list_params.py b/src/lithic/types/external_payment_list_params.py index 13c3710b..09c4ce48 100644 --- a/src/lithic/types/external_payment_list_params.py +++ b/src/lithic/types/external_payment_list_params.py @@ -21,7 +21,13 @@ class ExternalPaymentListParams(TypedDict, total=False): business_account_token: str category: Literal[ - "EXTERNAL_WIRE", "EXTERNAL_ACH", "EXTERNAL_CHECK", "EXTERNAL_FEDNOW", "EXTERNAL_RTP", "EXTERNAL_TRANSFER" + "EXTERNAL_WIRE", + "EXTERNAL_ACH", + "EXTERNAL_CHECK", + "EXTERNAL_FEDNOW", + "EXTERNAL_RTP", + "EXTERNAL_STABLECOIN", + "EXTERNAL_TRANSFER", ] """The external rail the funds moved on""" 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 d62c53bf..ac265547 100644 --- a/src/lithic/types/financial_accounts/statements/statement_line_items.py +++ b/src/lithic/types/financial_accounts/statements/statement_line_items.py @@ -31,6 +31,7 @@ class Data(BaseModel): "EXTERNAL_CHECK", "EXTERNAL_FEDNOW", "EXTERNAL_RTP", + "EXTERNAL_STABLECOIN", "EXTERNAL_TRANSFER", "EXTERNAL_WIRE", "MANAGEMENT_ADJUSTMENT", @@ -114,6 +115,11 @@ class Data(BaseModel): "EXTERNAL_RTP_RELEASED", "EXTERNAL_RTP_REVERSED", "EXTERNAL_RTP_SETTLED", + "EXTERNAL_STABLECOIN_CANCELED", + "EXTERNAL_STABLECOIN_INITIATED", + "EXTERNAL_STABLECOIN_RELEASED", + "EXTERNAL_STABLECOIN_REVERSED", + "EXTERNAL_STABLECOIN_SETTLED", "EXTERNAL_TRANSFER_CANCELED", "EXTERNAL_TRANSFER_INITIATED", "EXTERNAL_TRANSFER_RELEASED", diff --git a/src/lithic/types/payment.py b/src/lithic/types/payment.py index 3b89c17c..63708ea5 100644 --- a/src/lithic/types/payment.py +++ b/src/lithic/types/payment.py @@ -273,6 +273,7 @@ class Payment(BaseModel): "EXTERNAL_CHECK", "EXTERNAL_FEDNOW", "EXTERNAL_RTP", + "EXTERNAL_STABLECOIN", "EXTERNAL_TRANSFER", "EXTERNAL_WIRE", "MANAGEMENT_ADJUSTMENT", diff --git a/src/lithic/types/shared/financial_event.py b/src/lithic/types/shared/financial_event.py index 9d677eb0..327414ad 100644 --- a/src/lithic/types/shared/financial_event.py +++ b/src/lithic/types/shared/financial_event.py @@ -85,6 +85,11 @@ class FinancialEvent(BaseModel): "EXTERNAL_RTP_RELEASED", "EXTERNAL_RTP_REVERSED", "EXTERNAL_RTP_SETTLED", + "EXTERNAL_STABLECOIN_CANCELED", + "EXTERNAL_STABLECOIN_INITIATED", + "EXTERNAL_STABLECOIN_RELEASED", + "EXTERNAL_STABLECOIN_REVERSED", + "EXTERNAL_STABLECOIN_SETTLED", "EXTERNAL_TRANSFER_CANCELED", "EXTERNAL_TRANSFER_INITIATED", "EXTERNAL_TRANSFER_RELEASED", From c7b557e0873ef183937d5c432f2a026e8fdd37c3 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 10 Sep 2026 15:53:32 +0000 Subject: [PATCH 03/14] feat: TRE-14429: Document the stablecoin payments endpoint --- .stats.yml | 8 +- api.md | 2 + src/lithic/resources/payments.py | 200 +++++++++++++++++- src/lithic/types/__init__.py | 2 + .../types/payment_create_stablecoin_params.py | 46 ++++ .../payment_create_stablecoin_response.py | 15 ++ src/lithic/types/payment_list_params.py | 2 +- tests/api_resources/test_payments.py | 107 ++++++++++ 8 files changed, 373 insertions(+), 9 deletions(-) create mode 100644 src/lithic/types/payment_create_stablecoin_params.py create mode 100644 src/lithic/types/payment_create_stablecoin_response.py diff --git a/.stats.yml b/.stats.yml index 010a2f92..e600cff2 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 215 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-61d6a4ff8361065995b3a743d6034b7deb3d307e3f3d0c9ef24010dd1b71d692.yml -openapi_spec_hash: 736b5c82d6b4a14788140fe05e0fbc30 -config_hash: 27fa50e251754c8982e3dc615ef6da41 +configured_endpoints: 216 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-70147140a7b2043acf622024eb3bde9b04264f8e9a695d4c79b5ee4db1534518.yml +openapi_spec_hash: 7a181cb1cfaaa201143bd9d04a841a2e +config_hash: e95c2dda5d175f9316457e0a84e35dce diff --git a/api.md b/api.md index de19390a..3ebe313e 100644 --- a/api.md +++ b/api.md @@ -711,6 +711,7 @@ Types: from lithic.types import ( Payment, PaymentCreateResponse, + PaymentCreateStablecoinResponse, PaymentRetryResponse, PaymentSimulateActionResponse, PaymentSimulateReceiptResponse, @@ -724,6 +725,7 @@ Methods: - client.payments.create(\*\*params) -> PaymentCreateResponse - client.payments.retrieve(payment_token) -> Payment - client.payments.list(\*\*params) -> SyncCursorPage[Payment] +- client.payments.create_stablecoin(\*\*params) -> PaymentCreateStablecoinResponse - client.payments.retry(payment_token) -> PaymentRetryResponse - client.payments.return\_(payment_token, \*\*params) -> Payment - client.payments.simulate_action(payment_token, \*\*params) -> PaymentSimulateActionResponse diff --git a/src/lithic/resources/payments.py b/src/lithic/resources/payments.py index bfe781ed..9418ef6f 100644 --- a/src/lithic/resources/payments.py +++ b/src/lithic/resources/payments.py @@ -17,6 +17,7 @@ payment_simulate_return_params, payment_simulate_receipt_params, payment_simulate_release_params, + payment_create_stablecoin_params, ) from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given from .._utils import path_template, maybe_transform, async_maybe_transform @@ -32,6 +33,7 @@ from ..types.payment_simulate_return_response import PaymentSimulateReturnResponse from ..types.payment_simulate_receipt_response import PaymentSimulateReceiptResponse from ..types.payment_simulate_release_response import PaymentSimulateReleaseResponse +from ..types.payment_create_stablecoin_response import PaymentCreateStablecoinResponse __all__ = ["Payments", "AsyncPayments"] @@ -77,7 +79,14 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PaymentCreateResponse: """ - Initiates a payment between a financial account and an external bank account. + Initiates an ACH payment between a financial account and an external bank + account. + + This endpoint originates on the ACH rail only. To send a stablecoin payout, use + the + [Create stablecoin payment](https://docs.lithic.com/reference/createstablecoinpayment) + endpoint. Payments on every rail are read back through + [List payments](https://docs.lithic.com/reference/searchpayments). Args: token: Customer-provided token that will serve as an idempotency token. This token will @@ -155,7 +164,7 @@ def list( account_token: str | Omit = omit, begin: Union[str, datetime] | Omit = omit, business_account_token: str | Omit = omit, - category: Literal["ACH"] | Omit = omit, + category: Literal["ACH", "STABLECOIN"] | Omit = omit, end: Union[str, datetime] | Omit = omit, ending_before: str | Omit = omit, financial_account_token: str | Omit = omit, @@ -224,6 +233,88 @@ def list( model=Payment, ) + def create_stablecoin( + self, + *, + amount: int, + blockchain_recipient_token: str, + financial_account_token: str, + type: Literal["PAYMENT"], + token: str | Omit = omit, + hold: payment_create_stablecoin_params.Hold | Omit = omit, + memo: 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, + ) -> PaymentCreateStablecoinResponse: + """ + Initiates a stablecoin payout from a financial account to a registered + blockchain recipient. + + The recipient must have been registered with + [Create blockchain recipient](https://docs.lithic.com/reference/createblockchainrecipient) + and have completed address screening — only a recipient in the `ENABLED` + verification state can receive a payout. The destination address and chain come + from the recipient, so they are not supplied here. + + Only payouts are initiated through this endpoint. Stablecoin pay-ins are + credited from on-chain deposits to a financial account's deposit address and are + not created through the API. Funds are placed on hold when the payout is + initiated, and a payout that fails on chain reverses that hold. A payout cannot + be cancelled once it has been submitted on chain. + + This endpoint is only available to stablecoin-enabled programs. Contact your + customer success manager to learn more. + + Args: + amount: Payout amount in cents + + blockchain_recipient_token: Token of the blockchain recipient to send the payout to. The recipient must be + in the `ENABLED` verification state + + financial_account_token: Token of the financial account the payout is funded from + + type: Direction of the payment. Stablecoin supports payouts only + + token: Customer-provided token that will serve as an idempotency token. This token will + become the transaction token + + hold: Optional hold to settle when this payout is initiated + + memo: Memo recorded on the payout. Defaults to `Stablecoin payout on ` when + omitted + + 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 + """ + return self._post( + "/v1/payments/stablecoin", + body=maybe_transform( + { + "amount": amount, + "blockchain_recipient_token": blockchain_recipient_token, + "financial_account_token": financial_account_token, + "type": type, + "token": token, + "hold": hold, + "memo": memo, + }, + payment_create_stablecoin_params.PaymentCreateStablecoinParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=PaymentCreateStablecoinResponse, + ) + def retry( self, payment_token: str, @@ -582,7 +673,14 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PaymentCreateResponse: """ - Initiates a payment between a financial account and an external bank account. + Initiates an ACH payment between a financial account and an external bank + account. + + This endpoint originates on the ACH rail only. To send a stablecoin payout, use + the + [Create stablecoin payment](https://docs.lithic.com/reference/createstablecoinpayment) + endpoint. Payments on every rail are read back through + [List payments](https://docs.lithic.com/reference/searchpayments). Args: token: Customer-provided token that will serve as an idempotency token. This token will @@ -660,7 +758,7 @@ def list( account_token: str | Omit = omit, begin: Union[str, datetime] | Omit = omit, business_account_token: str | Omit = omit, - category: Literal["ACH"] | Omit = omit, + category: Literal["ACH", "STABLECOIN"] | Omit = omit, end: Union[str, datetime] | Omit = omit, ending_before: str | Omit = omit, financial_account_token: str | Omit = omit, @@ -729,6 +827,88 @@ def list( model=Payment, ) + async def create_stablecoin( + self, + *, + amount: int, + blockchain_recipient_token: str, + financial_account_token: str, + type: Literal["PAYMENT"], + token: str | Omit = omit, + hold: payment_create_stablecoin_params.Hold | Omit = omit, + memo: 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, + ) -> PaymentCreateStablecoinResponse: + """ + Initiates a stablecoin payout from a financial account to a registered + blockchain recipient. + + The recipient must have been registered with + [Create blockchain recipient](https://docs.lithic.com/reference/createblockchainrecipient) + and have completed address screening — only a recipient in the `ENABLED` + verification state can receive a payout. The destination address and chain come + from the recipient, so they are not supplied here. + + Only payouts are initiated through this endpoint. Stablecoin pay-ins are + credited from on-chain deposits to a financial account's deposit address and are + not created through the API. Funds are placed on hold when the payout is + initiated, and a payout that fails on chain reverses that hold. A payout cannot + be cancelled once it has been submitted on chain. + + This endpoint is only available to stablecoin-enabled programs. Contact your + customer success manager to learn more. + + Args: + amount: Payout amount in cents + + blockchain_recipient_token: Token of the blockchain recipient to send the payout to. The recipient must be + in the `ENABLED` verification state + + financial_account_token: Token of the financial account the payout is funded from + + type: Direction of the payment. Stablecoin supports payouts only + + token: Customer-provided token that will serve as an idempotency token. This token will + become the transaction token + + hold: Optional hold to settle when this payout is initiated + + memo: Memo recorded on the payout. Defaults to `Stablecoin payout on ` when + omitted + + 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 + """ + return await self._post( + "/v1/payments/stablecoin", + body=await async_maybe_transform( + { + "amount": amount, + "blockchain_recipient_token": blockchain_recipient_token, + "financial_account_token": financial_account_token, + "type": type, + "token": token, + "hold": hold, + "memo": memo, + }, + payment_create_stablecoin_params.PaymentCreateStablecoinParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=PaymentCreateStablecoinResponse, + ) + async def retry( self, payment_token: str, @@ -1059,6 +1239,9 @@ def __init__(self, payments: Payments) -> None: self.list = _legacy_response.to_raw_response_wrapper( payments.list, ) + self.create_stablecoin = _legacy_response.to_raw_response_wrapper( + payments.create_stablecoin, + ) self.retry = _legacy_response.to_raw_response_wrapper( payments.retry, ) @@ -1092,6 +1275,9 @@ def __init__(self, payments: AsyncPayments) -> None: self.list = _legacy_response.async_to_raw_response_wrapper( payments.list, ) + self.create_stablecoin = _legacy_response.async_to_raw_response_wrapper( + payments.create_stablecoin, + ) self.retry = _legacy_response.async_to_raw_response_wrapper( payments.retry, ) @@ -1125,6 +1311,9 @@ def __init__(self, payments: Payments) -> None: self.list = to_streamed_response_wrapper( payments.list, ) + self.create_stablecoin = to_streamed_response_wrapper( + payments.create_stablecoin, + ) self.retry = to_streamed_response_wrapper( payments.retry, ) @@ -1158,6 +1347,9 @@ def __init__(self, payments: AsyncPayments) -> None: self.list = async_to_streamed_response_wrapper( payments.list, ) + self.create_stablecoin = async_to_streamed_response_wrapper( + payments.create_stablecoin, + ) self.retry = async_to_streamed_response_wrapper( payments.retry, ) diff --git a/src/lithic/types/__init__.py b/src/lithic/types/__init__.py index 2c670e3c..715d9661 100644 --- a/src/lithic/types/__init__.py +++ b/src/lithic/types/__init__.py @@ -167,6 +167,7 @@ from .payment_simulate_release_params import PaymentSimulateReleaseParams as PaymentSimulateReleaseParams from .management_operation_list_params import ManagementOperationListParams as ManagementOperationListParams from .management_operation_transaction import ManagementOperationTransaction as ManagementOperationTransaction +from .payment_create_stablecoin_params import PaymentCreateStablecoinParams as PaymentCreateStablecoinParams from .payment_simulate_action_response import PaymentSimulateActionResponse as PaymentSimulateActionResponse from .payment_simulate_return_response import PaymentSimulateReturnResponse as PaymentSimulateReturnResponse from .responder_endpoint_create_params import ResponderEndpointCreateParams as ResponderEndpointCreateParams @@ -179,6 +180,7 @@ from .tokenization_result_webhook_event import TokenizationResultWebhookEvent as TokenizationResultWebhookEvent from .blockchain_recipient_create_params import BlockchainRecipientCreateParams as BlockchainRecipientCreateParams from .management_operation_create_params import ManagementOperationCreateParams as ManagementOperationCreateParams +from .payment_create_stablecoin_response import PaymentCreateStablecoinResponse as PaymentCreateStablecoinResponse from .responder_endpoint_create_response import ResponderEndpointCreateResponse as ResponderEndpointCreateResponse from .tokenization_updated_webhook_event import TokenizationUpdatedWebhookEvent as TokenizationUpdatedWebhookEvent from .transaction_simulate_return_params import TransactionSimulateReturnParams as TransactionSimulateReturnParams diff --git a/src/lithic/types/payment_create_stablecoin_params.py b/src/lithic/types/payment_create_stablecoin_params.py new file mode 100644 index 00000000..aaba7e2f --- /dev/null +++ b/src/lithic/types/payment_create_stablecoin_params.py @@ -0,0 +1,46 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["PaymentCreateStablecoinParams", "Hold"] + + +class PaymentCreateStablecoinParams(TypedDict, total=False): + amount: Required[int] + """Payout amount in cents""" + + blockchain_recipient_token: Required[str] + """Token of the blockchain recipient to send the payout to. + + The recipient must be in the `ENABLED` verification state + """ + + financial_account_token: Required[str] + """Token of the financial account the payout is funded from""" + + type: Required[Literal["PAYMENT"]] + """Direction of the payment. Stablecoin supports payouts only""" + + token: str + """Customer-provided token that will serve as an idempotency token. + + This token will become the transaction token + """ + + hold: Hold + """Optional hold to settle when this payout is initiated""" + + memo: str + """Memo recorded on the payout. + + Defaults to `Stablecoin payout on ` when omitted + """ + + +class Hold(TypedDict, total=False): + """Optional hold to settle when this payout is initiated""" + + token: Required[str] + """Token of the hold to settle when this payout is initiated""" diff --git a/src/lithic/types/payment_create_stablecoin_response.py b/src/lithic/types/payment_create_stablecoin_response.py new file mode 100644 index 00000000..54d6938c --- /dev/null +++ b/src/lithic/types/payment_create_stablecoin_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from .balance import Balance +from .payment import Payment + +__all__ = ["PaymentCreateStablecoinResponse"] + + +class PaymentCreateStablecoinResponse(Payment): + """Payment transaction""" + + balance: Optional[Balance] = None + """Balance""" diff --git a/src/lithic/types/payment_list_params.py b/src/lithic/types/payment_list_params.py index 6c4fe92e..0723ace5 100644 --- a/src/lithic/types/payment_list_params.py +++ b/src/lithic/types/payment_list_params.py @@ -22,7 +22,7 @@ class PaymentListParams(TypedDict, total=False): business_account_token: str - category: Literal["ACH"] + category: Literal["ACH", "STABLECOIN"] end: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] """Date string in RFC 3339 format. diff --git a/tests/api_resources/test_payments.py b/tests/api_resources/test_payments.py index 40083d6f..5793c0d4 100644 --- a/tests/api_resources/test_payments.py +++ b/tests/api_resources/test_payments.py @@ -17,6 +17,7 @@ PaymentSimulateReturnResponse, PaymentSimulateReceiptResponse, PaymentSimulateReleaseResponse, + PaymentCreateStablecoinResponse, ) from lithic._utils import parse_date, parse_datetime from lithic.pagination import SyncCursorPage, AsyncCursorPage @@ -174,6 +175,59 @@ def test_streaming_response_list(self, client: Lithic) -> None: assert cast(Any, response.is_closed) is True + @parametrize + def test_method_create_stablecoin(self, client: Lithic) -> None: + payment = client.payments.create_stablecoin( + amount=1588, + blockchain_recipient_token="1e3fdb71-4b52-4a30-a7a9-52c85e26a1d9", + financial_account_token="35b0c466-a3e3-519a-9549-ead6a6a2277d", + type="PAYMENT", + ) + assert_matches_type(PaymentCreateStablecoinResponse, payment, path=["response"]) + + @parametrize + def test_method_create_stablecoin_with_all_params(self, client: Lithic) -> None: + payment = client.payments.create_stablecoin( + amount=1588, + blockchain_recipient_token="1e3fdb71-4b52-4a30-a7a9-52c85e26a1d9", + financial_account_token="35b0c466-a3e3-519a-9549-ead6a6a2277d", + type="PAYMENT", + token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + hold={"token": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}, + memo="Vendor payout", + ) + assert_matches_type(PaymentCreateStablecoinResponse, payment, path=["response"]) + + @parametrize + def test_raw_response_create_stablecoin(self, client: Lithic) -> None: + response = client.payments.with_raw_response.create_stablecoin( + amount=1588, + blockchain_recipient_token="1e3fdb71-4b52-4a30-a7a9-52c85e26a1d9", + financial_account_token="35b0c466-a3e3-519a-9549-ead6a6a2277d", + type="PAYMENT", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + payment = response.parse() + assert_matches_type(PaymentCreateStablecoinResponse, payment, path=["response"]) + + @parametrize + def test_streaming_response_create_stablecoin(self, client: Lithic) -> None: + with client.payments.with_streaming_response.create_stablecoin( + amount=1588, + blockchain_recipient_token="1e3fdb71-4b52-4a30-a7a9-52c85e26a1d9", + financial_account_token="35b0c466-a3e3-519a-9549-ead6a6a2277d", + type="PAYMENT", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + payment = response.parse() + assert_matches_type(PaymentCreateStablecoinResponse, payment, path=["response"]) + + assert cast(Any, response.is_closed) is True + @parametrize def test_method_retry(self, client: Lithic) -> None: payment = client.payments.retry( @@ -598,6 +652,59 @@ async def test_streaming_response_list(self, async_client: AsyncLithic) -> None: assert cast(Any, response.is_closed) is True + @parametrize + async def test_method_create_stablecoin(self, async_client: AsyncLithic) -> None: + payment = await async_client.payments.create_stablecoin( + amount=1588, + blockchain_recipient_token="1e3fdb71-4b52-4a30-a7a9-52c85e26a1d9", + financial_account_token="35b0c466-a3e3-519a-9549-ead6a6a2277d", + type="PAYMENT", + ) + assert_matches_type(PaymentCreateStablecoinResponse, payment, path=["response"]) + + @parametrize + async def test_method_create_stablecoin_with_all_params(self, async_client: AsyncLithic) -> None: + payment = await async_client.payments.create_stablecoin( + amount=1588, + blockchain_recipient_token="1e3fdb71-4b52-4a30-a7a9-52c85e26a1d9", + financial_account_token="35b0c466-a3e3-519a-9549-ead6a6a2277d", + type="PAYMENT", + token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + hold={"token": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}, + memo="Vendor payout", + ) + assert_matches_type(PaymentCreateStablecoinResponse, payment, path=["response"]) + + @parametrize + async def test_raw_response_create_stablecoin(self, async_client: AsyncLithic) -> None: + response = await async_client.payments.with_raw_response.create_stablecoin( + amount=1588, + blockchain_recipient_token="1e3fdb71-4b52-4a30-a7a9-52c85e26a1d9", + financial_account_token="35b0c466-a3e3-519a-9549-ead6a6a2277d", + type="PAYMENT", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + payment = response.parse() + assert_matches_type(PaymentCreateStablecoinResponse, payment, path=["response"]) + + @parametrize + async def test_streaming_response_create_stablecoin(self, async_client: AsyncLithic) -> None: + async with async_client.payments.with_streaming_response.create_stablecoin( + amount=1588, + blockchain_recipient_token="1e3fdb71-4b52-4a30-a7a9-52c85e26a1d9", + financial_account_token="35b0c466-a3e3-519a-9549-ead6a6a2277d", + type="PAYMENT", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + payment = await response.parse() + assert_matches_type(PaymentCreateStablecoinResponse, payment, path=["response"]) + + assert cast(Any, response.is_closed) is True + @parametrize async def test_method_retry(self, async_client: AsyncLithic) -> None: payment = await async_client.payments.retry( From 3cdcf9fec6517da95ac06beaf373bc9070a8704f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 10 Sep 2026 17:05:23 +0000 Subject: [PATCH 04/14] feat: TRE-14349: add installment plan management operation event types --- .stats.yml | 4 ++-- src/lithic/resources/management_operations.py | 4 ++++ .../financial_accounts/statements/statement_line_items.py | 2 ++ src/lithic/types/management_operation_create_params.py | 2 ++ src/lithic/types/management_operation_transaction.py | 2 ++ src/lithic/types/shared/financial_event.py | 2 ++ 6 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index e600cff2..a0ed4370 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 216 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-70147140a7b2043acf622024eb3bde9b04264f8e9a695d4c79b5ee4db1534518.yml -openapi_spec_hash: 7a181cb1cfaaa201143bd9d04a841a2e +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-17e70cd484ec2fc2aca1243462ac8849153dbbe9b9245959ff51681b14f74024.yml +openapi_spec_hash: cc75e169c1c5ddc9ed619de07ee94d70 config_hash: e95c2dda5d175f9316457e0a84e35dce diff --git a/src/lithic/resources/management_operations.py b/src/lithic/resources/management_operations.py index c5f7ee5f..47784ffd 100644 --- a/src/lithic/resources/management_operations.py +++ b/src/lithic/resources/management_operations.py @@ -67,6 +67,8 @@ def create( "CURRENCY_CONVERSION_REVERSAL", "INTEREST", "INTEREST_REVERSAL", + "INSTALLMENT_FEE", + "INSTALLMENT_FEE_REVERSAL", "LATE_PAYMENT", "LATE_PAYMENT_REVERSAL", "BILLING_ERROR", @@ -353,6 +355,8 @@ async def create( "CURRENCY_CONVERSION_REVERSAL", "INTEREST", "INTEREST_REVERSAL", + "INSTALLMENT_FEE", + "INSTALLMENT_FEE_REVERSAL", "LATE_PAYMENT", "LATE_PAYMENT_REVERSAL", "BILLING_ERROR", 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 ac265547..b7a495eb 100644 --- a/src/lithic/types/financial_accounts/statements/statement_line_items.py +++ b/src/lithic/types/financial_accounts/statements/statement_line_items.py @@ -132,6 +132,8 @@ class Data(BaseModel): "EXTERNAL_WIRE_SETTLED", "FINANCIAL_AUTHORIZATION", "FINANCIAL_CREDIT_AUTHORIZATION", + "INSTALLMENT_FEE", + "INSTALLMENT_FEE_REVERSAL", "INTEREST", "INTEREST_REVERSAL", "INTERNAL_ADJUSTMENT", diff --git a/src/lithic/types/management_operation_create_params.py b/src/lithic/types/management_operation_create_params.py index 2c1cdbc1..50bc9c31 100644 --- a/src/lithic/types/management_operation_create_params.py +++ b/src/lithic/types/management_operation_create_params.py @@ -37,6 +37,8 @@ class ManagementOperationCreateParams(TypedDict, total=False): "CURRENCY_CONVERSION_REVERSAL", "INTEREST", "INTEREST_REVERSAL", + "INSTALLMENT_FEE", + "INSTALLMENT_FEE_REVERSAL", "LATE_PAYMENT", "LATE_PAYMENT_REVERSAL", "BILLING_ERROR", diff --git a/src/lithic/types/management_operation_transaction.py b/src/lithic/types/management_operation_transaction.py index 16b8134a..547d0a4f 100644 --- a/src/lithic/types/management_operation_transaction.py +++ b/src/lithic/types/management_operation_transaction.py @@ -33,6 +33,8 @@ class Event(BaseModel): "CURRENCY_CONVERSION_REVERSAL", "INTEREST", "INTEREST_REVERSAL", + "INSTALLMENT_FEE", + "INSTALLMENT_FEE_REVERSAL", "LATE_PAYMENT", "LATE_PAYMENT_REVERSAL", "BILLING_ERROR", diff --git a/src/lithic/types/shared/financial_event.py b/src/lithic/types/shared/financial_event.py index 327414ad..542116aa 100644 --- a/src/lithic/types/shared/financial_event.py +++ b/src/lithic/types/shared/financial_event.py @@ -102,6 +102,8 @@ class FinancialEvent(BaseModel): "EXTERNAL_WIRE_SETTLED", "FINANCIAL_AUTHORIZATION", "FINANCIAL_CREDIT_AUTHORIZATION", + "INSTALLMENT_FEE", + "INSTALLMENT_FEE_REVERSAL", "INTEREST", "INTEREST_REVERSAL", "INTERNAL_ADJUSTMENT", From 8f1b51c992cf317ee4353a3244e347f02a666b0f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 10 Sep 2026 17:57:51 +0000 Subject: [PATCH 05/14] feat: Add missing blockchain/stablecoin endpoints to the spec --- .stats.yml | 8 +- api.md | 1 + src/lithic/resources/blockchain_recipients.py | 98 ++++++++++++++++++- .../test_blockchain_recipients.py | 80 +++++++++++++++ 4 files changed, 182 insertions(+), 5 deletions(-) diff --git a/.stats.yml b/.stats.yml index a0ed4370..8373f9a5 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 216 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-17e70cd484ec2fc2aca1243462ac8849153dbbe9b9245959ff51681b14f74024.yml -openapi_spec_hash: cc75e169c1c5ddc9ed619de07ee94d70 -config_hash: e95c2dda5d175f9316457e0a84e35dce +configured_endpoints: 217 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-c4c2ee9eddaa18ab29ef2d881e7c373d214d167b3eb7a74559f862ce36e95f74.yml +openapi_spec_hash: 3b1897cb075e1f19e2ce33e95781656a +config_hash: b314c3c5c82a483d1a7812b31b1d1fc4 diff --git a/api.md b/api.md index 3ebe313e..4857b2f2 100644 --- a/api.md +++ b/api.md @@ -702,6 +702,7 @@ from lithic.types import BlockchainRecipient Methods: - client.blockchain_recipients.create(\*\*params) -> BlockchainRecipient +- client.blockchain_recipients.retrieve(blockchain_recipient_token) -> BlockchainRecipient # Payments diff --git a/src/lithic/resources/blockchain_recipients.py b/src/lithic/resources/blockchain_recipients.py index 0a6b8e27..5be3cca5 100644 --- a/src/lithic/resources/blockchain_recipients.py +++ b/src/lithic/resources/blockchain_recipients.py @@ -7,7 +7,7 @@ from .. import _legacy_response from ..types import OwnerType, blockchain_recipient_create_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform +from .._utils import path_template, 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 @@ -108,6 +108,48 @@ def create( cast_to=BlockchainRecipient, ) + def retrieve( + self, + blockchain_recipient_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, + ) -> BlockchainRecipient: + """ + Get a blockchain recipient by token + + Use this to poll the `verification_state` after registering an address: a + recipient cannot receive a payout until screening completes and moves it out of + `PENDING` + + 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 blockchain_recipient_token: + raise ValueError( + f"Expected a non-empty value for `blockchain_recipient_token` but received {blockchain_recipient_token!r}" + ) + return self._get( + path_template( + "/v1/blockchain_recipients/{blockchain_recipient_token}", + blockchain_recipient_token=blockchain_recipient_token, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BlockchainRecipient, + ) + class AsyncBlockchainRecipients(AsyncAPIResource): @cached_property @@ -199,6 +241,48 @@ async def create( cast_to=BlockchainRecipient, ) + async def retrieve( + self, + blockchain_recipient_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, + ) -> BlockchainRecipient: + """ + Get a blockchain recipient by token + + Use this to poll the `verification_state` after registering an address: a + recipient cannot receive a payout until screening completes and moves it out of + `PENDING` + + 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 blockchain_recipient_token: + raise ValueError( + f"Expected a non-empty value for `blockchain_recipient_token` but received {blockchain_recipient_token!r}" + ) + return await self._get( + path_template( + "/v1/blockchain_recipients/{blockchain_recipient_token}", + blockchain_recipient_token=blockchain_recipient_token, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BlockchainRecipient, + ) + class BlockchainRecipientsWithRawResponse: def __init__(self, blockchain_recipients: BlockchainRecipients) -> None: @@ -207,6 +291,9 @@ def __init__(self, blockchain_recipients: BlockchainRecipients) -> None: self.create = _legacy_response.to_raw_response_wrapper( blockchain_recipients.create, ) + self.retrieve = _legacy_response.to_raw_response_wrapper( + blockchain_recipients.retrieve, + ) class AsyncBlockchainRecipientsWithRawResponse: @@ -216,6 +303,9 @@ def __init__(self, blockchain_recipients: AsyncBlockchainRecipients) -> None: self.create = _legacy_response.async_to_raw_response_wrapper( blockchain_recipients.create, ) + self.retrieve = _legacy_response.async_to_raw_response_wrapper( + blockchain_recipients.retrieve, + ) class BlockchainRecipientsWithStreamingResponse: @@ -225,6 +315,9 @@ def __init__(self, blockchain_recipients: BlockchainRecipients) -> None: self.create = to_streamed_response_wrapper( blockchain_recipients.create, ) + self.retrieve = to_streamed_response_wrapper( + blockchain_recipients.retrieve, + ) class AsyncBlockchainRecipientsWithStreamingResponse: @@ -234,3 +327,6 @@ def __init__(self, blockchain_recipients: AsyncBlockchainRecipients) -> None: self.create = async_to_streamed_response_wrapper( blockchain_recipients.create, ) + self.retrieve = async_to_streamed_response_wrapper( + blockchain_recipients.retrieve, + ) diff --git a/tests/api_resources/test_blockchain_recipients.py b/tests/api_resources/test_blockchain_recipients.py index 97b65d38..1f7efa7c 100644 --- a/tests/api_resources/test_blockchain_recipients.py +++ b/tests/api_resources/test_blockchain_recipients.py @@ -73,6 +73,46 @@ def test_streaming_response_create(self, client: Lithic) -> None: assert cast(Any, response.is_closed) is True + @parametrize + def test_method_retrieve(self, client: Lithic) -> None: + blockchain_recipient = client.blockchain_recipients.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(BlockchainRecipient, blockchain_recipient, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: Lithic) -> None: + response = client.blockchain_recipients.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" + blockchain_recipient = response.parse() + assert_matches_type(BlockchainRecipient, blockchain_recipient, path=["response"]) + + @parametrize + def test_streaming_response_retrieve(self, client: Lithic) -> None: + with client.blockchain_recipients.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" + + blockchain_recipient = response.parse() + assert_matches_type(BlockchainRecipient, blockchain_recipient, 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 `blockchain_recipient_token` but received ''" + ): + client.blockchain_recipients.with_raw_response.retrieve( + "", + ) + class TestAsyncBlockchainRecipients: parametrize = pytest.mark.parametrize( @@ -134,3 +174,43 @@ async def test_streaming_response_create(self, async_client: AsyncLithic) -> Non assert_matches_type(BlockchainRecipient, blockchain_recipient, path=["response"]) assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_retrieve(self, async_client: AsyncLithic) -> None: + blockchain_recipient = await async_client.blockchain_recipients.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(BlockchainRecipient, blockchain_recipient, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncLithic) -> None: + response = await async_client.blockchain_recipients.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" + blockchain_recipient = response.parse() + assert_matches_type(BlockchainRecipient, blockchain_recipient, path=["response"]) + + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncLithic) -> None: + async with async_client.blockchain_recipients.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" + + blockchain_recipient = await response.parse() + assert_matches_type(BlockchainRecipient, blockchain_recipient, 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 `blockchain_recipient_token` but received ''" + ): + await async_client.blockchain_recipients.with_raw_response.retrieve( + "", + ) From 14889dbf638b7d1b85e4b3145d8b3914cc87619a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 11 Sep 2026 15:28:56 +0000 Subject: [PATCH 06/14] feat(api): add card.pin_updated webhook event --- .stats.yml | 4 +-- api.md | 1 + src/lithic/resources/events/events.py | 2 ++ src/lithic/resources/events/subscriptions.py | 6 ++++ src/lithic/types/__init__.py | 1 + .../types/card_pin_updated_webhook_event.py | 30 +++++++++++++++++++ src/lithic/types/event.py | 3 ++ src/lithic/types/event_list_params.py | 1 + src/lithic/types/event_subscription.py | 1 + .../events/subscription_create_params.py | 1 + ...scription_send_simulated_example_params.py | 1 + .../events/subscription_update_params.py | 1 + src/lithic/types/parsed_webhook_event.py | 2 ++ 13 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 src/lithic/types/card_pin_updated_webhook_event.py diff --git a/.stats.yml b/.stats.yml index 8373f9a5..a3a73e4a 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 217 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-c4c2ee9eddaa18ab29ef2d881e7c373d214d167b3eb7a74559f862ce36e95f74.yml -openapi_spec_hash: 3b1897cb075e1f19e2ce33e95781656a +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-6acbf033ded2c03ed5d5c64b6bea9f3250323bf7879a11e9c545aa30e65b3cca.yml +openapi_spec_hash: c6007083223ccff12c5c15bc9e531b41 config_hash: b314c3c5c82a483d1a7812b31b1d1fc4 diff --git a/api.md b/api.md index 4857b2f2..dba2ce2d 100644 --- a/api.md +++ b/api.md @@ -1011,6 +1011,7 @@ from lithic.types import ( BookTransferTransactionUpdatedWebhookEvent, CardCreatedWebhookEvent, CardConvertedWebhookEvent, + CardPinUpdatedWebhookEvent, CardRenewedWebhookEvent, CardReissuedWebhookEvent, CardShippedWebhookEvent, diff --git a/src/lithic/resources/events/events.py b/src/lithic/resources/events/events.py index 36fd0dbc..ae1d55c8 100644 --- a/src/lithic/resources/events/events.py +++ b/src/lithic/resources/events/events.py @@ -123,6 +123,7 @@ def list( "card_transaction.updated", "card.converted", "card.created", + "card.pin_updated", "card.reissued", "card.renewed", "card.shipped", @@ -406,6 +407,7 @@ def list( "card_transaction.updated", "card.converted", "card.created", + "card.pin_updated", "card.reissued", "card.renewed", "card.shipped", diff --git a/src/lithic/resources/events/subscriptions.py b/src/lithic/resources/events/subscriptions.py index bb5390ad..5c128852 100644 --- a/src/lithic/resources/events/subscriptions.py +++ b/src/lithic/resources/events/subscriptions.py @@ -75,6 +75,7 @@ def create( "card_transaction.updated", "card.converted", "card.created", + "card.pin_updated", "card.reissued", "card.renewed", "card.shipped", @@ -230,6 +231,7 @@ def update( "card_transaction.updated", "card.converted", "card.created", + "card.pin_updated", "card.reissued", "card.renewed", "card.shipped", @@ -708,6 +710,7 @@ def send_simulated_example( "card_transaction.updated", "card.converted", "card.created", + "card.pin_updated", "card.reissued", "card.renewed", "card.shipped", @@ -840,6 +843,7 @@ async def create( "card_transaction.updated", "card.converted", "card.created", + "card.pin_updated", "card.reissued", "card.renewed", "card.shipped", @@ -995,6 +999,7 @@ async def update( "card_transaction.updated", "card.converted", "card.created", + "card.pin_updated", "card.reissued", "card.renewed", "card.shipped", @@ -1473,6 +1478,7 @@ async def send_simulated_example( "card_transaction.updated", "card.converted", "card.created", + "card.pin_updated", "card.reissued", "card.renewed", "card.shipped", diff --git a/src/lithic/types/__init__.py b/src/lithic/types/__init__.py index 715d9661..30be65e9 100644 --- a/src/lithic/types/__init__.py +++ b/src/lithic/types/__init__.py @@ -152,6 +152,7 @@ from .account_activity_list_response import AccountActivityListResponse as AccountActivityListResponse from .account_holder_create_response import AccountHolderCreateResponse as AccountHolderCreateResponse from .account_holder_update_response import AccountHolderUpdateResponse as AccountHolderUpdateResponse +from .card_pin_updated_webhook_event import CardPinUpdatedWebhookEvent as CardPinUpdatedWebhookEvent from .external_payment_cancel_params import ExternalPaymentCancelParams as ExternalPaymentCancelParams from .external_payment_create_params import ExternalPaymentCreateParams as ExternalPaymentCreateParams from .external_payment_settle_params import ExternalPaymentSettleParams as ExternalPaymentSettleParams diff --git a/src/lithic/types/card_pin_updated_webhook_event.py b/src/lithic/types/card_pin_updated_webhook_event.py new file mode 100644 index 00000000..33be0ff4 --- /dev/null +++ b/src/lithic/types/card_pin_updated_webhook_event.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from .._models import BaseModel + +__all__ = ["CardPinUpdatedWebhookEvent"] + + +class CardPinUpdatedWebhookEvent(BaseModel): + card_token: str + """The token of the card whose PIN or PIN status was updated""" + + event_type: Literal["card.pin_updated"] + """The type of event that occurred.""" + + pin_status: Literal["OK", "BLOCKED"] + """The card's PIN status after the update""" + + status_reason: Literal["PIN_SET", "PIN_CHANGED", "PIN_UNBLOCKED", "EXCESSIVE_PIN_ATTEMPTS"] + """The reason for the PIN update: + + - `PIN_SET` - The PIN was set for the first time; `pin_status` is `OK` + - `PIN_CHANGED` - The PIN was changed, including when changing a blocked PIN; + `pin_status` is `OK` + - `PIN_UNBLOCKED` - The PIN was unblocked without changing it; `pin_status` is + `OK` + - `EXCESSIVE_PIN_ATTEMPTS` - The PIN was blocked due to excessive incorrect PIN + attempts; `pin_status` is `BLOCKED` + """ diff --git a/src/lithic/types/event.py b/src/lithic/types/event.py index dcbd1046..9ae25185 100644 --- a/src/lithic/types/event.py +++ b/src/lithic/types/event.py @@ -37,6 +37,7 @@ class Event(BaseModel): "card_transaction.updated", "card.converted", "card.created", + "card.pin_updated", "card.reissued", "card.renewed", "card.shipped", @@ -112,6 +113,8 @@ class Event(BaseModel): - card.converted: Occurs when a card is converted from virtual to physical cards. - card.created: Occurs when a new card is created. + - card.pin_updated: Occurs when a card's PIN is set, changed, unblocked, or + blocked due to excessive incorrect PIN attempts. - card.reissued: Occurs when a card is reissued. - card.renewed: Occurs when a card is renewed. - card.shipped: Occurs when a card is shipped. diff --git a/src/lithic/types/event_list_params.py b/src/lithic/types/event_list_params.py index 8f4b11ef..a162c6b2 100644 --- a/src/lithic/types/event_list_params.py +++ b/src/lithic/types/event_list_params.py @@ -47,6 +47,7 @@ class EventListParams(TypedDict, total=False): "card_transaction.updated", "card.converted", "card.created", + "card.pin_updated", "card.reissued", "card.renewed", "card.shipped", diff --git a/src/lithic/types/event_subscription.py b/src/lithic/types/event_subscription.py index a8349d20..39384f23 100644 --- a/src/lithic/types/event_subscription.py +++ b/src/lithic/types/event_subscription.py @@ -40,6 +40,7 @@ class EventSubscription(BaseModel): "card_transaction.updated", "card.converted", "card.created", + "card.pin_updated", "card.reissued", "card.renewed", "card.shipped", diff --git a/src/lithic/types/events/subscription_create_params.py b/src/lithic/types/events/subscription_create_params.py index 00f5ccbf..6ae0e7d7 100644 --- a/src/lithic/types/events/subscription_create_params.py +++ b/src/lithic/types/events/subscription_create_params.py @@ -35,6 +35,7 @@ class SubscriptionCreateParams(TypedDict, total=False): "card_transaction.updated", "card.converted", "card.created", + "card.pin_updated", "card.reissued", "card.renewed", "card.shipped", 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 5fdb92c0..8013dee6 100644 --- a/src/lithic/types/events/subscription_send_simulated_example_params.py +++ b/src/lithic/types/events/subscription_send_simulated_example_params.py @@ -24,6 +24,7 @@ class SubscriptionSendSimulatedExampleParams(TypedDict, total=False): "card_transaction.updated", "card.converted", "card.created", + "card.pin_updated", "card.reissued", "card.renewed", "card.shipped", diff --git a/src/lithic/types/events/subscription_update_params.py b/src/lithic/types/events/subscription_update_params.py index 6571ac66..53fa683d 100644 --- a/src/lithic/types/events/subscription_update_params.py +++ b/src/lithic/types/events/subscription_update_params.py @@ -35,6 +35,7 @@ class SubscriptionUpdateParams(TypedDict, total=False): "card_transaction.updated", "card.converted", "card.created", + "card.pin_updated", "card.reissued", "card.renewed", "card.shipped", diff --git a/src/lithic/types/parsed_webhook_event.py b/src/lithic/types/parsed_webhook_event.py index 3959e4a3..c0a535b2 100644 --- a/src/lithic/types/parsed_webhook_event.py +++ b/src/lithic/types/parsed_webhook_event.py @@ -17,6 +17,7 @@ from .card_converted_webhook_event import CardConvertedWebhookEvent from .balance_updated_webhook_event import BalanceUpdatedWebhookEvent from .dispute_updated_webhook_event import DisputeUpdatedWebhookEvent +from .card_pin_updated_webhook_event import CardPinUpdatedWebhookEvent from .loan_tape_created_webhook_event import LoanTapeCreatedWebhookEvent from .loan_tape_updated_webhook_event import LoanTapeUpdatedWebhookEvent from .statements_created_webhook_event import StatementsCreatedWebhookEvent @@ -448,6 +449,7 @@ class LegacyPayload(BaseModel): BookTransferTransactionUpdatedWebhookEvent, CardCreatedWebhookEvent, CardConvertedWebhookEvent, + CardPinUpdatedWebhookEvent, CardRenewedWebhookEvent, CardReissuedWebhookEvent, CardShippedWebhookEvent, From 7da6f4449fc8a5e018e8cc6483400a3383f3df4e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 11 Sep 2026 17:41:48 +0000 Subject: [PATCH 07/14] feat(api): add psd2_context field and types to three_ds_authentication --- .stats.yml | 4 +- src/lithic/types/three_ds_authentication.py | 63 +++++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index a3a73e4a..da1c1969 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 217 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-6acbf033ded2c03ed5d5c64b6bea9f3250323bf7879a11e9c545aa30e65b3cca.yml -openapi_spec_hash: c6007083223ccff12c5c15bc9e531b41 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-e1085922e2d7ee4ce3122f1d9dfe675877f5551a591630592cfea38bd6fea9ed.yml +openapi_spec_hash: e9ca63bde70f9e3953e0a135e7daf185 config_hash: b314c3c5c82a483d1a7812b31b1d1fc4 diff --git a/src/lithic/types/three_ds_authentication.py b/src/lithic/types/three_ds_authentication.py index 3aebc6f8..81b37b74 100644 --- a/src/lithic/types/three_ds_authentication.py +++ b/src/lithic/types/three_ds_authentication.py @@ -17,6 +17,7 @@ "App", "Browser", "ChallengeMetadata", + "Psd2Context", "Transaction", ] @@ -401,6 +402,61 @@ class ChallengeMetadata(BaseModel): """The phone number used for delivering the OTP. Relevant only for SMS_OTP method.""" +class Psd2Context(BaseModel): + """PSD2/SCA context for EEA and UK transactions. + + Present when Lithic determines the transaction is in scope for PSD2 Strong Customer Authentication. Absent for out-of-scope transactions. + """ + + acquirer_exemption: Optional[ + Literal[ + "NONE", + "TRANSACTION_RISK_ANALYSIS", + "LOW_VALUE", + "RECURRING_PAYMENT", + "MERCHANT_INITIATED_TRANSACTION", + "TRUSTED_BENEFICIARY", + "STRONG_CUSTOMER_AUTHENTICATION_DELEGATION", + "SECURE_CORPORATE_PAYMENT", + "AUTHENTICATION_OUTAGE_EXCEPTION", + "BUNDLED", + ] + ] = None + """SCA exemption declared by the acquirer in the 3DS authentication request. + + - `NONE` - No exemption claimed + - `TRANSACTION_RISK_ANALYSIS` - Transaction Risk Analysis (TRA) exemption; + acquirer asserts low fraud risk + - `LOW_VALUE` - Low-value payment exemption; transaction is below the EUR 30 + threshold + - `RECURRING_PAYMENT` - Recurring payment with a fixed amount to the same payee + - `MERCHANT_INITIATED_TRANSACTION` - Merchant-initiated transaction (MIT); + cardholder not present + - `TRUSTED_BENEFICIARY` - Trusted beneficiary; merchant is on cardholder's + whitelist + - `STRONG_CUSTOMER_AUTHENTICATION_DELEGATION` - SCA already performed by a + delegated third-party authenticator + - `SECURE_CORPORATE_PAYMENT` - Secure corporate payment using a dedicated + corporate card or process + - `AUTHENTICATION_OUTAGE_EXCEPTION` - Authentication outage exception; + scheme-level fallback during ACS downtime + - `BUNDLED` - Mastercard only; bundled exemption code where the exact exemption + type cannot be distinguished + """ + + lithic_exemption_validation: Optional[Literal["ACCEPTED", "REJECTED", "NOT_VALIDATED"]] = None + """Lithic's validation of the acquirer-declared exemption. + + Absent when no acquirer exemption was declared. + + - `ACCEPTED` - Lithic signals support the acquirer's claim + - `REJECTED` - Lithic signals contradict the claim, or a required signal is + missing + - `NOT_VALIDATED` - Exemption was declared but Lithic has no basis to evaluate + it; treated as `REJECTED` for challenge purposes + """ + + class Transaction(BaseModel): """ Object containing data about the e-commerce transaction for which the merchant is requesting authentication. @@ -593,6 +649,13 @@ class ThreeDSAuthentication(BaseModel): (e.g. in-flight customer decisioning request). """ + psd2_context: Optional[Psd2Context] = None + """PSD2/SCA context for EEA and UK transactions. + + Present when Lithic determines the transaction is in scope for PSD2 Strong + Customer Authentication. Absent for out-of-scope transactions. + """ + three_ri_request_type: Optional[ Literal[ "ACCOUNT_VERIFICATION", From 60c6b8eefa05208966212c0cc205ef0019f115ac Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 15 Sep 2026 18:00:32 +0000 Subject: [PATCH 08/14] feat: [CARDS-5174] Add reiusse/renew 409 error --- .stats.yml | 4 ++-- src/lithic/resources/cards/cards.py | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.stats.yml b/.stats.yml index da1c1969..ff7d0860 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 217 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-e1085922e2d7ee4ce3122f1d9dfe675877f5551a591630592cfea38bd6fea9ed.yml -openapi_spec_hash: e9ca63bde70f9e3953e0a135e7daf185 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-d25e38eb235b2a76fb0920a6316f134eeb541476224cf9d2b8bf7e899d06f9f4.yml +openapi_spec_hash: 7b64684e889ae161a1354dc34f3499dd config_hash: b314c3c5c82a483d1a7812b31b1d1fc4 diff --git a/src/lithic/resources/cards/cards.py b/src/lithic/resources/cards/cards.py index 05bfae1e..b60d3852 100644 --- a/src/lithic/resources/cards/cards.py +++ b/src/lithic/resources/cards/cards.py @@ -1012,7 +1012,8 @@ def reissue( physically damaged). The PAN, expiry, and CVC2 will remain the same and the original card can continue to be used until the new card is activated. Only applies to cards of type `PHYSICAL`. A card can be reissued or renewed a total - of 8 times. + of 8 times. Returns `409` if the card is still ongoing manufacturing when using + Thales as a manufacturer. Args: carrier: If omitted, the previous carrier will be used. @@ -1097,7 +1098,8 @@ def renew( `PHYSICAL` card can be reissued or renewed a total of 8 times. For `VIRTUAL`, the card will retain the same card token and PAN and receive an updated expiry and CVC2 code. `product_id`, `shipping_method`, `shipping_address`, `carrier` - are only relevant for renewing `PHYSICAL` cards. + are only relevant for renewing `PHYSICAL` cards. Returns `409` if the card is + still ongoing manufacturing when using Thales as a manufacturer. Args: shipping_address: The shipping address this card will be sent to. @@ -2289,7 +2291,8 @@ async def reissue( physically damaged). The PAN, expiry, and CVC2 will remain the same and the original card can continue to be used until the new card is activated. Only applies to cards of type `PHYSICAL`. A card can be reissued or renewed a total - of 8 times. + of 8 times. Returns `409` if the card is still ongoing manufacturing when using + Thales as a manufacturer. Args: carrier: If omitted, the previous carrier will be used. @@ -2374,7 +2377,8 @@ async def renew( `PHYSICAL` card can be reissued or renewed a total of 8 times. For `VIRTUAL`, the card will retain the same card token and PAN and receive an updated expiry and CVC2 code. `product_id`, `shipping_method`, `shipping_address`, `carrier` - are only relevant for renewing `PHYSICAL` cards. + are only relevant for renewing `PHYSICAL` cards. Returns `409` if the card is + still ongoing manufacturing when using Thales as a manufacturer. Args: shipping_address: The shipping address this card will be sent to. From dc065e43f9c025156c5ca142a9a222b5e0305354 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 15 Sep 2026 18:30:41 +0000 Subject: [PATCH 09/14] feat(api): add STABLECOIN_REVIEWED event type to payments simulate_action --- .stats.yml | 4 ++-- src/lithic/resources/payments.py | 2 ++ src/lithic/types/payment_simulate_action_params.py | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index ff7d0860..84c4edd8 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 217 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-d25e38eb235b2a76fb0920a6316f134eeb541476224cf9d2b8bf7e899d06f9f4.yml -openapi_spec_hash: 7b64684e889ae161a1354dc34f3499dd +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-da0eed08089ca63f636cb174cdabe65591f65bb8a16bd5db94439834cc509044.yml +openapi_spec_hash: 2f7de4d9c35540a1d0163b75b4c08f6d config_hash: b314c3c5c82a483d1a7812b31b1d1fc4 diff --git a/src/lithic/resources/payments.py b/src/lithic/resources/payments.py index 9418ef6f..5ffa727e 100644 --- a/src/lithic/resources/payments.py +++ b/src/lithic/resources/payments.py @@ -440,6 +440,7 @@ def simulate_action( "ACH_RETURN_INITIATED", "ACH_RETURN_PROCESSED", "ACH_RETURN_SETTLED", + "STABLECOIN_REVIEWED", ], date_of_death: Union[str, date] | Omit = omit, decline_reason: Literal[ @@ -1034,6 +1035,7 @@ async def simulate_action( "ACH_RETURN_INITIATED", "ACH_RETURN_PROCESSED", "ACH_RETURN_SETTLED", + "STABLECOIN_REVIEWED", ], date_of_death: Union[str, date] | Omit = omit, decline_reason: Literal[ diff --git a/src/lithic/types/payment_simulate_action_params.py b/src/lithic/types/payment_simulate_action_params.py index b5500957..37581dc4 100644 --- a/src/lithic/types/payment_simulate_action_params.py +++ b/src/lithic/types/payment_simulate_action_params.py @@ -24,6 +24,7 @@ class PaymentSimulateActionParams(TypedDict, total=False): "ACH_RETURN_INITIATED", "ACH_RETURN_PROCESSED", "ACH_RETURN_SETTLED", + "STABLECOIN_REVIEWED", ] ] """Event Type""" From 445299db5e0bbce6d2a5611a4cb752ac141dd77e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 15 Sep 2026 19:22:52 +0000 Subject: [PATCH 10/14] feat: AUTH-3759: Add DECLINE_SCA_REQUIRED and SCA_REQUIRED enum entries --- .stats.yml | 4 ++-- src/lithic/types/auth_rules/report_stats.py | 1 + src/lithic/types/auth_rules/v2_list_results_response.py | 1 + src/lithic/types/transaction.py | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 84c4edd8..90a58107 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 217 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-da0eed08089ca63f636cb174cdabe65591f65bb8a16bd5db94439834cc509044.yml -openapi_spec_hash: 2f7de4d9c35540a1d0163b75b4c08f6d +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-22e6715ab0428fcbda66e78f701a4324634ac8934106a450c50a341a4ad75a39.yml +openapi_spec_hash: 3c728da2d5bf1544686a6f09a0e3e393 config_hash: b314c3c5c82a483d1a7812b31b1d1fc4 diff --git a/src/lithic/types/auth_rules/report_stats.py b/src/lithic/types/auth_rules/report_stats.py index d8a1bdb7..46cfb36a 100644 --- a/src/lithic/types/auth_rules/report_stats.py +++ b/src/lithic/types/auth_rules/report_stats.py @@ -68,6 +68,7 @@ class ExampleActionDeclineActionAuthorization(BaseModel): "PROGRAM_SUSPENDED", "PROGRAM_USAGE_RESTRICTION", "REVERSAL_UNMATCHED", + "SCA_REQUIRED", "SECURITY_VIOLATION", "SINGLE_USE_CARD_REATTEMPTED", "SUSPECTED_FRAUD", diff --git a/src/lithic/types/auth_rules/v2_list_results_response.py b/src/lithic/types/auth_rules/v2_list_results_response.py index c42048e1..a5704f39 100644 --- a/src/lithic/types/auth_rules/v2_list_results_response.py +++ b/src/lithic/types/auth_rules/v2_list_results_response.py @@ -81,6 +81,7 @@ class AuthorizationResultActionDeclineActionAuthorization(BaseModel): "PROGRAM_SUSPENDED", "PROGRAM_USAGE_RESTRICTION", "REVERSAL_UNMATCHED", + "SCA_REQUIRED", "SECURITY_VIOLATION", "SINGLE_USE_CARD_REATTEMPTED", "SUSPECTED_FRAUD", diff --git a/src/lithic/types/transaction.py b/src/lithic/types/transaction.py index a12e94df..6cffa54c 100644 --- a/src/lithic/types/transaction.py +++ b/src/lithic/types/transaction.py @@ -450,6 +450,7 @@ class EventRuleResult(BaseModel): "PROGRAM_SUSPENDED", "PROGRAM_USAGE_RESTRICTION", "REVERSAL_UNMATCHED", + "SCA_REQUIRED", "SECURITY_VIOLATION", "SINGLE_USE_CARD_REATTEMPTED", "SUSPECTED_FRAUD", @@ -565,6 +566,7 @@ class Event(BaseModel): "PROGRAM_SUSPENDED", "PROGRAM_USAGE_RESTRICTION", "REVERSAL_UNMATCHED", + "SCA_REQUIRED", "SECURITY_VIOLATION", "SINGLE_USE_CARD_REATTEMPTED", "SUSPECTED_FRAUD", From 615daa4be69ee4aab3fb1bc992635b335077ad92 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 16 Sep 2026 13:56:49 +0000 Subject: [PATCH 11/14] feat(api): add FEE/FEE_REVERSAL enum values to management_operations and financial events --- .stats.yml | 4 ++-- src/lithic/resources/management_operations.py | 4 ++++ .../financial_accounts/statements/statement_line_items.py | 2 ++ src/lithic/types/management_operation_create_params.py | 2 ++ src/lithic/types/management_operation_transaction.py | 2 ++ src/lithic/types/shared/financial_event.py | 2 ++ 6 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 90a58107..bab0dfd3 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 217 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-22e6715ab0428fcbda66e78f701a4324634ac8934106a450c50a341a4ad75a39.yml -openapi_spec_hash: 3c728da2d5bf1544686a6f09a0e3e393 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-cc426da9e5047cbcd8e764a20ea1afd35c685ebaedc87128f0a22f9f05ae1537.yml +openapi_spec_hash: 731d6efde305387fde11ba31972f176b config_hash: b314c3c5c82a483d1a7812b31b1d1fc4 diff --git a/src/lithic/resources/management_operations.py b/src/lithic/resources/management_operations.py index 47784ffd..c518b745 100644 --- a/src/lithic/resources/management_operations.py +++ b/src/lithic/resources/management_operations.py @@ -87,6 +87,8 @@ def create( "QUARTERLY_REVERSAL", "MONTHLY", "MONTHLY_REVERSAL", + "FEE", + "FEE_REVERSAL", ], financial_account_token: str, token: str | Omit = omit, @@ -375,6 +377,8 @@ async def create( "QUARTERLY_REVERSAL", "MONTHLY", "MONTHLY_REVERSAL", + "FEE", + "FEE_REVERSAL", ], financial_account_token: str, token: str | Omit = omit, 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 b7a495eb..7f10bab7 100644 --- a/src/lithic/types/financial_accounts/statements/statement_line_items.py +++ b/src/lithic/types/financial_accounts/statements/statement_line_items.py @@ -130,6 +130,8 @@ class Data(BaseModel): "EXTERNAL_WIRE_RELEASED", "EXTERNAL_WIRE_REVERSED", "EXTERNAL_WIRE_SETTLED", + "FEE", + "FEE_REVERSAL", "FINANCIAL_AUTHORIZATION", "FINANCIAL_CREDIT_AUTHORIZATION", "INSTALLMENT_FEE", diff --git a/src/lithic/types/management_operation_create_params.py b/src/lithic/types/management_operation_create_params.py index 50bc9c31..5595b308 100644 --- a/src/lithic/types/management_operation_create_params.py +++ b/src/lithic/types/management_operation_create_params.py @@ -57,6 +57,8 @@ class ManagementOperationCreateParams(TypedDict, total=False): "QUARTERLY_REVERSAL", "MONTHLY", "MONTHLY_REVERSAL", + "FEE", + "FEE_REVERSAL", ] ] diff --git a/src/lithic/types/management_operation_transaction.py b/src/lithic/types/management_operation_transaction.py index 547d0a4f..68d4f01e 100644 --- a/src/lithic/types/management_operation_transaction.py +++ b/src/lithic/types/management_operation_transaction.py @@ -53,6 +53,8 @@ class Event(BaseModel): "QUARTERLY_REVERSAL", "MONTHLY", "MONTHLY_REVERSAL", + "FEE", + "FEE_REVERSAL", ] subtype: Optional[str] = None diff --git a/src/lithic/types/shared/financial_event.py b/src/lithic/types/shared/financial_event.py index 542116aa..ba5b9f7f 100644 --- a/src/lithic/types/shared/financial_event.py +++ b/src/lithic/types/shared/financial_event.py @@ -100,6 +100,8 @@ class FinancialEvent(BaseModel): "EXTERNAL_WIRE_RELEASED", "EXTERNAL_WIRE_REVERSED", "EXTERNAL_WIRE_SETTLED", + "FEE", + "FEE_REVERSAL", "FINANCIAL_AUTHORIZATION", "FINANCIAL_CREDIT_AUTHORIZATION", "INSTALLMENT_FEE", From 9ac74418812660394107e068a012a373a9f81460 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 16 Sep 2026 21:46:16 +0000 Subject: [PATCH 12/14] feat: [TRE-14464] Update /retry payments endpoint to accept method --- .stats.yml | 4 +-- api.md | 2 +- src/lithic/resources/payments.py | 13 ++++++++++ src/lithic/types/__init__.py | 1 + src/lithic/types/payment_retry_params.py | 17 +++++++++++++ tests/api_resources/test_payments.py | 32 ++++++++++++++++++------ 6 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 src/lithic/types/payment_retry_params.py diff --git a/.stats.yml b/.stats.yml index bab0dfd3..f61c2150 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 217 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-cc426da9e5047cbcd8e764a20ea1afd35c685ebaedc87128f0a22f9f05ae1537.yml -openapi_spec_hash: 731d6efde305387fde11ba31972f176b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-701e31821e8acdd56e8afce852fd2207ef6962cc314fdc1e9d814adf8aae8e1f.yml +openapi_spec_hash: ddf405339b9f603c2ebc58a0a168bfbd config_hash: b314c3c5c82a483d1a7812b31b1d1fc4 diff --git a/api.md b/api.md index dba2ce2d..7aa53746 100644 --- a/api.md +++ b/api.md @@ -727,7 +727,7 @@ Methods: - client.payments.retrieve(payment_token) -> Payment - client.payments.list(\*\*params) -> SyncCursorPage[Payment] - client.payments.create_stablecoin(\*\*params) -> PaymentCreateStablecoinResponse -- client.payments.retry(payment_token) -> PaymentRetryResponse +- client.payments.retry(payment_token, \*\*params) -> PaymentRetryResponse - client.payments.return\_(payment_token, \*\*params) -> Payment - client.payments.simulate_action(payment_token, \*\*params) -> PaymentSimulateActionResponse - client.payments.simulate_receipt(\*\*params) -> PaymentSimulateReceiptResponse diff --git a/src/lithic/resources/payments.py b/src/lithic/resources/payments.py index 5ffa727e..e8a6a72a 100644 --- a/src/lithic/resources/payments.py +++ b/src/lithic/resources/payments.py @@ -11,6 +11,7 @@ from .. import _legacy_response from ..types import ( payment_list_params, + payment_retry_params, payment_create_params, payment_return_params, payment_simulate_action_params, @@ -319,6 +320,7 @@ def retry( self, payment_token: str, *, + method: Literal["ACH_NEXT_DAY", "ACH_SAME_DAY"] | 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, @@ -330,6 +332,10 @@ def retry( Retry an origination which has been returned. Args: + method: Settlement speed to retry the payment at. Defaults to the original payment's + method. An `ACH_SAME_DAY` retry is rejected if the payment is for $1,000,000.00 + or more, or if it is submitted after the same day ACH cutoff + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -342,6 +348,7 @@ def retry( raise ValueError(f"Expected a non-empty value for `payment_token` but received {payment_token!r}") return self._post( path_template("/v1/payments/{payment_token}/retry", payment_token=payment_token), + body=maybe_transform({"method": method}, payment_retry_params.PaymentRetryParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -914,6 +921,7 @@ async def retry( self, payment_token: str, *, + method: Literal["ACH_NEXT_DAY", "ACH_SAME_DAY"] | 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, @@ -925,6 +933,10 @@ async def retry( Retry an origination which has been returned. Args: + method: Settlement speed to retry the payment at. Defaults to the original payment's + method. An `ACH_SAME_DAY` retry is rejected if the payment is for $1,000,000.00 + or more, or if it is submitted after the same day ACH cutoff + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -937,6 +949,7 @@ async def retry( raise ValueError(f"Expected a non-empty value for `payment_token` but received {payment_token!r}") return await self._post( path_template("/v1/payments/{payment_token}/retry", payment_token=payment_token), + body=await async_maybe_transform({"method": method}, payment_retry_params.PaymentRetryParams), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), diff --git a/src/lithic/types/__init__.py b/src/lithic/types/__init__.py index 30be65e9..1c8fbe72 100644 --- a/src/lithic/types/__init__.py +++ b/src/lithic/types/__init__.py @@ -81,6 +81,7 @@ from .blockchain_recipient import BlockchainRecipient as BlockchainRecipient from .internal_transaction import InternalTransaction as InternalTransaction from .parsed_webhook_event import ParsedWebhookEvent as ParsedWebhookEvent +from .payment_retry_params import PaymentRetryParams as PaymentRetryParams from .spend_limit_duration import SpendLimitDuration as SpendLimitDuration from .account_update_params import AccountUpdateParams as AccountUpdateParams from .card_provision_params import CardProvisionParams as CardProvisionParams diff --git a/src/lithic/types/payment_retry_params.py b/src/lithic/types/payment_retry_params.py new file mode 100644 index 00000000..fc0400b5 --- /dev/null +++ b/src/lithic/types/payment_retry_params.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["PaymentRetryParams"] + + +class PaymentRetryParams(TypedDict, total=False): + method: Literal["ACH_NEXT_DAY", "ACH_SAME_DAY"] + """Settlement speed to retry the payment at. + + Defaults to the original payment's method. An `ACH_SAME_DAY` retry is rejected + if the payment is for $1,000,000.00 or more, or if it is submitted after the + same day ACH cutoff + """ diff --git a/tests/api_resources/test_payments.py b/tests/api_resources/test_payments.py index 5793c0d4..c24aebab 100644 --- a/tests/api_resources/test_payments.py +++ b/tests/api_resources/test_payments.py @@ -231,14 +231,22 @@ def test_streaming_response_create_stablecoin(self, client: Lithic) -> None: @parametrize def test_method_retry(self, client: Lithic) -> None: payment = client.payments.retry( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payment_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(PaymentRetryResponse, payment, path=["response"]) + + @parametrize + def test_method_retry_with_all_params(self, client: Lithic) -> None: + payment = client.payments.retry( + payment_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + method="ACH_SAME_DAY", ) assert_matches_type(PaymentRetryResponse, payment, path=["response"]) @parametrize def test_raw_response_retry(self, client: Lithic) -> None: response = client.payments.with_raw_response.retry( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payment_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -249,7 +257,7 @@ def test_raw_response_retry(self, client: Lithic) -> None: @parametrize def test_streaming_response_retry(self, client: Lithic) -> None: with client.payments.with_streaming_response.retry( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payment_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -263,7 +271,7 @@ def test_streaming_response_retry(self, client: Lithic) -> None: def test_path_params_retry(self, client: Lithic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `payment_token` but received ''"): client.payments.with_raw_response.retry( - "", + payment_token="", ) @parametrize @@ -708,14 +716,22 @@ async def test_streaming_response_create_stablecoin(self, async_client: AsyncLit @parametrize async def test_method_retry(self, async_client: AsyncLithic) -> None: payment = await async_client.payments.retry( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payment_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(PaymentRetryResponse, payment, path=["response"]) + + @parametrize + async def test_method_retry_with_all_params(self, async_client: AsyncLithic) -> None: + payment = await async_client.payments.retry( + payment_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + method="ACH_SAME_DAY", ) assert_matches_type(PaymentRetryResponse, payment, path=["response"]) @parametrize async def test_raw_response_retry(self, async_client: AsyncLithic) -> None: response = await async_client.payments.with_raw_response.retry( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payment_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True @@ -726,7 +742,7 @@ async def test_raw_response_retry(self, async_client: AsyncLithic) -> None: @parametrize async def test_streaming_response_retry(self, async_client: AsyncLithic) -> None: async with async_client.payments.with_streaming_response.retry( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payment_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -740,7 +756,7 @@ async def test_streaming_response_retry(self, async_client: AsyncLithic) -> None async def test_path_params_retry(self, async_client: AsyncLithic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `payment_token` but received ''"): await async_client.payments.with_raw_response.retry( - "", + payment_token="", ) @parametrize From 001bd06bbd7c7274e6a1c59f4adcb9e86959b74e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 17 Sep 2026 20:15:07 +0000 Subject: [PATCH 13/14] feat: [TRE-14524] Add Open to buy API spec --- .stats.yml | 8 +- api.md | 12 ++ .../resources/financial_accounts/__init__.py | 14 ++ .../financial_accounts/financial_accounts.py | 32 +++ .../financial_accounts/open_to_buy.py | 194 ++++++++++++++++++ .../types/financial_accounts/__init__.py | 2 + .../types/financial_accounts/open_to_buy.py | 21 ++ .../financial_accounts/open_to_buy_summary.py | 33 +++ .../financial_accounts/test_open_to_buy.py | 104 ++++++++++ 9 files changed, 416 insertions(+), 4 deletions(-) create mode 100644 src/lithic/resources/financial_accounts/open_to_buy.py create mode 100644 src/lithic/types/financial_accounts/open_to_buy.py create mode 100644 src/lithic/types/financial_accounts/open_to_buy_summary.py create mode 100644 tests/api_resources/financial_accounts/test_open_to_buy.py diff --git a/.stats.yml b/.stats.yml index f61c2150..c360f978 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 217 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-701e31821e8acdd56e8afce852fd2207ef6962cc314fdc1e9d814adf8aae8e1f.yml -openapi_spec_hash: ddf405339b9f603c2ebc58a0a168bfbd -config_hash: b314c3c5c82a483d1a7812b31b1d1fc4 +configured_endpoints: 218 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic/lithic-18e08b593c738bb6a429fe225dac7c4bf5d161a7dbb003e495b87a21d2aff6a8.yml +openapi_spec_hash: b6f308ea5a6d9ad9c22c14e7574d9669 +config_hash: 0cfee7faa13d28e91697e2d79c50935e diff --git a/api.md b/api.md index 7aa53746..194a63e7 100644 --- a/api.md +++ b/api.md @@ -479,6 +479,18 @@ Methods: - client.financial_accounts.balances.list(financial_account_token, \*\*params) -> SyncSinglePage[FinancialAccountBalance] +## OpenToBuy + +Types: + +```python +from lithic.types.financial_accounts import OpenToBuy, OpenToBuySummary +``` + +Methods: + +- client.financial_accounts.open_to_buy.retrieve(financial_account_token) -> OpenToBuy + ## FinancialTransactions Methods: diff --git a/src/lithic/resources/financial_accounts/__init__.py b/src/lithic/resources/financial_accounts/__init__.py index 74f0a994..cd2caa18 100644 --- a/src/lithic/resources/financial_accounts/__init__.py +++ b/src/lithic/resources/financial_accounts/__init__.py @@ -24,6 +24,14 @@ StatementsWithStreamingResponse, AsyncStatementsWithStreamingResponse, ) +from .open_to_buy import ( + OpenToBuyResource, + AsyncOpenToBuyResource, + OpenToBuyResourceWithRawResponse, + AsyncOpenToBuyResourceWithRawResponse, + OpenToBuyResourceWithStreamingResponse, + AsyncOpenToBuyResourceWithStreamingResponse, +) from .financial_accounts import ( FinancialAccounts, AsyncFinancialAccounts, @@ -72,6 +80,12 @@ "AsyncBalancesWithRawResponse", "BalancesWithStreamingResponse", "AsyncBalancesWithStreamingResponse", + "OpenToBuyResource", + "AsyncOpenToBuyResource", + "OpenToBuyResourceWithRawResponse", + "AsyncOpenToBuyResourceWithRawResponse", + "OpenToBuyResourceWithStreamingResponse", + "AsyncOpenToBuyResourceWithStreamingResponse", "FinancialTransactions", "AsyncFinancialTransactions", "FinancialTransactionsWithRawResponse", diff --git a/src/lithic/resources/financial_accounts/financial_accounts.py b/src/lithic/resources/financial_accounts/financial_accounts.py index fd5998be..6cd19bee 100644 --- a/src/lithic/resources/financial_accounts/financial_accounts.py +++ b/src/lithic/resources/financial_accounts/financial_accounts.py @@ -36,6 +36,14 @@ ) from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper +from .open_to_buy import ( + OpenToBuyResource, + AsyncOpenToBuyResource, + OpenToBuyResourceWithRawResponse, + AsyncOpenToBuyResourceWithRawResponse, + OpenToBuyResourceWithStreamingResponse, + AsyncOpenToBuyResourceWithStreamingResponse, +) from ...pagination import SyncSinglePage, AsyncSinglePage from ..._base_client import AsyncPaginator, make_request_options from .credit_configuration import ( @@ -88,6 +96,10 @@ class FinancialAccounts(SyncAPIResource): def balances(self) -> Balances: return Balances(self._client) + @cached_property + def open_to_buy(self) -> OpenToBuyResource: + return OpenToBuyResource(self._client) + @cached_property def financial_transactions(self) -> FinancialTransactions: return FinancialTransactions(self._client) @@ -415,6 +427,10 @@ class AsyncFinancialAccounts(AsyncAPIResource): def balances(self) -> AsyncBalances: return AsyncBalances(self._client) + @cached_property + def open_to_buy(self) -> AsyncOpenToBuyResource: + return AsyncOpenToBuyResource(self._client) + @cached_property def financial_transactions(self) -> AsyncFinancialTransactions: return AsyncFinancialTransactions(self._client) @@ -766,6 +782,10 @@ def __init__(self, financial_accounts: FinancialAccounts) -> None: def balances(self) -> BalancesWithRawResponse: return BalancesWithRawResponse(self._financial_accounts.balances) + @cached_property + def open_to_buy(self) -> OpenToBuyResourceWithRawResponse: + return OpenToBuyResourceWithRawResponse(self._financial_accounts.open_to_buy) + @cached_property def financial_transactions(self) -> FinancialTransactionsWithRawResponse: return FinancialTransactionsWithRawResponse(self._financial_accounts.financial_transactions) @@ -818,6 +838,10 @@ def __init__(self, financial_accounts: AsyncFinancialAccounts) -> None: def balances(self) -> AsyncBalancesWithRawResponse: return AsyncBalancesWithRawResponse(self._financial_accounts.balances) + @cached_property + def open_to_buy(self) -> AsyncOpenToBuyResourceWithRawResponse: + return AsyncOpenToBuyResourceWithRawResponse(self._financial_accounts.open_to_buy) + @cached_property def financial_transactions(self) -> AsyncFinancialTransactionsWithRawResponse: return AsyncFinancialTransactionsWithRawResponse(self._financial_accounts.financial_transactions) @@ -870,6 +894,10 @@ def __init__(self, financial_accounts: FinancialAccounts) -> None: def balances(self) -> BalancesWithStreamingResponse: return BalancesWithStreamingResponse(self._financial_accounts.balances) + @cached_property + def open_to_buy(self) -> OpenToBuyResourceWithStreamingResponse: + return OpenToBuyResourceWithStreamingResponse(self._financial_accounts.open_to_buy) + @cached_property def financial_transactions(self) -> FinancialTransactionsWithStreamingResponse: return FinancialTransactionsWithStreamingResponse(self._financial_accounts.financial_transactions) @@ -922,6 +950,10 @@ def __init__(self, financial_accounts: AsyncFinancialAccounts) -> None: def balances(self) -> AsyncBalancesWithStreamingResponse: return AsyncBalancesWithStreamingResponse(self._financial_accounts.balances) + @cached_property + def open_to_buy(self) -> AsyncOpenToBuyResourceWithStreamingResponse: + return AsyncOpenToBuyResourceWithStreamingResponse(self._financial_accounts.open_to_buy) + @cached_property def financial_transactions(self) -> AsyncFinancialTransactionsWithStreamingResponse: return AsyncFinancialTransactionsWithStreamingResponse(self._financial_accounts.financial_transactions) diff --git a/src/lithic/resources/financial_accounts/open_to_buy.py b/src/lithic/resources/financial_accounts/open_to_buy.py new file mode 100644 index 00000000..d57227cb --- /dev/null +++ b/src/lithic/resources/financial_accounts/open_to_buy.py @@ -0,0 +1,194 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ... import _legacy_response +from ..._types import Body, Query, Headers, NotGiven, not_given +from ..._utils import path_template +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper +from ..._base_client import make_request_options +from ...types.financial_accounts.open_to_buy import OpenToBuy + +__all__ = ["OpenToBuyResource", "AsyncOpenToBuyResource"] + + +class OpenToBuyResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> OpenToBuyResourceWithRawResponse: + """ + 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 OpenToBuyResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> OpenToBuyResourceWithStreamingResponse: + """ + 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 OpenToBuyResourceWithStreamingResponse(self) + + def retrieve( + self, + financial_account_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, + ) -> OpenToBuy: + """ + Get the funds available for card spend backed by a given Security Account, along + with the balances that amount is derived from. + + Open to buy is the amount Lithic authorizes card spend against. It is not a + stored balance, so it is recalculated on every request from the Security + Account, the funds held against spend Lithic has already paid out to the + networks on your behalf, and the spend that has not yet been collected. The + accounts that feed the calculation depend on your program setup, so + `summary.settled_funds` is `null` outside Commercial Charge. + + Supported for Commercial Charge, Dynamic Reserve, and Secured Charge programs. + Returns `404` if `financial_account_token` is not a Security Account you own, or + if your program setup does not use an open to buy calculation. + + 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 financial_account_token: + raise ValueError( + f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" + ) + return self._get( + path_template( + "/v1/financial_accounts/{financial_account_token}/open_to_buy", + financial_account_token=financial_account_token, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=OpenToBuy, + ) + + +class AsyncOpenToBuyResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncOpenToBuyResourceWithRawResponse: + """ + 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 AsyncOpenToBuyResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncOpenToBuyResourceWithStreamingResponse: + """ + 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 AsyncOpenToBuyResourceWithStreamingResponse(self) + + async def retrieve( + self, + financial_account_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, + ) -> OpenToBuy: + """ + Get the funds available for card spend backed by a given Security Account, along + with the balances that amount is derived from. + + Open to buy is the amount Lithic authorizes card spend against. It is not a + stored balance, so it is recalculated on every request from the Security + Account, the funds held against spend Lithic has already paid out to the + networks on your behalf, and the spend that has not yet been collected. The + accounts that feed the calculation depend on your program setup, so + `summary.settled_funds` is `null` outside Commercial Charge. + + Supported for Commercial Charge, Dynamic Reserve, and Secured Charge programs. + Returns `404` if `financial_account_token` is not a Security Account you own, or + if your program setup does not use an open to buy calculation. + + 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 financial_account_token: + raise ValueError( + f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}" + ) + return await self._get( + path_template( + "/v1/financial_accounts/{financial_account_token}/open_to_buy", + financial_account_token=financial_account_token, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=OpenToBuy, + ) + + +class OpenToBuyResourceWithRawResponse: + def __init__(self, open_to_buy: OpenToBuyResource) -> None: + self._open_to_buy = open_to_buy + + self.retrieve = _legacy_response.to_raw_response_wrapper( + open_to_buy.retrieve, + ) + + +class AsyncOpenToBuyResourceWithRawResponse: + def __init__(self, open_to_buy: AsyncOpenToBuyResource) -> None: + self._open_to_buy = open_to_buy + + self.retrieve = _legacy_response.async_to_raw_response_wrapper( + open_to_buy.retrieve, + ) + + +class OpenToBuyResourceWithStreamingResponse: + def __init__(self, open_to_buy: OpenToBuyResource) -> None: + self._open_to_buy = open_to_buy + + self.retrieve = to_streamed_response_wrapper( + open_to_buy.retrieve, + ) + + +class AsyncOpenToBuyResourceWithStreamingResponse: + def __init__(self, open_to_buy: AsyncOpenToBuyResource) -> None: + self._open_to_buy = open_to_buy + + self.retrieve = async_to_streamed_response_wrapper( + open_to_buy.retrieve, + ) diff --git a/src/lithic/types/financial_accounts/__init__.py b/src/lithic/types/financial_accounts/__init__.py index 1938293c..5b460f67 100644 --- a/src/lithic/types/financial_accounts/__init__.py +++ b/src/lithic/types/financial_accounts/__init__.py @@ -5,8 +5,10 @@ from .loan_tape import LoanTape as LoanTape from .statement import Statement as Statement from .statements import Statements as Statements +from .open_to_buy import OpenToBuy as OpenToBuy from .category_balances import CategoryBalances as CategoryBalances from .balance_list_params import BalanceListParams as BalanceListParams +from .open_to_buy_summary import OpenToBuySummary as OpenToBuySummary from .loan_tape_list_params import LoanTapeListParams as LoanTapeListParams from .statement_list_params import StatementListParams as StatementListParams from .interest_tier_schedule import InterestTierSchedule as InterestTierSchedule diff --git a/src/lithic/types/financial_accounts/open_to_buy.py b/src/lithic/types/financial_accounts/open_to_buy.py new file mode 100644 index 00000000..26755e9e --- /dev/null +++ b/src/lithic/types/financial_accounts/open_to_buy.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..._models import BaseModel +from .open_to_buy_summary import OpenToBuySummary + +__all__ = ["OpenToBuy"] + + +class OpenToBuy(BaseModel): + """Open to Buy""" + + open_to_buy: int + """ + Funds available for card spend backed by this Security Account, in the + currency's smallest unit (e.g., cents for USD). Equal to the sum of the amounts + in `summary`, and reaches zero once outstanding spend has consumed all available + funding + """ + + summary: OpenToBuySummary + """Balances that open to buy is derived from""" diff --git a/src/lithic/types/financial_accounts/open_to_buy_summary.py b/src/lithic/types/financial_accounts/open_to_buy_summary.py new file mode 100644 index 00000000..5b9d8eaf --- /dev/null +++ b/src/lithic/types/financial_accounts/open_to_buy_summary.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from ..._models import BaseModel + +__all__ = ["OpenToBuySummary"] + + +class OpenToBuySummary(BaseModel): + """Open to Buy Summary""" + + security: int + """ + Available balance of the Security Account backing card spend, in the currency's + smallest unit (e.g., cents for USD) + """ + + settled_funds: Optional[int] = None + """ + Funding that has moved out of the Security Account to cover card spend Lithic + has already paid out to the networks, in the currency's smallest unit (e.g., + cents for USD). Open to buy counts it alongside `security`, and it clears once + collected from your business clients. Only Commercial Charge tracks this + separately, so this is `null` for every other program setup + """ + + total_outstanding_spend: int + """ + Customer card spend that has not yet been collected, in the currency's smallest + unit (e.g., cents for USD). Reported as a negative amount, because it reduces + open to buy + """ diff --git a/tests/api_resources/financial_accounts/test_open_to_buy.py b/tests/api_resources/financial_accounts/test_open_to_buy.py new file mode 100644 index 00000000..0dc20f6e --- /dev/null +++ b/tests/api_resources/financial_accounts/test_open_to_buy.py @@ -0,0 +1,104 @@ +# 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.financial_accounts import OpenToBuy + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestOpenToBuy: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_retrieve(self, client: Lithic) -> None: + open_to_buy = client.financial_accounts.open_to_buy.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(OpenToBuy, open_to_buy, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: Lithic) -> None: + response = client.financial_accounts.open_to_buy.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" + open_to_buy = response.parse() + assert_matches_type(OpenToBuy, open_to_buy, path=["response"]) + + @parametrize + def test_streaming_response_retrieve(self, client: Lithic) -> None: + with client.financial_accounts.open_to_buy.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" + + open_to_buy = response.parse() + assert_matches_type(OpenToBuy, open_to_buy, 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 `financial_account_token` but received ''" + ): + client.financial_accounts.open_to_buy.with_raw_response.retrieve( + "", + ) + + +class TestAsyncOpenToBuy: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_retrieve(self, async_client: AsyncLithic) -> None: + open_to_buy = await async_client.financial_accounts.open_to_buy.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(OpenToBuy, open_to_buy, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncLithic) -> None: + response = await async_client.financial_accounts.open_to_buy.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" + open_to_buy = response.parse() + assert_matches_type(OpenToBuy, open_to_buy, path=["response"]) + + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncLithic) -> None: + async with async_client.financial_accounts.open_to_buy.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" + + open_to_buy = await response.parse() + assert_matches_type(OpenToBuy, open_to_buy, 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 `financial_account_token` but received ''" + ): + await async_client.financial_accounts.open_to_buy.with_raw_response.retrieve( + "", + ) From e29c567a7bc79b565bad84e40edc3c213592a9c3 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 17 Sep 2026 20:15:46 +0000 Subject: [PATCH 14/14] release: 0.132.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 20 ++++++++++++++++++++ pyproject.toml | 2 +- src/lithic/_version.py | 2 +- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index a24ae611..b4da64f2 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.131.0" + ".": "0.132.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 8563b697..8cecf5c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## 0.132.0 (2026-09-17) + +Full Changelog: [v0.131.0...v0.132.0](https://github.com/lithic-com/lithic-python/compare/v0.131.0...v0.132.0) + +### Features + +* [CARDS-5174] Add reiusse/renew 409 error ([60c6b8e](https://github.com/lithic-com/lithic-python/commit/60c6b8eefa05208966212c0cc205ef0019f115ac)) +* [TRE-14464] Update /retry payments endpoint to accept method ([9ac7441](https://github.com/lithic-com/lithic-python/commit/9ac74418812660394107e068a012a373a9f81460)) +* [TRE-14524] Add Open to buy API spec ([001bd06](https://github.com/lithic-com/lithic-python/commit/001bd06bbd7c7274e6a1c59f4adcb9e86959b74e)) +* Add missing blockchain/stablecoin endpoints to the spec ([8f1b51c](https://github.com/lithic-com/lithic-python/commit/8f1b51c992cf317ee4353a3244e347f02a666b0f)) +* **api:** add card.pin_updated webhook event ([14889db](https://github.com/lithic-com/lithic-python/commit/14889dbf638b7d1b85e4b3145d8b3914cc87619a)) +* **api:** add EXTERNAL_STABLECOIN category and events to external_payments/account_activity ([945f5ae](https://github.com/lithic-com/lithic-python/commit/945f5aed2a5ddf72dac4319d65cc0c87c86ca172)) +* **api:** add FEE/FEE_REVERSAL enum values to management_operations and financial events ([615daa4](https://github.com/lithic-com/lithic-python/commit/615daa4be69ee4aab3fb1bc992635b335077ad92)) +* **api:** add OTHER enum value to auth_rules v2 type field ([3f0a148](https://github.com/lithic-com/lithic-python/commit/3f0a148adc95e092aa25c9e569bbda518bbe3f54)) +* **api:** add psd2_context field and types to three_ds_authentication ([7da6f44](https://github.com/lithic-com/lithic-python/commit/7da6f4449fc8a5e018e8cc6483400a3383f3df4e)) +* **api:** add STABLECOIN_REVIEWED event type to payments simulate_action ([dc065e4](https://github.com/lithic-com/lithic-python/commit/dc065e43f9c025156c5ca142a9a222b5e0305354)) +* AUTH-3759: Add DECLINE_SCA_REQUIRED and SCA_REQUIRED enum entries ([445299d](https://github.com/lithic-com/lithic-python/commit/445299db5e0bbce6d2a5611a4cb752ac141dd77e)) +* TRE-14349: add installment plan management operation event types ([3cdcf9f](https://github.com/lithic-com/lithic-python/commit/3cdcf9fec6517da95ac06beaf373bc9070a8704f)) +* TRE-14429: Document the stablecoin payments endpoint ([c7b557e](https://github.com/lithic-com/lithic-python/commit/c7b557e0873ef183937d5c432f2a026e8fdd37c3)) + ## 0.131.0 (2026-08-31) Full Changelog: [v0.130.0...v0.131.0](https://github.com/lithic-com/lithic-python/compare/v0.130.0...v0.131.0) diff --git a/pyproject.toml b/pyproject.toml index 0df4f166..5b20f1f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "lithic" -version = "0.131.0" +version = "0.132.0" description = "The official Python library for the lithic API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/lithic/_version.py b/src/lithic/_version.py index 5e23cbfb..6a10b27d 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.131.0" # x-release-please-version +__version__ = "0.132.0" # x-release-please-version