Unofficial research mirror of the Pydantic documentation (MIT licence) for an academic study. Some details differ from the official documentation, so do not rely on this site for real projects. Official docs: docs.pydantic.dev. About this study.
Skip to content

Payment

The pydantic_extra_types.payment module provides the PaymentCardNumber data type.

PaymentCardBrand

Bases: str, Enum

Payment card brands supported by the PaymentCardNumber.

PaymentCardNumber

PaymentCardNumber(card_number: str)

Bases: str

A payment card number.

Source code in .venv/lib/python3.12/site-packages/pydantic_extra_types/payment.py
51
52
53
54
55
56
57
58
def __init__(self, card_number: str):
    self.validate_digits(card_number)

    card_number = self.validate_luhn_check_digit(card_number)

    self.bin = card_number[:6]
    self.last4 = card_number[-4:]
    self.brand = self.validate_brand(card_number)

strip_whitespace class-attribute

strip_whitespace: bool = True

Whether to strip whitespace from the input value.

min_length class-attribute

min_length: int = 12

The minimum length of the card number.

max_length class-attribute

max_length: int = 19

The maximum length of the card number.

bin instance-attribute

bin: str = card_number[:6]

The first 6 digits of the card number.

last4 instance-attribute

last4: str = card_number[-4:]

The last 4 digits of the card number.

brand instance-attribute

brand: PaymentCardBrand = validate_brand(card_number)

The brand of the card.

masked property

masked: str

The masked card number.

validate classmethod

validate(
    __input_value: str, _: ValidationInfo
) -> PaymentCardNumber

Validate the PaymentCardNumber instance.

Parameters:

Name Type Description Default
__input_value str

The input value to validate.

required
_ ValidationInfo

The validation info.

required

Returns:

Type Description
PaymentCardNumber

The validated PaymentCardNumber instance.

Source code in .venv/lib/python3.12/site-packages/pydantic_extra_types/payment.py
69
70
71
72
73
74
75
76
77
78
79
80
@classmethod
def validate(cls, __input_value: str, _: core_schema.ValidationInfo) -> PaymentCardNumber:
    """Validate the `PaymentCardNumber` instance.

    Args:
        __input_value: The input value to validate.
        _: The validation info.

    Returns:
        The validated `PaymentCardNumber` instance.
    """
    return cls(__input_value)

validate_digits classmethod

validate_digits(card_number: str) -> None

Validate that the card number is all digits.

Parameters:

Name Type Description Default
card_number str

The card number to validate.

required

Raises:

Type Description
PydanticCustomError

If the card number is not all digits.

Source code in .venv/lib/python3.12/site-packages/pydantic_extra_types/payment.py
88
89
90
91
92
93
94
95
96
97
98
99
@classmethod
def validate_digits(cls, card_number: str) -> None:
    """Validate that the card number is all digits.

    Args:
        card_number: The card number to validate.

    Raises:
        PydanticCustomError: If the card number is not all digits.
    """
    if not card_number or not all('0' <= c <= '9' for c in card_number):
        raise PydanticCustomError('payment_card_number_digits', 'Card number is not all digits')

validate_luhn_check_digit classmethod

validate_luhn_check_digit(card_number: str) -> str

Validate the payment card number. Based on the Luhn algorithm.

Parameters:

Name Type Description Default
card_number str

The card number to validate.

required

Returns:

Type Description
str

The validated card number.

Raises:

Type Description
PydanticCustomError

If the card number is not valid.

Source code in .venv/lib/python3.12/site-packages/pydantic_extra_types/payment.py
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
@classmethod
def validate_luhn_check_digit(cls, card_number: str) -> str:
    """Validate the payment card number.
    Based on the [Luhn algorithm](https://en.wikipedia.org/wiki/Luhn_algorithm).

    Args:
        card_number: The card number to validate.

    Returns:
        The validated card number.

    Raises:
        PydanticCustomError: If the card number is not valid.
    """
    sum_ = int(card_number[-1])
    length = len(card_number)
    parity = length % 2
    for i in range(length - 1):
        digit = int(card_number[i])
        if i % 2 == parity:
            digit *= 2
        if digit > 9:
            digit -= 9
        sum_ += digit
    valid = sum_ % 10 == 0
    if not valid:
        raise PydanticCustomError('payment_card_number_luhn', 'Card number is not luhn valid')
    return card_number

validate_brand staticmethod

validate_brand(card_number: str) -> PaymentCardBrand

Validate length based on BIN for major brands.

Parameters:

Name Type Description Default
card_number str

The card number to validate.

required

Returns:

Type Description
PaymentCardBrand

The validated card brand.

Raises:

Type Description
PydanticCustomError

If the card number is not valid.

Source code in .venv/lib/python3.12/site-packages/pydantic_extra_types/payment.py
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
@staticmethod
def validate_brand(card_number: str) -> PaymentCardBrand:
    """Validate length based on
    [BIN](https://en.wikipedia.org/wiki/Payment_card_number#Issuer_identification_number_(IIN))
    for major brands.

    Args:
        card_number: The card number to validate.

    Returns:
        The validated card brand.

    Raises:
        PydanticCustomError: If the card number is not valid.
    """
    brand, required_length = PaymentCardNumber._identify_brand(card_number)

    valid = len(card_number) in required_length if brand != PaymentCardBrand.other else True

    if not valid:
        raise PydanticCustomError(
            'payment_card_number_brand',
            f'Length for a {brand} card must be {" or ".join(map(str, required_length))}',
            {'brand': brand, 'required_length': required_length},
        )

    return brand