diff --git a/.stats.yml b/.stats.yml index 50060d6a..da1c1969 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 -config_hash: 27fa50e251754c8982e3dc615ef6da41 +configured_endpoints: 217 +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/api.md b/api.md index de19390a..dba2ce2d 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 @@ -711,6 +712,7 @@ Types: from lithic.types import ( Payment, PaymentCreateResponse, + PaymentCreateStablecoinResponse, PaymentRetryResponse, PaymentSimulateActionResponse, PaymentSimulateReceiptResponse, @@ -724,6 +726,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 @@ -1008,6 +1011,7 @@ from lithic.types import ( BookTransferTransactionUpdatedWebhookEvent, CardCreatedWebhookEvent, CardConvertedWebhookEvent, + CardPinUpdatedWebhookEvent, CardRenewedWebhookEvent, CardReissuedWebhookEvent, CardShippedWebhookEvent, 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/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/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/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/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/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/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..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 @@ -167,6 +168,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 +181,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/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/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 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/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..b7a495eb 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", @@ -126,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/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, 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/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/src/lithic/types/shared/financial_event.py b/src/lithic/types/shared/financial_event.py index 9d677eb0..542116aa 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", @@ -97,6 +102,8 @@ class FinancialEvent(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/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", 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( + "", + ) 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(