Skip to content

Business logic

Card Holders

CardHolderLogic

CardHolderLogic(card_holder_queries, card_holder_actions)

This class is the public interface to the card holder logic.

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 ⧉

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_holders.py
def __init__(
    self,
    card_holder_queries: CardHolderQueries,
    card_holder_actions: CardHolderActions,
) -> None:
    self.card_holder_queries = card_holder_queries
    self.card_holder_actions = card_holder_actions

card_holder_actions instance-attribute

card_holder_actions = card_holder_actions

card_holder_queries instance-attribute

card_holder_queries = card_holder_queries

create classmethod

create()

Normal factory

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_holders.py
@classmethod
def create(cls) -> "CardHolderLogic":
    """Normal factory"""
    return cls(
        card_holder_queries=CardHolderQueries(),
        card_holder_actions=CardHolderActions.create(),
    )

create_null classmethod

create_null()

Null factory

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_holders.py
@classmethod
def create_null(cls) -> "CardHolderLogic":
    """Null factory"""
    return cls(
        card_holder_queries=CardHolderQueries(),
        card_holder_actions=CardHolderActions.create_null(),
    )

declare_card_holder

declare_card_holder(
    session,
    /,
    first_name,
    last_name,
    display_name=None,
    short_name=None,
    provider=PaymentServiceProvider.adyen,
    external_id=None,
)

Declare a card holder.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_holders.py
@obs.api_call()
def declare_card_holder(
    self,
    session: Session,
    /,
    first_name: str,
    last_name: str,
    display_name: str | None = None,
    short_name: str | None = None,
    provider: PaymentServiceProvider = PaymentServiceProvider.adyen,
    external_id: str | None = None,
) -> CardHolderId:
    """
    Declare a card holder.
    """
    return self.card_holder_actions.declare_card_holder(
        session,
        first_name=first_name,
        last_name=last_name,
        display_name=display_name,
        short_name=short_name,
        provider=provider,
        external_id=external_id,
    )

get_card_holder

get_card_holder(session, /, id)

Get a card holder entity from its ID.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_holders.py
@obs.api_call()
def get_card_holder(
    self,
    session: Session,
    /,
    id: CardHolderId,
) -> CardHolder:
    """
    Get a card holder entity from its ID.
    """
    return self.card_holder_queries.get_card_holder(
        session,
        id,
    )

terminate_card_holder

terminate_card_holder(session, /, id)

Terminate a card holder.

Card holders in terminal state cannot be modified or used anymore.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_holders.py
@obs.api_call()
def terminate_card_holder(
    self,
    session: Session,
    /,
    id: CardHolderId,
) -> None:
    """
    Terminate a card holder.

    Card holders in terminal state cannot be modified or used anymore.
    """
    self.card_holder_actions.terminate_card_holder(
        session,
        id,
    )

update_card_holder_contact_info

update_card_holder_contact_info(
    session, /, id, phone_number, email
)

Update the phone number and email of a card holder on the PSP. Phone number is is needed to add cards to digital wallets. Email is optional as a second option for adding cards to digit wallets.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_holders.py
@obs.api_call()
def update_card_holder_contact_info(
    self,
    session: Session,
    /,
    id: CardHolderId,
    phone_number: str,
    email: str | None,
) -> None:
    """
    Update the phone number and email of a card holder on the PSP.
    Phone number is is needed to add cards to digital wallets.
    Email is optional as a second option for adding cards to digit wallets.
    """
    self.card_holder_actions.update_card_holder_contact_info(
        session,
        id,
        phone_number=phone_number,
        email=email,
    )

update_card_holder_identity

update_card_holder_identity(
    session,
    /,
    id,
    first_name,
    last_name,
    display_name,
    short_name,
)

Update the identity of a card holder.

The current identity of a card holder is used when issuing a card. The identity of a card holder may change over time, but cards are immutable.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_holders.py
@obs.api_call()
def update_card_holder_identity(
    self,
    session: Session,
    /,
    id: CardHolderId,
    first_name: str,
    last_name: str,
    display_name: str | None,
    short_name: str | None,
) -> None:
    """
    Update the identity of a card holder.

    The current identity of a card holder is used when issuing a card.
    The identity of a card holder may change over time, but cards are immutable.
    """
    self.card_holder_actions.update_card_holder_identity(
        session,
        id,
        first_name=first_name,
        last_name=last_name,
        display_name=display_name,
        short_name=short_name,
    )

Cards

CardLogic

CardLogic(
    card_queries,
    card_reveal_queries,
    card_authentication_actions,
)

This class is the public interface to the card logic.

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 ⧉

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/cards.py
def __init__(
    self,
    card_queries: CardQueries,
    card_reveal_queries: CardRevealQueries,
    card_authentication_actions: CardAuthenticationActions,
) -> None:
    self.card_queries = card_queries
    self.card_reveal_queries = card_reveal_queries
    self.card_authentication_actions = card_authentication_actions

card_authentication_actions instance-attribute

card_authentication_actions = card_authentication_actions

card_queries instance-attribute

card_queries = card_queries

card_reveal_queries instance-attribute

card_reveal_queries = card_reveal_queries

create classmethod

create()

Normal factory

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/cards.py
@classmethod
def create(cls) -> "CardLogic":
    """Normal factory"""
    return cls(
        card_queries=CardQueries(),
        card_reveal_queries=CardRevealQueries.create(),
        card_authentication_actions=CardAuthenticationActions.create(),
    )

create_null classmethod

create_null()

Null factory

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/cards.py
@classmethod
def create_null(cls) -> "CardLogic":
    """Null factory"""
    return cls(
        card_queries=CardQueries(),
        card_reveal_queries=CardRevealQueries.create_null(),
        card_authentication_actions=CardAuthenticationActions.create_null(),
    )

edit_card_authentication_info

edit_card_authentication_info(
    session, /, id, phone_number, email
)

Update the card authentication info. The phone number is mandatory, the email is optional

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/cards.py
@obs.api_call()
def edit_card_authentication_info(
    self,
    session: Session,
    /,
    id: CardId,
    phone_number: str,
    email: str | None,
) -> None:
    """
    Update the card authentication info. The phone number is mandatory, the email is optional
    """
    self.card_authentication_actions.edit_card_authentication_info(
        session,
        id,
        phone_number,
        email,
    )

get_card

get_card(session, id)

Get a card entity from its ID.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/cards.py
@obs.api_call()
def get_card(
    self,
    session: Session,
    id: CardId,
) -> Card:
    """
    Get a card entity from its ID.
    """
    return self.card_queries.get_card(
        session,
        id,
    )

get_card_ids_for_account

get_card_ids_for_account(session, account_id)

Get all the card IDs for an account.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/cards.py
@obs.api_call()
def get_card_ids_for_account(
    self,
    session: Session,
    account_id: AccountId,
) -> list[CardId]:
    """
    Get all the card IDs for an account.
    """
    return self.card_queries.get_card_ids_for_account(
        session,
        account_id,
    )

get_card_ids_for_card_holder

get_card_ids_for_card_holder(session, card_holder_id)

Get all the card IDs for a card holder.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/cards.py
@obs.api_call()
def get_card_ids_for_card_holder(
    self,
    session: Session,
    card_holder_id: CardHolderId,
) -> list[CardId]:
    """
    Get all the card IDs for a card holder.
    """
    return self.card_queries.get_card_ids_for_card_holder(
        session,
        card_holder_id,
    )

get_card_pan_reveal_public_key

get_card_pan_reveal_public_key()

Get the base-64 public key used for client-side encryption of card PAN reveal requests.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/cards.py
@obs.api_call()
def get_card_pan_reveal_public_key(self) -> str:
    """
    Get the base-64 public key used for client-side encryption of card PAN reveal requests.
    """
    return self.card_reveal_queries.get_card_pan_reveal_public_key()

get_card_pin_reveal_public_key

get_card_pin_reveal_public_key()

Get the base-64 public key used for client-side encryption of card PIN reveal requests.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/cards.py
@obs.api_call()
def get_card_pin_reveal_public_key(self) -> str:
    """
    Get the base-64 public key used for client-side encryption of card PIN reveal requests.
    """
    return self.card_reveal_queries.get_card_pin_reveal_public_key()

get_cards_for_account

get_cards_for_account(session, account_id)

Get all the cards for an account.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/cards.py
@obs.api_call()
def get_cards_for_account(
    self,
    session: Session,
    account_id: AccountId,
) -> list[Card]:
    """
    Get all the cards for an account.
    """
    return self.card_queries.get_cards_for_account(
        session,
        account_id,
    )

get_cards_for_card_holder

get_cards_for_card_holder(session, card_holder_id)

Get all the cards for a card holder.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/cards.py
@obs.api_call()
def get_cards_for_card_holder(
    self,
    session: Session,
    card_holder_id: CardHolderId,
) -> list[Card]:
    """
    Get all the cards for a card holder.
    """
    return self.card_queries.get_cards_for_card_holder(
        session,
        card_holder_id,
    )

reveal_card_default_password

reveal_card_default_password(id)

Reveal the default password of a card.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/cards.py
@obs.api_call()
def reveal_card_default_password(
    self,
    /,
    id: CardId,
) -> str:
    """
    Reveal the default password of a card.
    """
    return self.card_reveal_queries.reveal_card_default_password(id)

reveal_card_pan

reveal_card_pan(session, id, encrypted_aes_key)

Reveal the PAN of a card.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/cards.py
@obs.api_call()
def reveal_card_pan(
    self,
    session: Session,
    id: CardId,
    encrypted_aes_key: str,
) -> CardRevealPANData:
    """
    Reveal the PAN of a card.
    """
    return self.card_reveal_queries.reveal_card_pan(
        session,
        id,
        encrypted_aes_key,
    )

reveal_card_pin

reveal_card_pin(session, id, encrypted_aes_key)

Reveal the PAN of a card.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/cards.py
@obs.api_call()
def reveal_card_pin(
    self,
    session: Session,
    id: CardId,
    encrypted_aes_key: str,
) -> CardRevealPINData:
    """
    Reveal the PAN of a card.
    """
    return self.card_reveal_queries.reveal_card_pin(
        session,
        id,
        encrypted_aes_key,
    )

CardLifecycleLogic

CardLifecycleLogic(card_lifecycle_actions)

This class is the public interface to the card lifecycle logic.

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 ⧉

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_lifecycle.py
def __init__(self, card_lifecycle_actions: CardLifecycleActions) -> None:
    self.card_lifecycle_actions = card_lifecycle_actions

card_lifecycle_actions instance-attribute

card_lifecycle_actions = card_lifecycle_actions

create classmethod

create()

Normal factory

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_lifecycle.py
@classmethod
def create(cls) -> "CardLifecycleLogic":
    """Normal factory"""
    return cls(CardLifecycleActions.create())

create_card

create_card(
    session,
    /,
    card_holder_id,
    account_id,
    form_factor,
    phone_number,
    email,
    shipment_info=None,
    issued_at=None,
    issuance_reason=None,
    description=None,
    reference=None,
    configuration=None,
)

Create a card for a card holder.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_lifecycle.py
@obs.api_call()
def create_card(
    self,
    session: Session,
    /,
    card_holder_id: CardHolderId,
    account_id: AccountId,
    form_factor: CardFormFactor,
    phone_number: str,
    email: str | None,
    shipment_info: CardShipmentInfo | None = None,
    issued_at: datetime | None = None,
    issuance_reason: str | None = None,
    description: str | None = None,
    reference: str | None = None,
    # TODO @frederic.bonnet 2024-06-30: pass configuration_id instead
    configuration: CardIssuingConfiguration | None = None,
) -> CardId:
    """
    Create a card for a card holder.
    """
    return self.card_lifecycle_actions.create_card(
        session,
        card_holder_id=card_holder_id,
        account_id=account_id,
        form_factor=form_factor,
        phone_number=phone_number,
        email=email,
        shipment_info=shipment_info,
        issued_at=issued_at,
        issuance_reason=issuance_reason,
        description=description,
        reference=reference,
        configuration=configuration,
    )

create_null classmethod

create_null(track_adyen_requests=None)

Null factory

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_lifecycle.py
@classmethod
def create_null(
    cls,
    track_adyen_requests: list[tuple[str, dict, dict]] | None = None,  # type: ignore[type-arg]
) -> "CardLifecycleLogic":
    """Null factory"""
    return cls(
        CardLifecycleActions.create_null(track_adyen_requests=track_adyen_requests)
    )

terminate_card

terminate_card(session, /, id)

Terminate a card.

Cards in terminal state cannot be modified or used anymore.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_lifecycle.py
@obs.api_call()
def terminate_card(
    self,
    session: Session,
    /,
    id: CardId,
) -> None:
    """
    Terminate a card.

    Cards in terminal state cannot be modified or used anymore.
    """
    self.card_lifecycle_actions.terminate_card(
        session,
        id,
    )

CardStatusLogic

CardStatusLogic(card_status_actions)

This class is the public interface to the card status logic.

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 ⧉

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_status.py
def __init__(self, card_status_actions: CardStatusActions) -> None:
    self.card_status_actions = card_status_actions

    # TODO WIP we haven't decided on the pattern we'll use for public events. For now let's declare them as topics.
    self.card_suspended_by_provider_topic = Topic[CardSuspendedByProvider]()

card_status_actions instance-attribute

card_status_actions = card_status_actions

card_suspended_by_provider_topic instance-attribute

card_suspended_by_provider_topic = Topic[
    CardSuspendedByProvider
]()

activate_card

activate_card(session, /, id)

Activate a card.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_status.py
@obs.api_call()
def activate_card(
    self,
    session: Session,
    /,
    id: CardId,
) -> None:
    """
    Activate a card.
    """
    self.card_status_actions.activate_card(
        session,
        id,
    )

close_card

close_card(session, /, id, reason)

Close a card. This action is non-revertible.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_status.py
@obs.api_call()
def close_card(
    self,
    session: Session,
    /,
    id: CardId,
    reason: str,
) -> None:
    """
    Close a card. This action is non-revertible.
    """
    self.card_status_actions.close_card(
        session,
        id,
        reason=reason,
    )

create classmethod

create()

Normal factory

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_status.py
@classmethod
def create(cls) -> "CardStatusLogic":
    """Normal factory"""
    return cls(CardStatusActions.create())

create_null classmethod

create_null(track_adyen_requests=None)

Null factory

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_status.py
@classmethod
def create_null(
    cls,
    track_adyen_requests: list[tuple[str, dict, dict]] | None = None,  # type: ignore[type-arg]
) -> "CardStatusLogic":
    """Null factory"""
    return cls(
        CardStatusActions.create_null(track_adyen_requests=track_adyen_requests)
    )

suspend_card

suspend_card(
    session, /, id, reason, suspension_source=None
)

Suspend a card.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_status.py
@obs.api_call()
def suspend_card(
    self,
    session: Session,
    /,
    id: CardId,
    reason: str,
    suspension_source: CardSuspensionSource | None = None,
) -> None:
    """
    Suspend a card.
    """
    self.card_status_actions.suspend_card(
        session,
        id,
        reason=reason,
        suspension_source=suspension_source,
    )

CardSuspendedByProvider dataclass

CardSuspendedByProvider(id, reason)

id instance-attribute

id

reason instance-attribute

reason

CardIncidentsLogic

CardIncidentsLogic(card_incidents_actions)

This class is the public interface to the card incidents declaration logic.

Incidents should eventually lead to the replacement of the card.

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 ⧉

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_incidents.py
def __init__(self, card_incidents_actions: CardIncidentsActions) -> None:
    self.card_incidents_actions = card_incidents_actions

card_incidents_actions instance-attribute

card_incidents_actions = card_incidents_actions

create classmethod

create()

Normal factory

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_incidents.py
@classmethod
def create(cls) -> "CardIncidentsLogic":
    """Normal factory"""
    return cls(CardIncidentsActions.create())

create_null classmethod

create_null(track_adyen_requests=None)

Null factory

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_incidents.py
@classmethod
def create_null(
    cls,
    track_adyen_requests: list[tuple[str, dict, dict]] | None = None,  # type: ignore[type-arg]
) -> "CardIncidentsLogic":
    """Null factory"""
    return cls(
        CardIncidentsActions.create_null(track_adyen_requests=track_adyen_requests)
    )

declare_card_damaged

declare_card_damaged(
    session, /, id, suspension_source=None
)

Declare a card as damaged.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_incidents.py
@obs.api_call()
def declare_card_damaged(
    self,
    session: Session,
    /,
    id: CardId,
    suspension_source: CardSuspensionSource | None = None,
) -> None:
    """
    Declare a card as damaged.
    """
    self.card_incidents_actions.declare_card_damaged(
        session,
        id,
        suspension_source=suspension_source,
    )

declare_card_lost

declare_card_lost(session, /, id, suspension_source=None)

Declare a card as lost.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_incidents.py
@obs.api_call()
def declare_card_lost(
    self,
    session: Session,
    /,
    id: CardId,
    suspension_source: CardSuspensionSource | None = None,
) -> None:
    """
    Declare a card as lost.
    """
    self.card_incidents_actions.declare_card_lost(
        session,
        id,
        suspension_source=suspension_source,
    )

declare_card_stolen

declare_card_stolen(session, /, id, suspension_source=None)

Declare a card as stolen.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_incidents.py
@obs.api_call()
def declare_card_stolen(
    self,
    session: Session,
    /,
    id: CardId,
    suspension_source: CardSuspensionSource | None = None,
) -> None:
    """
    Declare a card as stolen.
    """
    self.card_incidents_actions.declare_card_stolen(
        session,
        id,
        suspension_source=suspension_source,
    )

declare_card_temporarily_suspended

declare_card_temporarily_suspended(
    session, /, id, suspension_source
)

Declare a card as temporarily suspended.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_incidents.py
@obs.api_call()
def declare_card_temporarily_suspended(
    self,
    session: Session,
    /,
    id: CardId,
    suspension_source: CardSuspensionSource,
) -> None:
    """
    Declare a card as temporarily suspended.
    """
    self.card_incidents_actions.declare_card_temporarily_suspended(
        session,
        id,
        suspension_source=suspension_source,
    )

CardDelivered dataclass

CardDelivered(id)

id instance-attribute

id

CardDeliveryLogic

CardDeliveryLogic()

This class is the public interface to the card delivery logic.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_delivery.py
def __init__(self) -> None:
    self.card_order_queries = CardOrderQueries()
    self.card_delivery_actions = CardDeliveryActions()

    # TODO WIP we haven't decided on the pattern we'll use for public events. For now let's declare them as topics.
    self.card_ordered_topic = Topic[CardOrdered]()
    self.card_delivery_status_changed_topic = Topic[CardDeliveryStatusChanged]()
    self.card_delivered_topic = Topic[CardDelivered]()
    self.card_not_delivered_topic = Topic[CardNotDelivered]()

card_delivered_topic instance-attribute

card_delivered_topic = Topic[CardDelivered]()

card_delivery_actions instance-attribute

card_delivery_actions = CardDeliveryActions()

card_delivery_status_changed_topic instance-attribute

card_delivery_status_changed_topic = Topic[
    CardDeliveryStatusChanged
]()

card_not_delivered_topic instance-attribute

card_not_delivered_topic = Topic[CardNotDelivered]()

card_order_queries instance-attribute

card_order_queries = CardOrderQueries()

card_ordered_topic instance-attribute

card_ordered_topic = Topic[CardOrdered]()

declare_card_not_received

declare_card_not_received(session, /, id)
Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_delivery.py
@obs.api_call()
def declare_card_not_received(  # noqa: D102
    self,
    session: Session,
    /,
    id: CardId,
) -> None:
    self.card_delivery_actions.declare_card_not_received(
        session,
        id,
    )

declare_card_received

declare_card_received(session, /, id)
Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_delivery.py
@obs.api_call()
def declare_card_received(  # noqa: D102
    self,
    session: Session,
    /,
    id: CardId,
) -> None:
    self.card_delivery_actions.declare_card_received(
        session,
        id,
    )

get_card_order

get_card_order(session, /, card_id)

Get the card order info for a card.

Source code in components/payment_gateway/subcomponents/cards/protected/business_logic/card_delivery.py
@obs.api_call()
def get_card_order(
    self,
    session: Session,
    /,
    card_id: CardId,
) -> CardOrder:
    """
    Get the card order info for a card.
    """
    return self.card_order_queries.get_card_order(
        session,
        card_id,
    )

CardDeliveryStatusChanged dataclass

CardDeliveryStatusChanged(id, status)

id instance-attribute

id

status instance-attribute

status

CardNotDelivered dataclass

CardNotDelivered(id)

id instance-attribute

id

CardOrdered dataclass

CardOrdered(id)

id instance-attribute

id