From 996ffd808a3036bb1d8b432853971e1af3d5d433 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Tue, 12 Sep 2023 21:30:23 +0000 Subject: [PATCH] feat(api)!: remove Limits API, add ACH controls to Account Numbers - Remove Limits related endpoints - Add `inbound_ach` property to Account Numbers - Add ability to block ACH debits for Account Numbers - Make `entity_id` required for archiving entities BREAKING CHANGES: - Removed Limits related endpoints - `POST /limits` - `GET /limits` - `PATCH /limits/{limit_id}` - `GET /limits/{limit_id}` - `entity_id` is now required for `POST /entities/{entity_id}/archive` # Migration Use the new `inbound_ach` properties on Account Numbers to control ACH debit behavior. --- .stats.yml | 2 +- api.md | 15 - src/increase/_client.py | 4 - src/increase/resources/__init__.py | 3 - src/increase/resources/account_numbers.py | 16 + src/increase/resources/accounts.py | 10 +- src/increase/resources/entities/entities.py | 12 +- src/increase/resources/limits.py | 434 ------------------ src/increase/types/__init__.py | 4 - src/increase/types/account_number.py | 17 +- .../types/account_number_create_params.py | 19 +- .../types/account_number_update_params.py | 17 +- src/increase/types/card_profile.py | 3 +- .../types/card_profile_list_params.py | 4 +- src/increase/types/declined_transaction.py | 24 +- src/increase/types/limit.py | 76 --- src/increase/types/limit_create_params.py | 39 -- src/increase/types/limit_list_params.py | 24 - src/increase/types/limit_update_params.py | 16 - .../simulations/ach_transfer_simulation.py | 24 +- .../card_authorization_simulation.py | 24 +- ...ime_payments_transfer_simulation_result.py | 24 +- tests/api_resources/test_account_numbers.py | 20 + tests/api_resources/test_card_profiles.py | 4 +- tests/api_resources/test_limits.py | 125 ----- 25 files changed, 143 insertions(+), 817 deletions(-) delete mode 100644 src/increase/resources/limits.py delete mode 100644 src/increase/types/limit.py delete mode 100644 src/increase/types/limit_create_params.py delete mode 100644 src/increase/types/limit_list_params.py delete mode 100644 src/increase/types/limit_update_params.py delete mode 100644 tests/api_resources/test_limits.py diff --git a/.stats.yml b/.stats.yml index 93f240e6b..f9d1086b6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1 +1 @@ -configured_endpoints: 144 +configured_endpoints: 140 diff --git a/api.md b/api.md index 849852abf..d8f383d93 100644 --- a/api.md +++ b/api.md @@ -257,21 +257,6 @@ Methods: - client.declined_transactions.retrieve(declined_transaction_id) -> DeclinedTransaction - client.declined_transactions.list(\*\*params) -> SyncPage[DeclinedTransaction] -# Limits - -Types: - -```python -from increase.types import Limit -``` - -Methods: - -- client.limits.create(\*\*params) -> Limit -- client.limits.retrieve(limit_id) -> Limit -- client.limits.update(limit_id, \*\*params) -> Limit -- client.limits.list(\*\*params) -> SyncPage[Limit] - # AccountTransfers Types: diff --git a/src/increase/_client.py b/src/increase/_client.py index 97a1fcac4..5071da937 100644 --- a/src/increase/_client.py +++ b/src/increase/_client.py @@ -71,7 +71,6 @@ class Increase(SyncAPIClient): pending_transactions: resources.PendingTransactions programs: resources.Programs declined_transactions: resources.DeclinedTransactions - limits: resources.Limits account_transfers: resources.AccountTransfers ach_transfers: resources.ACHTransfers ach_prenotifications: resources.ACHPrenotifications @@ -176,7 +175,6 @@ def __init__( self.pending_transactions = resources.PendingTransactions(self) self.programs = resources.Programs(self) self.declined_transactions = resources.DeclinedTransactions(self) - self.limits = resources.Limits(self) self.account_transfers = resources.AccountTransfers(self) self.ach_transfers = resources.ACHTransfers(self) self.ach_prenotifications = resources.ACHPrenotifications(self) @@ -353,7 +351,6 @@ class AsyncIncrease(AsyncAPIClient): pending_transactions: resources.AsyncPendingTransactions programs: resources.AsyncPrograms declined_transactions: resources.AsyncDeclinedTransactions - limits: resources.AsyncLimits account_transfers: resources.AsyncAccountTransfers ach_transfers: resources.AsyncACHTransfers ach_prenotifications: resources.AsyncACHPrenotifications @@ -458,7 +455,6 @@ def __init__( self.pending_transactions = resources.AsyncPendingTransactions(self) self.programs = resources.AsyncPrograms(self) self.declined_transactions = resources.AsyncDeclinedTransactions(self) - self.limits = resources.AsyncLimits(self) self.account_transfers = resources.AsyncAccountTransfers(self) self.ach_transfers = resources.AsyncACHTransfers(self) self.ach_prenotifications = resources.AsyncACHPrenotifications(self) diff --git a/src/increase/resources/__init__.py b/src/increase/resources/__init__.py index 2ed6e885a..3f6ee190a 100644 --- a/src/increase/resources/__init__.py +++ b/src/increase/resources/__init__.py @@ -4,7 +4,6 @@ from .files import Files, AsyncFiles from .events import Events, AsyncEvents from .groups import Groups, AsyncGroups -from .limits import Limits, AsyncLimits from .exports import Exports, AsyncExports from .accounts import Accounts, AsyncAccounts from .entities import Entities, AsyncEntities @@ -88,8 +87,6 @@ "AsyncPrograms", "DeclinedTransactions", "AsyncDeclinedTransactions", - "Limits", - "AsyncLimits", "AccountTransfers", "AsyncAccountTransfers", "ACHTransfers", diff --git a/src/increase/resources/account_numbers.py b/src/increase/resources/account_numbers.py index b63c3f766..7c5c502fd 100644 --- a/src/increase/resources/account_numbers.py +++ b/src/increase/resources/account_numbers.py @@ -25,6 +25,7 @@ def create( *, account_id: str, name: str, + inbound_ach: account_number_create_params.InboundACH | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -41,6 +42,8 @@ def create( name: The name you choose for the Account Number. + inbound_ach: Options related to how this Account Number should handle inbound ACH transfers. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -57,6 +60,7 @@ def create( { "account_id": account_id, "name": name, + "inbound_ach": inbound_ach, }, account_number_create_params.AccountNumberCreateParams, ), @@ -107,6 +111,7 @@ def update( self, account_number_id: str, *, + inbound_ach: account_number_update_params.InboundACH | NotGiven = NOT_GIVEN, name: str | NotGiven = NOT_GIVEN, status: Literal["active", "disabled", "canceled"] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -123,6 +128,8 @@ def update( Args: account_number_id: The identifier of the Account Number. + inbound_ach: Options related to how this Account Number handles inbound ACH transfers. + name: The name you choose for the Account Number. status: This indicates if transfers can be made to the Account Number. @@ -145,6 +152,7 @@ def update( f"/account_numbers/{account_number_id}", body=maybe_transform( { + "inbound_ach": inbound_ach, "name": name, "status": status, }, @@ -229,6 +237,7 @@ async def create( *, account_id: str, name: str, + inbound_ach: account_number_create_params.InboundACH | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -245,6 +254,8 @@ async def create( name: The name you choose for the Account Number. + inbound_ach: Options related to how this Account Number should handle inbound ACH transfers. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -261,6 +272,7 @@ async def create( { "account_id": account_id, "name": name, + "inbound_ach": inbound_ach, }, account_number_create_params.AccountNumberCreateParams, ), @@ -311,6 +323,7 @@ async def update( self, account_number_id: str, *, + inbound_ach: account_number_update_params.InboundACH | NotGiven = NOT_GIVEN, name: str | NotGiven = NOT_GIVEN, status: Literal["active", "disabled", "canceled"] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -327,6 +340,8 @@ async def update( Args: account_number_id: The identifier of the Account Number. + inbound_ach: Options related to how this Account Number handles inbound ACH transfers. + name: The name you choose for the Account Number. status: This indicates if transfers can be made to the Account Number. @@ -349,6 +364,7 @@ async def update( f"/account_numbers/{account_number_id}", body=maybe_transform( { + "inbound_ach": inbound_ach, "name": name, "status": status, }, diff --git a/src/increase/resources/accounts.py b/src/increase/resources/accounts.py index 96dbdb0b1..cd14a8ce5 100644 --- a/src/increase/resources/accounts.py +++ b/src/increase/resources/accounts.py @@ -234,12 +234,13 @@ def close( timeout: float | None | NotGiven = NOT_GIVEN, idempotency_key: str | None = None, ) -> Account: - """ - Close an Account + """Close an Account Args: account_id: The identifier of the Account to close. + The account must have a zero balance. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -478,12 +479,13 @@ async def close( timeout: float | None | NotGiven = NOT_GIVEN, idempotency_key: str | None = None, ) -> Account: - """ - Close an Account + """Close an Account Args: account_id: The identifier of the Account to close. + The account must have a zero balance. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/increase/resources/entities/entities.py b/src/increase/resources/entities/entities.py index d414a9072..475bbbd64 100644 --- a/src/increase/resources/entities/entities.py +++ b/src/increase/resources/entities/entities.py @@ -219,12 +219,14 @@ def archive( timeout: float | None | NotGiven = NOT_GIVEN, idempotency_key: str | None = None, ) -> Entity: - """ - Archive an Entity + """Archive an Entity Args: entity_id: The identifier of the Entity to archive. + Any accounts associated with an entity + must be closed before the entity can be archived. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -486,12 +488,14 @@ async def archive( timeout: float | None | NotGiven = NOT_GIVEN, idempotency_key: str | None = None, ) -> Entity: - """ - Archive an Entity + """Archive an Entity Args: entity_id: The identifier of the Entity to archive. + Any accounts associated with an entity + must be closed before the entity can be archived. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/increase/resources/limits.py b/src/increase/resources/limits.py deleted file mode 100644 index fd291af1f..000000000 --- a/src/increase/resources/limits.py +++ /dev/null @@ -1,434 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -from typing_extensions import Literal - -from ..types import Limit, limit_list_params, limit_create_params, limit_update_params -from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven -from .._utils import maybe_transform -from .._resource import SyncAPIResource, AsyncAPIResource -from ..pagination import SyncPage, AsyncPage -from .._base_client import AsyncPaginator, make_request_options - -__all__ = ["Limits", "AsyncLimits"] - - -class Limits(SyncAPIResource): - def create( - self, - *, - metric: Literal["count", "volume"], - model_id: str, - value: int, - interval: Literal["transaction", "day", "week", "month", "year", "all_time"] | NotGiven = NOT_GIVEN, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - idempotency_key: str | None = None, - ) -> Limit: - """ - Create a Limit - - Args: - metric: The metric for the limit. - - - `count` - The maximum number of debits allowed. - - `volume` - The maximum volume of debits allowed in the minor unit of the - model's currency. - - model_id: The identifier of the Account, Account Number, or Card you wish to associate the - limit with. - - value: The value to test the limit against. - - interval: The interval for the metric. Required if `metric` is `count` or `volume`. - - - `transaction` - Enforce the limit per-transaction. - - `day` - Enforce the limit based on the previous 24 hour period. - - `week` - Enforce the limit based on the previous seven days. - - `month` - Enforce the limit based on the previous month, going back to the - current day in the previous month, or as close as possible given month length - differences. - - `year` - Enforce the limit based on the previous year. - - `all_time` - Enforce the limit for all time. - - 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 - - idempotency_key: Specify a custom idempotency key for this request - """ - return self._post( - "/limits", - body=maybe_transform( - { - "metric": metric, - "model_id": model_id, - "value": value, - "interval": interval, - }, - limit_create_params.LimitCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - idempotency_key=idempotency_key, - ), - cast_to=Limit, - ) - - def retrieve( - self, - limit_id: 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 | None | NotGiven = NOT_GIVEN, - ) -> Limit: - """ - Retrieve a Limit - - Args: - limit_id: The identifier of the Limit to retrieve. - - 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._get( - f"/limits/{limit_id}", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=Limit, - ) - - def update( - self, - limit_id: str, - *, - status: Literal["inactive", "active"], - # 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 | None | NotGiven = NOT_GIVEN, - idempotency_key: str | None = None, - ) -> Limit: - """ - Update a Limit - - Args: - limit_id: The limit to update. - - status: The status to update the limit with. - - - `inactive` - Disable the limit temporarily. - - `active` - Activate the limit. - - 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 - - idempotency_key: Specify a custom idempotency key for this request - """ - return self._patch( - f"/limits/{limit_id}", - body=maybe_transform({"status": status}, limit_update_params.LimitUpdateParams), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - idempotency_key=idempotency_key, - ), - cast_to=Limit, - ) - - def list( - self, - *, - cursor: str | NotGiven = NOT_GIVEN, - limit: int | NotGiven = NOT_GIVEN, - model_id: str | NotGiven = NOT_GIVEN, - status: str | NotGiven = NOT_GIVEN, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> SyncPage[Limit]: - """ - List Limits - - Args: - cursor: Return the page of entries after this one. - - limit: Limit the size of the list that is returned. The default (and maximum) is 100 - objects. - - model_id: The model to retrieve limits for. - - status: The status to retrieve limits for. - - 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._get_api_list( - "/limits", - page=SyncPage[Limit], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "cursor": cursor, - "limit": limit, - "model_id": model_id, - "status": status, - }, - limit_list_params.LimitListParams, - ), - ), - model=Limit, - ) - - -class AsyncLimits(AsyncAPIResource): - async def create( - self, - *, - metric: Literal["count", "volume"], - model_id: str, - value: int, - interval: Literal["transaction", "day", "week", "month", "year", "all_time"] | NotGiven = NOT_GIVEN, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - idempotency_key: str | None = None, - ) -> Limit: - """ - Create a Limit - - Args: - metric: The metric for the limit. - - - `count` - The maximum number of debits allowed. - - `volume` - The maximum volume of debits allowed in the minor unit of the - model's currency. - - model_id: The identifier of the Account, Account Number, or Card you wish to associate the - limit with. - - value: The value to test the limit against. - - interval: The interval for the metric. Required if `metric` is `count` or `volume`. - - - `transaction` - Enforce the limit per-transaction. - - `day` - Enforce the limit based on the previous 24 hour period. - - `week` - Enforce the limit based on the previous seven days. - - `month` - Enforce the limit based on the previous month, going back to the - current day in the previous month, or as close as possible given month length - differences. - - `year` - Enforce the limit based on the previous year. - - `all_time` - Enforce the limit for all time. - - 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 - - idempotency_key: Specify a custom idempotency key for this request - """ - return await self._post( - "/limits", - body=maybe_transform( - { - "metric": metric, - "model_id": model_id, - "value": value, - "interval": interval, - }, - limit_create_params.LimitCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - idempotency_key=idempotency_key, - ), - cast_to=Limit, - ) - - async def retrieve( - self, - limit_id: 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 | None | NotGiven = NOT_GIVEN, - ) -> Limit: - """ - Retrieve a Limit - - Args: - limit_id: The identifier of the Limit to retrieve. - - 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._get( - f"/limits/{limit_id}", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=Limit, - ) - - async def update( - self, - limit_id: str, - *, - status: Literal["inactive", "active"], - # 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 | None | NotGiven = NOT_GIVEN, - idempotency_key: str | None = None, - ) -> Limit: - """ - Update a Limit - - Args: - limit_id: The limit to update. - - status: The status to update the limit with. - - - `inactive` - Disable the limit temporarily. - - `active` - Activate the limit. - - 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 - - idempotency_key: Specify a custom idempotency key for this request - """ - return await self._patch( - f"/limits/{limit_id}", - body=maybe_transform({"status": status}, limit_update_params.LimitUpdateParams), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - idempotency_key=idempotency_key, - ), - cast_to=Limit, - ) - - def list( - self, - *, - cursor: str | NotGiven = NOT_GIVEN, - limit: int | NotGiven = NOT_GIVEN, - model_id: str | NotGiven = NOT_GIVEN, - status: str | NotGiven = NOT_GIVEN, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | None | NotGiven = NOT_GIVEN, - ) -> AsyncPaginator[Limit, AsyncPage[Limit]]: - """ - List Limits - - Args: - cursor: Return the page of entries after this one. - - limit: Limit the size of the list that is returned. The default (and maximum) is 100 - objects. - - model_id: The model to retrieve limits for. - - status: The status to retrieve limits for. - - 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._get_api_list( - "/limits", - page=AsyncPage[Limit], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "cursor": cursor, - "limit": limit, - "model_id": model_id, - "status": status, - }, - limit_list_params.LimitListParams, - ), - ), - model=Limit, - ) diff --git a/src/increase/types/__init__.py b/src/increase/types/__init__.py index 2fb878c32..2c62fa5af 100644 --- a/src/increase/types/__init__.py +++ b/src/increase/types/__init__.py @@ -6,7 +6,6 @@ from .file import File as File from .event import Event as Event from .group import Group as Group -from .limit import Limit as Limit from .entity import Entity as Entity from .export import Export as Export from .account import Account as Account @@ -30,7 +29,6 @@ from .account_statement import AccountStatement as AccountStatement from .bookkeeping_entry import BookkeepingEntry as BookkeepingEntry from .event_list_params import EventListParams as EventListParams -from .limit_list_params import LimitListParams as LimitListParams from .card_create_params import CardCreateParams as CardCreateParams from .card_update_params import CardUpdateParams as CardUpdateParams from .entity_list_params import EntityListParams as EntityListParams @@ -41,8 +39,6 @@ from .account_list_params import AccountListParams as AccountListParams from .ach_prenotification import ACHPrenotification as ACHPrenotification from .bookkeeping_account import BookkeepingAccount as BookkeepingAccount -from .limit_create_params import LimitCreateParams as LimitCreateParams -from .limit_update_params import LimitUpdateParams as LimitUpdateParams from .pending_transaction import PendingTransaction as PendingTransaction from .program_list_params import ProgramListParams as ProgramListParams from .declined_transaction import DeclinedTransaction as DeclinedTransaction diff --git a/src/increase/types/account_number.py b/src/increase/types/account_number.py index ba09fcf29..854fb1616 100644 --- a/src/increase/types/account_number.py +++ b/src/increase/types/account_number.py @@ -5,7 +5,19 @@ from .._models import BaseModel -__all__ = ["AccountNumber"] +__all__ = ["AccountNumber", "InboundACH"] + + +class InboundACH(BaseModel): + debit_status: Literal["allowed", "blocked"] + """Whether ACH debits are allowed against this Account Number. + + Note that they will still be declined if this is `allowed` if the Account Number + is not active. + + - `allowed` - ACH Debits are allowed. + - `blocked` - ACH Debits are blocked. + """ class AccountNumber(BaseModel): @@ -24,6 +36,9 @@ class AccountNumber(BaseModel): Number was created. """ + inbound_ach: InboundACH + """Properties related to how this Account Number handles inbound ACH transfers.""" + name: str """The name you choose for the Account Number.""" diff --git a/src/increase/types/account_number_create_params.py b/src/increase/types/account_number_create_params.py index a5ecb8b31..197990e60 100644 --- a/src/increase/types/account_number_create_params.py +++ b/src/increase/types/account_number_create_params.py @@ -2,9 +2,9 @@ from __future__ import annotations -from typing_extensions import Required, TypedDict +from typing_extensions import Literal, Required, TypedDict -__all__ = ["AccountNumberCreateParams"] +__all__ = ["AccountNumberCreateParams", "InboundACH"] class AccountNumberCreateParams(TypedDict, total=False): @@ -13,3 +13,18 @@ class AccountNumberCreateParams(TypedDict, total=False): name: Required[str] """The name you choose for the Account Number.""" + + inbound_ach: InboundACH + """Options related to how this Account Number should handle inbound ACH transfers.""" + + +class InboundACH(TypedDict, total=False): + debit_status: Required[Literal["allowed", "blocked"]] + """Whether ACH debits are allowed against this Account Number. + + Note that ACH debits will be declined if this is `allowed` but the Account + Number is not active. + + - `allowed` - ACH Debits are allowed. + - `blocked` - ACH Debits are blocked. + """ diff --git a/src/increase/types/account_number_update_params.py b/src/increase/types/account_number_update_params.py index 34b6138bf..80cdd8107 100644 --- a/src/increase/types/account_number_update_params.py +++ b/src/increase/types/account_number_update_params.py @@ -4,10 +4,13 @@ from typing_extensions import Literal, TypedDict -__all__ = ["AccountNumberUpdateParams"] +__all__ = ["AccountNumberUpdateParams", "InboundACH"] class AccountNumberUpdateParams(TypedDict, total=False): + inbound_ach: InboundACH + """Options related to how this Account Number handles inbound ACH transfers.""" + name: str """The name you choose for the Account Number.""" @@ -18,3 +21,15 @@ class AccountNumberUpdateParams(TypedDict, total=False): - `disabled` - The account number is temporarily disabled. - `canceled` - The account number is permanently disabled. """ + + +class InboundACH(TypedDict, total=False): + debit_status: Literal["allowed", "blocked"] + """Whether ACH debits are allowed against this Account Number. + + Note that ACH debits will be declined if this is `allowed` but the Account + Number is not active. + + - `allowed` - ACH Debits are allowed. + - `blocked` - ACH Debits are blocked. + """ diff --git a/src/increase/types/card_profile.py b/src/increase/types/card_profile.py index 26aaafcae..ff94d803d 100644 --- a/src/increase/types/card_profile.py +++ b/src/increase/types/card_profile.py @@ -59,12 +59,13 @@ class PhysicalCards(BaseModel): front_image_file_id: Optional[str] """The identifier of the File containing the physical card's front image.""" - status: Literal["not_eligible", "rejected", "pending_reviewing", "pending_submitting", "active"] + status: Literal["not_eligible", "rejected", "pending_creating", "pending_reviewing", "pending_submitting", "active"] """The status of the Physical Card Profile. - `not_eligible` - The Card Profile is not eligible for physical cards. - `rejected` - There is an issue with the Physical Card Profile preventing it from use. + - `pending_creating` - The Card Profile has not yet been processed by Increase. - `pending_reviewing` - The card profile is awaiting review by Increase. - `pending_submitting` - The card profile is awaiting submission to the fulfillment provider. diff --git a/src/increase/types/card_profile_list_params.py b/src/increase/types/card_profile_list_params.py index 713eaf8c1..a32288685 100644 --- a/src/increase/types/card_profile_list_params.py +++ b/src/increase/types/card_profile_list_params.py @@ -26,7 +26,9 @@ class CardProfileListParams(TypedDict, total=False): _PhysicalCardsStatusReservedKeywords = TypedDict( "_PhysicalCardsStatusReservedKeywords", { - "in": List[Literal["not_eligible", "rejected", "pending_reviewing", "pending_submitting", "active"]], + "in": List[ + Literal["not_eligible", "rejected", "pending_creating", "pending_reviewing", "pending_submitting", "active"] + ], }, total=False, ) diff --git a/src/increase/types/declined_transaction.py b/src/increase/types/declined_transaction.py index 3edc96e5a..fc216f880 100644 --- a/src/increase/types/declined_transaction.py +++ b/src/increase/types/declined_transaction.py @@ -314,39 +314,33 @@ class SourceCheckDecline(BaseModel): """ reason: Literal[ - "ach_route_canceled", "ach_route_disabled", + "ach_route_canceled", "breaches_limit", "entity_not_active", "group_locked", "insufficient_funds", - "unable_to_locate_account", - "not_our_item", - "unable_to_process", - "refer_to_image", "stop_payment_requested", - "returned", "duplicate_presentment", "not_authorized", - "altered_or_fictitious", + "amount_mismatch", + "not_our_item", ] """Why the check was declined. - - `ach_route_canceled` - The account number is canceled. - `ach_route_disabled` - The account number is disabled. + - `ach_route_canceled` - The account number is canceled. - `breaches_limit` - The transaction would cause a limit to be exceeded. - `entity_not_active` - The account's entity is not active. - `group_locked` - Your account is inactive. - `insufficient_funds` - Your account contains insufficient funds. - - `unable_to_locate_account` - Unable to locate account. - - `not_our_item` - Routing number on the check is not ours. - - `unable_to_process` - Unable to process. - - `refer_to_image` - Refer to image. - `stop_payment_requested` - Stop payment requested for this check. - - `returned` - Check was returned to sender. - `duplicate_presentment` - The check was a duplicate deposit. - - `not_authorized` - The transaction is not allowed. - - `altered_or_fictitious` - The check was altered or fictitious. + - `not_authorized` - The check was not authorized. + - `amount_mismatch` - The amount the receiving bank is attempting to deposit + does not match the amount on the check. + - `not_our_item` - The check attempting to be deposited does not belong to + Increase. """ diff --git a/src/increase/types/limit.py b/src/increase/types/limit.py deleted file mode 100644 index fdabfbc8f..000000000 --- a/src/increase/types/limit.py +++ /dev/null @@ -1,76 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -import typing_extensions -from typing import Optional -from typing_extensions import Literal - -from pydantic import Field as FieldInfo - -from .._models import BaseModel - -__all__ = ["Limit"] - - -class Limit(BaseModel): - id: str - """The Limit identifier.""" - - interval: Optional[Literal["transaction", "day", "week", "month", "year", "all_time"]] - """The interval for the metric. - - This is required if `metric` is `count` or `volume`. - - - `transaction` - Enforce the Limit per-transaction. - - `day` - Enforce the Limit based on the trailing 24 hour period. - - `week` - Enforce the Limit based on the trailing seven days. - - `month` - Enforce the Limit based on the trailing month, going back to the - current day in the previous month, or as close as possible given month length - differences. - - `year` - Enforce the Limit based on the trailing 365 days. - - `all_time` - Enforce the Limit for all time. - """ - - metric: Literal["count", "volume"] - """The metric for the Limit. - - - `count` - The maximum number of debits allowed. - - `volume` - The maximum volume of debits allowed in the minor unit of the - model's currency. - """ - - resource_id: str = FieldInfo(alias="model_id") - """The identifier of the Account Number, Account, or Card the Limit applies to.""" - - resource_type: Literal["account", "account_number", "card"] = FieldInfo(alias="model_type") - """The type of the model you wish to associate the Limit with. - - - `account` - Enforce the Limit for the entire account. - - `account_number` - Enforce the Limit for this specific route. - - `card` - Enforce the Limit for this specific card. - """ - - status: Literal["active", "inactive"] - """The current status of the Limit. - - - `active` - The Limit is active. - - `inactive` - The Limit is temporarily disabled. - """ - - type: Literal["limit"] - """A constant representing the object's type. - - For this resource it will always be `limit`. - """ - - value: int - """The value to evaluate the Limit against.""" - - @property - @typing_extensions.deprecated("The resource_id property should be used instead") - def model_id(self) -> str: - return self.resource_id - - @property - @typing_extensions.deprecated("The resource_type property should be used instead") - def model_type(self) -> Literal["account", "account_number", "card"]: - return self.resource_type diff --git a/src/increase/types/limit_create_params.py b/src/increase/types/limit_create_params.py deleted file mode 100644 index 10b21948c..000000000 --- a/src/increase/types/limit_create_params.py +++ /dev/null @@ -1,39 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -from typing_extensions import Literal, Required, TypedDict - -__all__ = ["LimitCreateParams"] - - -class LimitCreateParams(TypedDict, total=False): - metric: Required[Literal["count", "volume"]] - """The metric for the limit. - - - `count` - The maximum number of debits allowed. - - `volume` - The maximum volume of debits allowed in the minor unit of the - model's currency. - """ - - model_id: Required[str] - """ - The identifier of the Account, Account Number, or Card you wish to associate the - limit with. - """ - - value: Required[int] - """The value to test the limit against.""" - - interval: Literal["transaction", "day", "week", "month", "year", "all_time"] - """The interval for the metric. Required if `metric` is `count` or `volume`. - - - `transaction` - Enforce the limit per-transaction. - - `day` - Enforce the limit based on the previous 24 hour period. - - `week` - Enforce the limit based on the previous seven days. - - `month` - Enforce the limit based on the previous month, going back to the - current day in the previous month, or as close as possible given month length - differences. - - `year` - Enforce the limit based on the previous year. - - `all_time` - Enforce the limit for all time. - """ diff --git a/src/increase/types/limit_list_params.py b/src/increase/types/limit_list_params.py deleted file mode 100644 index c31260a1a..000000000 --- a/src/increase/types/limit_list_params.py +++ /dev/null @@ -1,24 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -from typing_extensions import TypedDict - -__all__ = ["LimitListParams"] - - -class LimitListParams(TypedDict, total=False): - cursor: str - """Return the page of entries after this one.""" - - limit: int - """Limit the size of the list that is returned. - - The default (and maximum) is 100 objects. - """ - - model_id: str - """The model to retrieve limits for.""" - - status: str - """The status to retrieve limits for.""" diff --git a/src/increase/types/limit_update_params.py b/src/increase/types/limit_update_params.py deleted file mode 100644 index a950be12d..000000000 --- a/src/increase/types/limit_update_params.py +++ /dev/null @@ -1,16 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -from typing_extensions import Literal, Required, TypedDict - -__all__ = ["LimitUpdateParams"] - - -class LimitUpdateParams(TypedDict, total=False): - status: Required[Literal["inactive", "active"]] - """The status to update the limit with. - - - `inactive` - Disable the limit temporarily. - - `active` - Activate the limit. - """ diff --git a/src/increase/types/simulations/ach_transfer_simulation.py b/src/increase/types/simulations/ach_transfer_simulation.py index 256088348..d9802a7a3 100644 --- a/src/increase/types/simulations/ach_transfer_simulation.py +++ b/src/increase/types/simulations/ach_transfer_simulation.py @@ -359,39 +359,33 @@ class DeclinedTransactionSourceCheckDecline(BaseModel): """ reason: Literal[ - "ach_route_canceled", "ach_route_disabled", + "ach_route_canceled", "breaches_limit", "entity_not_active", "group_locked", "insufficient_funds", - "unable_to_locate_account", - "not_our_item", - "unable_to_process", - "refer_to_image", "stop_payment_requested", - "returned", "duplicate_presentment", "not_authorized", - "altered_or_fictitious", + "amount_mismatch", + "not_our_item", ] """Why the check was declined. - - `ach_route_canceled` - The account number is canceled. - `ach_route_disabled` - The account number is disabled. + - `ach_route_canceled` - The account number is canceled. - `breaches_limit` - The transaction would cause a limit to be exceeded. - `entity_not_active` - The account's entity is not active. - `group_locked` - Your account is inactive. - `insufficient_funds` - Your account contains insufficient funds. - - `unable_to_locate_account` - Unable to locate account. - - `not_our_item` - Routing number on the check is not ours. - - `unable_to_process` - Unable to process. - - `refer_to_image` - Refer to image. - `stop_payment_requested` - Stop payment requested for this check. - - `returned` - Check was returned to sender. - `duplicate_presentment` - The check was a duplicate deposit. - - `not_authorized` - The transaction is not allowed. - - `altered_or_fictitious` - The check was altered or fictitious. + - `not_authorized` - The check was not authorized. + - `amount_mismatch` - The amount the receiving bank is attempting to deposit + does not match the amount on the check. + - `not_our_item` - The check attempting to be deposited does not belong to + Increase. """ diff --git a/src/increase/types/simulations/card_authorization_simulation.py b/src/increase/types/simulations/card_authorization_simulation.py index f7825c50b..1c7e2ed4f 100644 --- a/src/increase/types/simulations/card_authorization_simulation.py +++ b/src/increase/types/simulations/card_authorization_simulation.py @@ -327,39 +327,33 @@ class DeclinedTransactionSourceCheckDecline(BaseModel): """ reason: Literal[ - "ach_route_canceled", "ach_route_disabled", + "ach_route_canceled", "breaches_limit", "entity_not_active", "group_locked", "insufficient_funds", - "unable_to_locate_account", - "not_our_item", - "unable_to_process", - "refer_to_image", "stop_payment_requested", - "returned", "duplicate_presentment", "not_authorized", - "altered_or_fictitious", + "amount_mismatch", + "not_our_item", ] """Why the check was declined. - - `ach_route_canceled` - The account number is canceled. - `ach_route_disabled` - The account number is disabled. + - `ach_route_canceled` - The account number is canceled. - `breaches_limit` - The transaction would cause a limit to be exceeded. - `entity_not_active` - The account's entity is not active. - `group_locked` - Your account is inactive. - `insufficient_funds` - Your account contains insufficient funds. - - `unable_to_locate_account` - Unable to locate account. - - `not_our_item` - Routing number on the check is not ours. - - `unable_to_process` - Unable to process. - - `refer_to_image` - Refer to image. - `stop_payment_requested` - Stop payment requested for this check. - - `returned` - Check was returned to sender. - `duplicate_presentment` - The check was a duplicate deposit. - - `not_authorized` - The transaction is not allowed. - - `altered_or_fictitious` - The check was altered or fictitious. + - `not_authorized` - The check was not authorized. + - `amount_mismatch` - The amount the receiving bank is attempting to deposit + does not match the amount on the check. + - `not_our_item` - The check attempting to be deposited does not belong to + Increase. """ diff --git a/src/increase/types/simulations/inbound_real_time_payments_transfer_simulation_result.py b/src/increase/types/simulations/inbound_real_time_payments_transfer_simulation_result.py index 6d9593d03..636116db0 100644 --- a/src/increase/types/simulations/inbound_real_time_payments_transfer_simulation_result.py +++ b/src/increase/types/simulations/inbound_real_time_payments_transfer_simulation_result.py @@ -359,39 +359,33 @@ class DeclinedTransactionSourceCheckDecline(BaseModel): """ reason: Literal[ - "ach_route_canceled", "ach_route_disabled", + "ach_route_canceled", "breaches_limit", "entity_not_active", "group_locked", "insufficient_funds", - "unable_to_locate_account", - "not_our_item", - "unable_to_process", - "refer_to_image", "stop_payment_requested", - "returned", "duplicate_presentment", "not_authorized", - "altered_or_fictitious", + "amount_mismatch", + "not_our_item", ] """Why the check was declined. - - `ach_route_canceled` - The account number is canceled. - `ach_route_disabled` - The account number is disabled. + - `ach_route_canceled` - The account number is canceled. - `breaches_limit` - The transaction would cause a limit to be exceeded. - `entity_not_active` - The account's entity is not active. - `group_locked` - Your account is inactive. - `insufficient_funds` - Your account contains insufficient funds. - - `unable_to_locate_account` - Unable to locate account. - - `not_our_item` - Routing number on the check is not ours. - - `unable_to_process` - Unable to process. - - `refer_to_image` - Refer to image. - `stop_payment_requested` - Stop payment requested for this check. - - `returned` - Check was returned to sender. - `duplicate_presentment` - The check was a duplicate deposit. - - `not_authorized` - The transaction is not allowed. - - `altered_or_fictitious` - The check was altered or fictitious. + - `not_authorized` - The check was not authorized. + - `amount_mismatch` - The amount the receiving bank is attempting to deposit + does not match the amount on the check. + - `not_our_item` - The check attempting to be deposited does not belong to + Increase. """ diff --git a/tests/api_resources/test_account_numbers.py b/tests/api_resources/test_account_numbers.py index fd44feea0..a8675e8c6 100644 --- a/tests/api_resources/test_account_numbers.py +++ b/tests/api_resources/test_account_numbers.py @@ -29,6 +29,15 @@ def test_method_create(self, client: Increase) -> None: ) assert_matches_type(AccountNumber, account_number, path=["response"]) + @parametrize + def test_method_create_with_all_params(self, client: Increase) -> None: + account_number = client.account_numbers.create( + account_id="string", + name="x", + inbound_ach={"debit_status": "allowed"}, + ) + assert_matches_type(AccountNumber, account_number, path=["response"]) + @parametrize def test_method_retrieve(self, client: Increase) -> None: account_number = client.account_numbers.retrieve( @@ -47,6 +56,7 @@ def test_method_update(self, client: Increase) -> None: def test_method_update_with_all_params(self, client: Increase) -> None: account_number = client.account_numbers.update( "string", + inbound_ach={"debit_status": "allowed"}, name="x", status="active", ) @@ -87,6 +97,15 @@ async def test_method_create(self, client: AsyncIncrease) -> None: ) assert_matches_type(AccountNumber, account_number, path=["response"]) + @parametrize + async def test_method_create_with_all_params(self, client: AsyncIncrease) -> None: + account_number = await client.account_numbers.create( + account_id="string", + name="x", + inbound_ach={"debit_status": "allowed"}, + ) + assert_matches_type(AccountNumber, account_number, path=["response"]) + @parametrize async def test_method_retrieve(self, client: AsyncIncrease) -> None: account_number = await client.account_numbers.retrieve( @@ -105,6 +124,7 @@ async def test_method_update(self, client: AsyncIncrease) -> None: async def test_method_update_with_all_params(self, client: AsyncIncrease) -> None: account_number = await client.account_numbers.update( "string", + inbound_ach={"debit_status": "allowed"}, name="x", status="active", ) diff --git a/tests/api_resources/test_card_profiles.py b/tests/api_resources/test_card_profiles.py index a496c8299..fa34152a4 100644 --- a/tests/api_resources/test_card_profiles.py +++ b/tests/api_resources/test_card_profiles.py @@ -76,7 +76,7 @@ def test_method_list_with_all_params(self, client: Increase) -> None: card_profile = client.card_profiles.list( cursor="string", limit=0, - physical_cards_status={"in": ["not_eligible", "rejected", "pending_reviewing"]}, + physical_cards_status={"in": ["not_eligible", "rejected", "pending_creating"]}, status={"in": ["pending", "rejected", "active"]}, ) assert_matches_type(SyncPage[CardProfile], card_profile, path=["response"]) @@ -150,7 +150,7 @@ async def test_method_list_with_all_params(self, client: AsyncIncrease) -> None: card_profile = await client.card_profiles.list( cursor="string", limit=0, - physical_cards_status={"in": ["not_eligible", "rejected", "pending_reviewing"]}, + physical_cards_status={"in": ["not_eligible", "rejected", "pending_creating"]}, status={"in": ["pending", "rejected", "active"]}, ) assert_matches_type(AsyncPage[CardProfile], card_profile, path=["response"]) diff --git a/tests/api_resources/test_limits.py b/tests/api_resources/test_limits.py deleted file mode 100644 index a9164819a..000000000 --- a/tests/api_resources/test_limits.py +++ /dev/null @@ -1,125 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. - -from __future__ import annotations - -import os - -import pytest - -from increase import Increase, AsyncIncrease -from tests.utils import assert_matches_type -from increase.types import Limit -from increase.pagination import SyncPage, AsyncPage - -base_url = os.environ.get("API_BASE_URL", "http://127.0.0.1:4010") -api_key = os.environ.get("API_KEY", "something1234") - - -class TestLimits: - strict_client = Increase(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = Increase(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) - - @parametrize - def test_method_create(self, client: Increase) -> None: - limit = client.limits.create( - metric="count", - model_id="x", - value=0, - ) - assert_matches_type(Limit, limit, path=["response"]) - - @parametrize - def test_method_create_with_all_params(self, client: Increase) -> None: - limit = client.limits.create( - metric="count", - model_id="x", - value=0, - interval="transaction", - ) - assert_matches_type(Limit, limit, path=["response"]) - - @parametrize - def test_method_retrieve(self, client: Increase) -> None: - limit = client.limits.retrieve( - "string", - ) - assert_matches_type(Limit, limit, path=["response"]) - - @parametrize - def test_method_update(self, client: Increase) -> None: - limit = client.limits.update( - "string", - status="inactive", - ) - assert_matches_type(Limit, limit, path=["response"]) - - @parametrize - def test_method_list(self, client: Increase) -> None: - limit = client.limits.list() - assert_matches_type(SyncPage[Limit], limit, path=["response"]) - - @parametrize - def test_method_list_with_all_params(self, client: Increase) -> None: - limit = client.limits.list( - cursor="string", - limit=0, - model_id="x", - status="x", - ) - assert_matches_type(SyncPage[Limit], limit, path=["response"]) - - -class TestAsyncLimits: - strict_client = AsyncIncrease(base_url=base_url, api_key=api_key, _strict_response_validation=True) - loose_client = AsyncIncrease(base_url=base_url, api_key=api_key, _strict_response_validation=False) - parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) - - @parametrize - async def test_method_create(self, client: AsyncIncrease) -> None: - limit = await client.limits.create( - metric="count", - model_id="x", - value=0, - ) - assert_matches_type(Limit, limit, path=["response"]) - - @parametrize - async def test_method_create_with_all_params(self, client: AsyncIncrease) -> None: - limit = await client.limits.create( - metric="count", - model_id="x", - value=0, - interval="transaction", - ) - assert_matches_type(Limit, limit, path=["response"]) - - @parametrize - async def test_method_retrieve(self, client: AsyncIncrease) -> None: - limit = await client.limits.retrieve( - "string", - ) - assert_matches_type(Limit, limit, path=["response"]) - - @parametrize - async def test_method_update(self, client: AsyncIncrease) -> None: - limit = await client.limits.update( - "string", - status="inactive", - ) - assert_matches_type(Limit, limit, path=["response"]) - - @parametrize - async def test_method_list(self, client: AsyncIncrease) -> None: - limit = await client.limits.list() - assert_matches_type(AsyncPage[Limit], limit, path=["response"]) - - @parametrize - async def test_method_list_with_all_params(self, client: AsyncIncrease) -> None: - limit = await client.limits.list( - cursor="string", - limit=0, - model_id="x", - status="x", - ) - assert_matches_type(AsyncPage[Limit], limit, path=["response"])