Skip to content

components.payment_gateway.public.accounts

This module defines the public API for the accounts subcomponent.

Only business logic is exposed here. Basic entities and enums are exposed in separate modules to avoid loading the entire subcomponent with its models and dependencies when they are not needed.

Classes

AccountActions

AccountActions(adyen_client)

This class contains all the actions used to manage the lifecycle of an account.

Implements the following Nullable patterns: - Nullables: https://www.jamesshore.com/v2/projects/nullables/testing-without-mocks#nullables ⧉ - Parameterless instantiation: https://www.jamesshore.com/v2/projects/nullables/testing-without-mocks#instantiation ⧉

Tags
Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/actions/account_actions.py
def __init__(
    self,
    adyen_client: "AdyenBalanceAccountsApiClient | None",
) -> None:
    self._adyen_client = adyen_client

Attributes

adyen_client property
adyen_client

Ensures the Adyen client is available when accessing it.

Functions

activate_account
activate_account(session, /, id)

Activate an account.

Note

This operation is currently only supported for Adyen.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/actions/account_actions.py
@obs.api_call()
def activate_account(
    self,
    session: Session,
    /,
    id: AccountId,
) -> None:
    """
    Activate an account.

    Note:
        This operation is currently only supported for Adyen.
    """
    from shared.services.payment_providers.adyen.openapi.balance_platform_service_v2 import (
        BalanceAccountUpdateRequest,
    )

    with raise_if_account_not_found(id):
        account = AccountModelBroker.get_account(session, id=id)

    raise_on_terminated_account(account)
    raise_on_invalid_account_status_transition(account, AccountStatus.active)

    provider = get_provider_for_workspace(account.workspace_key)
    if provider == PaymentServiceProvider.adyen:
        # Update account status on Adyen side
        self.adyen_client.update_balance_account(
            account.external_id,
            request=BalanceAccountUpdateRequest(
                status="active",
            ),
            idempotency_key=None,  # TODO use this for retries
        )

    AccountModelBroker.set_account_status(
        session, id=account.id, status=AccountStatus.active
    )
create classmethod
create()

Normal factory

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/actions/account_actions.py
@classmethod
def create(cls) -> "AccountActions":
    """Normal factory"""
    from shared.services.payment_providers.adyen.clients.adyen_balance_accounts_api_client import (
        AdyenBalanceAccountsApiClient,
    )
    from shared.services.payment_providers.adyen.clients.exceptions import (
        AdyenClientMissingCredentialsException,
    )

    try:
        adyen_client = AdyenBalanceAccountsApiClient.create()
    except AdyenClientMissingCredentialsException:
        adyen_client = None
    return cls(adyen_client)
create_account
create_account(
    session,
    /,
    account_holder_id,
    description,
    reference=None,
)

Create an account for an account holder.

This will create a new account on the PSP workspace linked to the given account holder.

Note

This operation is currently only supported for Adyen.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/actions/account_actions.py
@obs.api_call()
def create_account(
    self,
    session: Session,
    /,
    account_holder_id: AccountHolderId,
    description: str,
    reference: str | None = None,
) -> AccountId:
    """
    Create an account for an account holder.

    This will create a new account on the PSP workspace linked to the given account holder.

    Note:
        This operation is currently only supported for Adyen.
    """
    from components.payment_gateway.subcomponents.accounts.adapters.adyen.helpers import (
        to_balance_account_info,
    )

    with raise_if_account_holder_not_found(account_holder_id):
        account_holder = AccountHolderModelBroker.get_account_holder(
            session,
            id=account_holder_id,
        )

    # Only Adyen is supported for now
    raise_on_provider_not_supported(
        account_holder.workspace_key, PaymentServiceProvider.adyen
    )

    # 1. Create Adyen request payload from our model
    balance_account_info = to_balance_account_info(
        external_account_holder_id=account_holder.external_id,
        description=description,
        reference=reference,
    )
    assert balance_account_info.description is not None

    # 2. Call Adyen API
    balance_account = self.adyen_client.create_balance_account(
        request=balance_account_info,
        idempotency_key=None,  # TODO use this for retries
    )

    # 3. Create entity from API result
    account = AccountModelBroker.create_account(
        session,
        workspace_key=account_holder.workspace_key,
        external_id=balance_account.id,
        description=balance_account_info.description,
        reference=balance_account_info.reference,
        account_holder_id=account_holder_id,
        status=AccountStatus(balance_account.status),
    )
    return AccountId(account.id)
create_null classmethod
create_null(track_adyen_requests=None)

Null factory

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/actions/account_actions.py
@classmethod
def create_null(
    cls,
    track_adyen_requests: list[tuple[str, dict, dict]] | None = None,  # type: ignore[type-arg]
) -> "AccountActions":
    """Null factory"""
    from shared.services.payment_providers.adyen.clients.adyen_balance_accounts_api_client import (
        AdyenBalanceAccountsApiClient,
    )

    return cls(
        AdyenBalanceAccountsApiClient.create_null(
            track_requests=track_adyen_requests
        )
    )
deactivate_account
deactivate_account(session, /, id)

Deactivate an account.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/actions/account_actions.py
@obs.api_call()
def deactivate_account(
    self,
    session: Session,
    /,
    id: AccountId,
) -> None:
    """
    Deactivate an account.
    """
    from shared.services.payment_providers.adyen.openapi.balance_platform_service_v2 import (
        BalanceAccountUpdateRequest,
    )

    with raise_if_account_not_found(id):
        account = AccountModelBroker.get_account(session, id=id)

    raise_on_terminated_account(account)
    raise_on_invalid_account_status_transition(account, AccountStatus.inactive)

    provider = get_provider_for_workspace(account.workspace_key)
    if provider == PaymentServiceProvider.adyen:
        # Update account status on Adyen side
        self.adyen_client.update_balance_account(
            account.external_id,
            request=BalanceAccountUpdateRequest(
                status="inactive",
            ),
            idempotency_key=None,  # TODO use this for retries
        )

    AccountModelBroker.set_account_status(
        session, id=account.id, status=AccountStatus.inactive
    )
declare_account
declare_account(
    session,
    /,
    external_id,
    account_holder_id,
    description,
    reference=None,
)

Declare an account for an account holder.

The account must exist in the PSP workspace.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/actions/account_actions.py
@obs.api_call()
def declare_account(
    self,
    session: Session,
    /,
    external_id: str,
    account_holder_id: AccountHolderId,
    description: str,
    reference: str | None = None,
) -> AccountId:
    """
    Declare an account for an account holder.

    The account must exist in the PSP workspace.
    """
    with raise_if_account_holder_not_found(account_holder_id):
        account_holder = AccountHolderModelBroker.get_account_holder(
            session,
            id=account_holder_id,
        )

    account = AccountModelBroker.create_account(
        session,
        workspace_key=account_holder.workspace_key,
        external_id=external_id,
        description=description,
        reference=reference,
        account_holder_id=account_holder_id,
        status=AccountStatus.active,
    )
    return AccountId(account.id)
terminate_account
terminate_account(session, /, id)

Terminate an account.

The operation is idempotent, i.e. it has no effect on already terminated entities.

Accounts in terminal state cannot be modified or used anymore. Any attempt to use or retrieve a terminated account will raise an AccountTerminatedException.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/actions/account_actions.py
@obs.api_call()
def terminate_account(
    self,
    session: Session,
    /,
    id: AccountId,
) -> None:
    """
    Terminate an account.

    The operation is idempotent, i.e. it has no effect on already terminated
    entities.

    Accounts in terminal state cannot be modified or used anymore. Any
    attempt to use or retrieve a terminated account will raise an
    `AccountTerminatedException`.
    """
    from shared.services.payment_providers.adyen.openapi.balance_platform_service_v2 import (
        BalanceAccountUpdateRequest,
    )

    with raise_if_account_not_found(id):
        account = AccountModelBroker.get_account(session, id=id)

    if account.status != AccountStatus.closed:
        provider = get_provider_for_workspace(account.workspace_key)
        if provider == PaymentServiceProvider.adyen:
            # Terminating an account should also close it on Adyen side
            self.adyen_client.update_balance_account(
                account.external_id,
                request=BalanceAccountUpdateRequest(
                    status="closed",
                ),
                idempotency_key=None,  # TODO use this for retries
            )

        AccountModelBroker.set_account_status(
            session, id=account.id, status=AccountStatus.closed
        )

    if not account.is_terminated:
        # Terminating an account should set its termination date on first call only
        AccountModelBroker.terminate_account(session, id=id)
update_account
update_account(session, /, id, description, reference=None)

Update the balance account description and reference.

New description/name for the account will be truncated to 300 characters. New optional reference for the account will be truncated to 150 characters.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/actions/account_actions.py
@obs.api_call()
def update_account(
    self,
    session: Session,
    /,
    id: AccountId,
    description: str,
    reference: str | None = None,
) -> None:
    """
    Update the balance account description and reference.

    New description/name for the account will be truncated to 300 characters.
    New optional reference for the account will be truncated to 150 characters.
    """
    from components.payment_gateway.subcomponents.accounts.adapters.adyen.helpers import (
        to_balance_account_info,
    )
    from shared.services.payment_providers.adyen.openapi.balance_platform_service_v2 import (
        BalanceAccountUpdateRequest,
    )

    with raise_if_account_not_found(id):
        account = AccountModelBroker.get_account(session, id=id)

    raise_on_terminated_account(account)

    provider = get_provider_for_workspace(account.workspace_key)
    if provider == PaymentServiceProvider.adyen:
        # 1. Create Adyen request payload from our model
        balance_account_info = to_balance_account_info(
            external_account_holder_id=account.account_holder.external_id,
            description=description,
            reference=reference,
        )
        assert balance_account_info.description is not None

        # 2. Call Adyen API
        self.adyen_client.update_balance_account(
            account.external_id,
            request=BalanceAccountUpdateRequest(
                description=balance_account_info.description,
                reference=balance_account_info.reference,
            ),
            idempotency_key=None,  # TODO use this for retries
        )

        # 3. Update entity from API result
        AccountModelBroker.update_account(
            session,
            id=account.id,
            description=balance_account_info.description,
            reference=balance_account_info.reference,
        )
    else:
        # Update entity from provided description and reference
        AccountModelBroker.update_account(
            session,
            id=account.id,
            description=description,
            reference=reference,
        )

AccountHolderActions

AccountHolderActions(
    adyen_account_holders_client,
    adyen_legal_entities_client,
)

This class contains all the actions related to account holders.

Implements the following Nullable patterns: - Nullables: https://www.jamesshore.com/v2/projects/nullables/testing-without-mocks#nullables ⧉ - Parameterless instantiation: https://www.jamesshore.com/v2/projects/nullables/testing-without-mocks#instantiation ⧉

Tags
Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/actions/account_holder_actions.py
def __init__(
    self,
    adyen_account_holders_client: "AdyenAccountHoldersApiClient | None",
    adyen_legal_entities_client: "AdyenLegalEntitiesApiClient | None",
) -> None:
    self._adyen_account_holders_client = adyen_account_holders_client
    self._adyen_legal_entities_client = adyen_legal_entities_client

Attributes

adyen_account_holders_client property
adyen_account_holders_client

Ensures the Adyen client is available when accessing it.

adyen_legal_entities_client

Ensures the Adyen client is available when accessing it.

Functions

create classmethod
create()

Normal factory

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/actions/account_holder_actions.py
@classmethod
def create(cls) -> "AccountHolderActions":
    """Normal factory"""
    from shared.services.payment_providers.adyen.clients.adyen_account_holders_api_client import (
        AdyenAccountHoldersApiClient,
    )
    from shared.services.payment_providers.adyen.clients.adyen_legal_entities_api_client import (
        AdyenLegalEntitiesApiClient,
    )
    from shared.services.payment_providers.adyen.clients.exceptions import (
        AdyenClientMissingCredentialsException,
    )

    try:
        adyen_account_holders_client = AdyenAccountHoldersApiClient.create()
    except AdyenClientMissingCredentialsException:
        adyen_account_holders_client = None

    try:
        adyen_legal_entities_client = AdyenLegalEntitiesApiClient.create()
    except AdyenClientMissingCredentialsException:
        adyen_legal_entities_client = None

    return cls(
        adyen_account_holders_client,
        adyen_legal_entities_client,
    )
create_null classmethod
create_null()

Null factory

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/actions/account_holder_actions.py
@classmethod
def create_null(cls) -> "AccountHolderActions":
    """Null factory"""
    from shared.services.payment_providers.adyen.clients.adyen_account_holders_api_client import (
        AdyenAccountHoldersApiClient,
    )
    from shared.services.payment_providers.adyen.clients.adyen_legal_entities_api_client import (
        AdyenLegalEntitiesApiClient,
    )

    return cls(
        AdyenAccountHoldersApiClient.create_null(),
        AdyenLegalEntitiesApiClient.create_null(),
    )
declare_account_holder
declare_account_holder(
    session,
    /,
    workspace_key,
    external_id,
    description,
    reference=None,
)

Declare an account holder.

The account holder must exist in the PSP workspace.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/actions/account_holder_actions.py
@obs.api_call()
def declare_account_holder(
    self,
    session: Session,
    /,
    workspace_key: str,
    external_id: str,
    description: str,
    reference: str | None = None,
) -> AccountHolderId:
    """
    Declare an account holder.

    The account holder must exist in the PSP workspace.
    """
    account_holder = AccountHolderModelBroker.create_account_holder(
        session,
        workspace_key=workspace_key,
        external_id=external_id,
        description=description,
        reference=reference,
    )
    return AccountHolderId(account_holder.id)
terminate_account_holder
terminate_account_holder(session, /, id)

Terminate an account holder.

The operation is idempotent, i.e. it has no effect on already terminated entities.

Account holders in terminal state cannot be modified or used anymore. Any attempt to use or retrieve a terminated account holder will raise an AccountHolderTerminatedException.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/actions/account_holder_actions.py
@obs.api_call()
def terminate_account_holder(
    self,
    session: Session,
    /,
    id: AccountHolderId,
) -> None:
    """
    Terminate an account holder.

    The operation is idempotent, i.e. it has no effect on already terminated
    entities.

    Account holders in terminal state cannot be modified or used anymore.
    Any attempt to use or retrieve a terminated account holder will raise an
    `AccountHolderTerminatedException`.
    """
    with raise_if_account_holder_not_found(id):
        account_holder = AccountHolderModelBroker.get_account_holder(session, id=id)

    if not account_holder.is_terminated:
        AccountHolderModelBroker.terminate_account_holder(session, id=id)
update_account_holder_legal_name(
    session, /, id, legal_name
)

Update the legal name of an account holder.

This method updates the legal name of an account holder in both the database and the third party API.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/actions/account_holder_actions.py
@obs.api_call()
def update_account_holder_legal_name(
    self,
    session: Session,
    /,
    id: AccountHolderId,
    legal_name: str,
) -> None:
    """
    Update the legal name of an account holder.

    This method updates the legal name of an account holder in both the
    database and the third party API.
    """
    from shared.services.payment_providers.adyen.openapi.legal_entity_service_v3 import (
        LegalEntityInfo,
    )

    with raise_if_account_holder_not_found(id):
        account_holder = AccountHolderModelBroker.get_account_holder(session, id=id)

    raise_on_terminated_account_holder(account_holder)

    # 1. Get legal entity ID from Adyen  # TODO @frederic.bonnet 2025-10-01 store it in the database? Depends on how it's done with other PSPs
    account_holder_data = self.adyen_account_holders_client.get_account_holder(
        id=account_holder.external_id
    )

    # 2. Get legal entity data from Adyen
    current_entity = self.adyen_legal_entities_client.get_legal_entity(
        id=account_holder_data.legalEntityId,
        idempotency_key=None,
    )

    # 3. Update legal entity name on Adyen
    assert current_entity.organization is not None, (
        "Legal entity must have an organization"
    )
    current_entity.organization.legalName = legal_name
    self.adyen_legal_entities_client.update_legal_entity(
        id=current_entity.id,
        request=LegalEntityInfo(
            type=current_entity.type, organization=current_entity.organization
        ),
    )

AccountHolderNotFoundException

Bases: PaymentAccountException

Exception raised when trying to use a non-existing Account Holder.

AccountHolderQueries

This class contains all the queries related to account holders.

Functions

get_account_holder
get_account_holder(session, /, id)

Get an account holder entity from its ID.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/queries/account_holder_queries.py
@obs.api_call()
def get_account_holder(
    self,
    session: Session,
    /,
    id: AccountHolderId,
) -> AccountHolder:
    """
    Get an account holder entity from its ID.
    """
    with raise_if_account_holder_not_found(id):
        account_holder = AccountHolderModelBroker.get_account_holder(session, id=id)

    raise_on_terminated_account_holder(account_holder)

    return AccountHolder(
        id=AccountHolderId(account_holder.id),
        workspace_key=account_holder.workspace_key,
        external_id=account_holder.external_id,
        description=account_holder.description,
        reference=account_holder.reference,
    )
get_account_holder_id_by_external_id
get_account_holder_id_by_external_id(
    session, /, workspace_key, external_id
)

Get an account holder entity from its external ID.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/queries/account_holder_queries.py
@obs.api_call()
def get_account_holder_id_by_external_id(
    self,
    session: Session,
    /,
    workspace_key: str,
    external_id: str,
) -> AccountHolderId:
    """
    Get an account holder entity from its external ID.
    """
    with raise_if_account_holder_not_found_for_external_id(external_id):
        account_holder_id = (
            AccountHolderModelBroker.get_account_holder_id_by_external_id(
                session,
                workspace_key=workspace_key,
                external_id=external_id,
            )
        )

    return AccountHolderId(account_holder_id)

AccountHolderTerminatedException

Bases: PaymentAccountException

Exception raised when trying to use a terminated Account Holder.

AccountNotFoundException

Bases: PaymentAccountException

Exception raised when trying to use a non-existing Account.

AccountQueries

This class contains all the queries related to accounts.

Functions

get_account
get_account(session, /, id)

Get an account entity from its ID.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/queries/account_queries.py
@obs.api_call()
def get_account(
    self,
    session: Session,
    /,
    id: AccountId,
) -> Account:
    """
    Get an account entity from its ID.
    """
    with raise_if_account_not_found(id):
        account = AccountModelBroker.get_account(session, id=id)

    raise_on_terminated_account(account)

    return _to_account(account)
get_account_id_by_external_id
get_account_id_by_external_id(
    session, /, workspace_key, external_id
)

Get an account ID by its external ID.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/queries/account_queries.py
@obs.api_call()
def get_account_id_by_external_id(
    self,
    session: Session,
    /,
    workspace_key: str,
    external_id: str,
) -> AccountId:
    """
    Get an account ID by its external ID.
    """
    account_id = AccountModelBroker.get_account_id_by_external_id(
        session,
        workspace_key=workspace_key,
        external_id=external_id,
    )

    return AccountId(account_id)
get_account_ids_for_account_holder
get_account_ids_for_account_holder(
    session, /, account_holder_id
)

Get all the account IDs for an account holder.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/queries/account_queries.py
@obs.api_call()
def get_account_ids_for_account_holder(
    self,
    session: Session,
    /,
    account_holder_id: AccountHolderId,
) -> list[AccountId]:
    """
    Get all the account IDs for an account holder.
    """
    return [
        AccountId(account_id)
        for account_id in AccountModelBroker.list_account_ids_for_account_holder(
            session, account_holder_id=account_holder_id
        )
    ]
get_accounts_for_account_holder
get_accounts_for_account_holder(
    session, /, account_holder_id
)

Get all the accounts for an account holder.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/queries/account_queries.py
@obs.api_call()
def get_accounts_for_account_holder(
    self,
    session: Session,
    /,
    account_holder_id: AccountHolderId,
) -> list[Account]:
    """
    Get all the accounts for an account holder.
    """
    return [
        _to_account(account)
        for account in AccountModelBroker.list_accounts_for_account_holder(
            session, account_holder_id=account_holder_id
        )
    ]

AccountTerminatedException

Bases: PaymentAccountException

Exception raised when trying to use a terminated Account.

InvalidAccountStatusTransitionException

Bases: PaymentAccountException, ValueError

Exception raised when attempting an invalid Account status transition.

PaymentAccountException

Bases: PaymentGatewayException

Base class for all Account exceptions.

SepaBeneficiaryLogic

This class is the public interface to the SEPA beneficiaries logic.

Functions

declare_sepa_beneficiary
declare_sepa_beneficiary(
    session,
    /,
    account_id,
    external_id,
    issued_at,
    name,
    iban,
    status=SepaBeneficiaryStatus.enabled,
)

Declare a new SEPA beneficiary on the given account.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/sepa_beneficiaries.py
@obs.api_call()
def declare_sepa_beneficiary(
    self,
    session: Session,
    /,
    account_id: AccountId,
    external_id: str,
    issued_at: datetime,
    name: str,
    iban: str,
    status: SepaBeneficiaryStatus = SepaBeneficiaryStatus.enabled,
) -> SepaBeneficiary:
    """
    Declare a new SEPA beneficiary on the given account.
    """
    with raise_if_account_not_found(account_id):
        account = AccountModelBroker.get_account(session, account_id)

    sepa_beneficiary = SepaBeneficiaryModelBroker.create_sepa_beneficiary(
        session,
        workspace_key=account.workspace_key,
        external_id=external_id,
        account_id=account_id,
        issued_at=issued_at,
        name=name,
        iban=iban,
        status=status,
    )

    return _to_sepa_beneficiary(sepa_beneficiary_model=sepa_beneficiary)
get_sepa_beneficiary
get_sepa_beneficiary(session, /, id)

Get a SEPA beneficiary entity from its ID.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/sepa_beneficiaries.py
@obs.api_call()
def get_sepa_beneficiary(
    self,
    session: Session,
    /,
    id: SepaBeneficiaryId,
) -> SepaBeneficiary:
    """
    Get a SEPA beneficiary entity from its ID.
    """
    with raise_if_sepa_beneficiary_not_found(id):
        sepa_beneficiary = SepaBeneficiaryModelBroker.get_sepa_beneficiary(
            session,
            id=id,
        )

    return _to_sepa_beneficiary(sepa_beneficiary_model=sepa_beneficiary)
get_sepa_beneficiary_by_external_id
get_sepa_beneficiary_by_external_id(
    session, /, workspace_key, external_id
)

Find a SEPA beneficiary by its external ID.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/sepa_beneficiaries.py
@obs.api_call()
def get_sepa_beneficiary_by_external_id(
    self,
    session: Session,
    /,
    workspace_key: str,
    external_id: str,
) -> Optional[SepaBeneficiary]:
    """
    Find a SEPA beneficiary by its external ID.
    """
    with raise_if_sepa_beneficiary_not_found_for_external_id(external_id):
        sepa_beneficiary = (
            SepaBeneficiaryModelBroker.find_sepa_beneficiary_by_external_id(
                session,
                workspace_key=workspace_key,
                external_id=external_id,
            )
        )

    return (
        _to_sepa_beneficiary(sepa_beneficiary_model=sepa_beneficiary)
        if sepa_beneficiary is not None
        else None
    )
set_sepa_beneficiary_status
set_sepa_beneficiary_status(session, /, id, status)

Update the status of the given SEPA beneficiary.

Source code in components/payment_gateway/subcomponents/accounts/protected/business_logic/sepa_beneficiaries.py
@obs.api_call()
def set_sepa_beneficiary_status(
    self,
    session: Session,
    /,
    id: SepaBeneficiaryId,
    status: SepaBeneficiaryStatus,
) -> None:
    """
    Update the status of the given SEPA beneficiary.
    """
    with raise_if_sepa_beneficiary_not_found(id):
        SepaBeneficiaryModelBroker.set_sepa_beneficiary_status(
            session,
            id=id,
            status=status,
        )