Skip to content

Models

components.payment_gateway.subcomponents.cards.models.card

Card

Bases: BaseModel

__table_args__ class-attribute instance-attribute

__table_args__ = (
    UniqueConstraint(
        "provider",
        "external_id",
        name="card__unique_external_id_per_provider",
    ),
    {"schema": PAYMENT_GATEWAY_SCHEMA_NAME},
)

__tablename__ class-attribute instance-attribute

__tablename__ = 'card'

account class-attribute instance-attribute

account = relationship(Account, foreign_keys=account_id)

account_id class-attribute instance-attribute

account_id = mapped_column(
    UUID(as_uuid=True),
    ForeignKey(id),
    index=True,
    nullable=True,
)

all_card_provisioning class-attribute instance-attribute

all_card_provisioning = relationship(
    "CardProvisioning",
    back_populates="card",
    order_by="CardProvisioning.provisioning_date.desc()",
    uselist=True,
    viewonly=True,
)

card_holder class-attribute instance-attribute

card_holder = relationship(
    CardHolder,
    foreign_keys=card_holder_id,
    back_populates="cards",
)

card_holder_id class-attribute instance-attribute

card_holder_id = mapped_column(
    UUID(as_uuid=True),
    ForeignKey(id),
    index=True,
    nullable=True,
)

current_status_log class-attribute instance-attribute

current_status_log = relationship(
    "CardStatusLog",
    uselist=False,
    viewonly=True,
    primaryjoin="and_(   CardStatusLog.card_id == Card.id,   CardStatusLog.created_at == (       select(func.max(CardStatusLog.created_at))       .where(CardStatusLog.card_id == Card.id)       .correlate(Card)       .scalar_subquery()   ))",
)

description class-attribute instance-attribute

description = mapped_column(Text, nullable=True)

display_name class-attribute instance-attribute

display_name = mapped_column_with_privacy(
    Text,
    nullable=False,
    privacy_properties=PrivacyProperties(
        some_name,
        NoneOrRedactedHashed(),
        NoneOrEncrypted(),
        FakeFullname(),
        PassThrough(),
        NoneOrPrefixRedactedHashed(),
    ),
)

expiration_date class-attribute instance-attribute

expiration_date = mapped_column(Date, nullable=False)

external_id class-attribute instance-attribute

external_id = mapped_column(
    String(255), nullable=False, index=True
)

ID used by the external payment service provider to identify the card.

is_physical property

is_physical

is_terminated property

is_terminated

is_virtual class-attribute instance-attribute

is_virtual = mapped_column(Boolean, nullable=False)

issuance_reason class-attribute instance-attribute

issuance_reason = mapped_column(Text, nullable=True)

issued_at class-attribute instance-attribute

issued_at = mapped_column(DateTime, nullable=False)

last_four_digits class-attribute instance-attribute

last_four_digits = mapped_column(String(4), nullable=False)

payments class-attribute instance-attribute

payments = relationship(
    "CardTransfer",
    back_populates="card",
    order_by="CardTransfer.created_at.desc()",
    uselist=True,
    viewonly=True,
)

provider class-attribute instance-attribute

provider = mapped_column(
    AlanBaseEnumTypeDecorator(PaymentServiceProvider),
    nullable=False,
)

The payment service provider that issued the card.

reference class-attribute instance-attribute

reference = mapped_column(Text, nullable=True)

status property

status

status_history class-attribute instance-attribute

status_history = relationship(
    "CardStatusLog",
    back_populates="card",
    order_by="CardStatusLog.created_at.desc()",
    uselist=True,
    viewonly=True,
)

terminated_at class-attribute instance-attribute

terminated_at = mapped_column(DateTime, nullable=True)

Termination is done at the initiative of the business layer. Cards in terminal state cannot be modified or used anymore.

validate_provider class-attribute instance-attribute

validate_provider = create_validator('provider')

CardStatusLog

Bases: BaseModel

__repr__

__repr__()
Source code in components/payment_gateway/subcomponents/cards/models/card.py
def __repr__(self) -> str:
    return f"<CardStatusLog [{self.id}]: {self.status}>"

__table_args__ class-attribute instance-attribute

__table_args__ = {'schema': PAYMENT_GATEWAY_SCHEMA_NAME}

__tablename__ class-attribute instance-attribute

__tablename__ = 'card_status_log'

card class-attribute instance-attribute

card = relationship(
    Card,
    foreign_keys=card_id,
    back_populates="status_history",
)

card_id class-attribute instance-attribute

card_id = mapped_column(
    UUID(as_uuid=True),
    ForeignKey(id),
    nullable=False,
    index=True,
)

reason class-attribute instance-attribute

reason = mapped_column(Text, nullable=True)

status class-attribute instance-attribute

status = mapped_column(
    AlanBaseEnumTypeDecorator(CardStatus), nullable=False
)

suspension_source class-attribute instance-attribute

suspension_source = mapped_column(
    AlanBaseEnumTypeDecorator(CardSuspensionSource),
    nullable=True,
)

components.payment_gateway.subcomponents.cards.models.card_holder

CardHolder

Bases: BaseModel

__table_args__ class-attribute instance-attribute

__table_args__ = (
    UniqueConstraint(
        "provider",
        "external_id",
        name="card_holder__unique_external_id_per_provider",
    ),
    CheckConstraint(
        "(external_id IS NULL) = (provider IN ('adyen'))",
        name="card_holder__no_external_id_for_adyen",
    ),
    {"schema": PAYMENT_GATEWAY_SCHEMA_NAME},
)

__tablename__ class-attribute instance-attribute

__tablename__ = 'card_holder'

cards class-attribute instance-attribute

cards = relationship(
    "Card",
    back_populates="card_holder",
    order_by="Card.created_at.desc()",
    uselist=True,
)

display_name class-attribute instance-attribute

display_name = mapped_column_with_privacy(
    Text,
    nullable=True,
    privacy_properties=PrivacyProperties(
        some_name,
        NoneOrRedactedHashed(),
        NoneOrEncrypted(),
        FakeFullname(),
        PassThrough(),
        NoneOrPrefixRedactedHashed(),
    ),
)

Display name is usually a simple combination of the first and last names, but can be shorter or abbreviated to fit on a card or any related document.

If too long, it will be truncated with no attempt at making it more readable. If that causes issues, the short name should be used instead. But in many cases truncation will be good enough, like for shipping labels.

Display name is optional because it will be derived from first and last names by default. However providing it here gives the flexibility to override the default for a better rendering in specific contexts.

external_id class-attribute instance-attribute

external_id = mapped_column(
    String(255), nullable=True, index=True
)

ID used by the external payment service provider to identify the account holder. Optional as this concept does not exist for all providers.

first_name class-attribute instance-attribute

first_name = mapped_column_with_privacy(
    Text,
    nullable=False,
    privacy_properties=PrivacyProperties(
        first_name,
        NoneOrRedactedHashed(),
        NoneOrEncrypted(),
        FakeFirstName(),
        PassThrough(),
        NoneOrPrefixRedactedHashed(),
    ),
)

is_terminated property

is_terminated

last_name class-attribute instance-attribute

last_name = mapped_column_with_privacy(
    Text,
    nullable=False,
    privacy_properties=PrivacyProperties(
        last_name,
        NoneOrRedactedHashed(),
        NoneOrEncrypted(),
        FakeLastName(),
        PassThrough(),
        NoneOrPrefixRedactedHashed(),
    ),
)

provider class-attribute instance-attribute

provider = mapped_column(
    AlanBaseEnumTypeDecorator(PaymentServiceProvider),
    nullable=False,
)

The payment service provider the card holder is declared to.

short_name class-attribute instance-attribute

short_name = mapped_column_with_privacy(
    String(18),
    nullable=True,
    privacy_properties=PrivacyProperties(
        some_name,
        NoneOrRedactedHashed(),
        NoneOrEncrypted(),
        FakeFullname(),
        PassThrough(),
        NoneOrPrefixRedactedHashed(),
    ),
)

Short name is a shorter version of the display name to meet specific constraints, like fitting on a card in vertical format. In these cases, the name must still be both readable and recognizable.

Like the display name, the short name is optional because it can be derived from the first and last names, however its very short length makes automatic generation less reliablem so it is better to provide it explicitly.

terminated_at class-attribute instance-attribute

terminated_at = mapped_column(DateTime, nullable=True)

Termination is done at the initiative of the business layer. Card holders in terminal state cannot be modified or used anymore.

validate_provider class-attribute instance-attribute

validate_provider = create_validator('provider')

components.payment_gateway.subcomponents.cards.models.card_order

CardOrder

Bases: BaseModel

__table_args__ class-attribute instance-attribute

__table_args__ = {'schema': PAYMENT_GATEWAY_SCHEMA_NAME}

__tablename__ class-attribute instance-attribute

__tablename__ = 'card_order'

card class-attribute instance-attribute

card = relationship(Card, foreign_keys=card_id)

card_id class-attribute instance-attribute

card_id = mapped_column(
    UUID(as_uuid=True),
    ForeignKey(id),
    index=True,
    nullable=False,
)

delivery_status class-attribute instance-attribute

delivery_status = mapped_column(
    AlanBaseEnumTypeDecorator(CardDeliveryStatus),
    nullable=False,
)

shipping_method class-attribute instance-attribute

shipping_method = mapped_column(String(255), nullable=False)

tracking_number class-attribute instance-attribute

tracking_number = mapped_column(String(255), nullable=True)

components.payment_gateway.subcomponents.cards.models.card_provisioning

CardProvisioning

Bases: BaseModel

__table_args__ class-attribute instance-attribute

__table_args__ = (
    UniqueConstraint(
        "provider",
        "external_id",
        name="card_provisioning__unique_external_id_per_provider",
    ),
    {"schema": PAYMENT_GATEWAY_SCHEMA_NAME},
)

__tablename__ class-attribute instance-attribute

__tablename__ = 'card_provisioning'

card class-attribute instance-attribute

card = relationship(
    Card,
    foreign_keys=[card_id],
    back_populates="all_card_provisioning",
)

card_id class-attribute instance-attribute

card_id = mapped_column(
    UUID(as_uuid=True),
    ForeignKey(id),
    index=True,
    nullable=True,
)

external_id class-attribute instance-attribute

external_id = mapped_column(
    String(255), nullable=False, index=True
)

provider class-attribute instance-attribute

provider = mapped_column(
    AlanBaseEnumTypeDecorator(PaymentServiceProvider),
    nullable=False,
)

provisioning_date class-attribute instance-attribute

provisioning_date = mapped_column(DateTime, nullable=False)

provisioning_type class-attribute instance-attribute

provisioning_type = mapped_column(
    AlanBaseEnumTypeDecorator(ProvisioningType),
    nullable=False,
)

validate_provider class-attribute instance-attribute

validate_provider = create_validator('provider')

wallet_provider class-attribute instance-attribute

wallet_provider = mapped_column(String, nullable=False)

components.payment_gateway.subcomponents.cards.models.helpers

load_all_models

load_all_models()
Source code in components/payment_gateway/subcomponents/cards/models/helpers.py
def load_all_models() -> list[type[DbModel]]:
    from components.payment_gateway.subcomponents.cards.models.card import (
        Card,
        CardStatusLog,
    )
    from components.payment_gateway.subcomponents.cards.models.card_holder import (
        CardHolder,
    )
    from components.payment_gateway.subcomponents.cards.models.card_order import (
        CardOrder,
    )
    from components.payment_gateway.subcomponents.cards.models.card_provisioning import (
        CardProvisioning,
    )

    return [CardHolder, Card, CardStatusLog, CardOrder, CardProvisioning]