Payment Card Numbers

Warning

To use this type, you need to install the optional pydantic-extra-types package:

pip install pydantic-extra-types

The PaymentCardNumber type validates payment cards (such as a debit or credit card).

from datetime import date

from pydantic import BaseModel, constr

from pydantic_extra_types.payment import PaymentCardBrand, PaymentCardNumber


class Card(BaseModel):
    name: constr(strip_whitespace=True, min_length=1)
    number: PaymentCardNumber
    exp: date

    @property
    def brand(self) -> PaymentCardBrand:
        return self.number.brand

    @property
    def expired(self) -> bool:
        return self.exp < date.today()


card = Card(
    name='Georg Wilhelm Friedrich Hegel',
    number='4000000000000002',
    exp=date(2023, 9, 30),
)

assert card.number.brand == PaymentCardBrand.visa
assert card.number.bin == '400000'
assert card.number.last4 == '0002'
assert card.number.masked == '400000******0002'

PaymentCardBrand can be one of the following based on the BIN:

  • PaymentCardBrand.amex
  • PaymentCardBrand.mastercard
  • PaymentCardBrand.visa
  • PaymentCardBrand.other

The actual validation verifies the card number is:

  • a str of only digits
  • luhn valid
  • the correct length based on the BIN, if Amex, Mastercard or Visa, and between 12 and 19 digits for all other brands