Skip to content

Commit 1497279

Browse files
committed
style: fix code style
1 parent 3a0433f commit 1497279

File tree

1 file changed

+72
-50
lines changed

1 file changed

+72
-50
lines changed

pydantic_extra_types/payment.py

Lines changed: 72 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,77 @@ def validate_luhn_check_digit(cls, card_number: str) -> str:
127127
raise PydanticCustomError('payment_card_number_luhn', 'Card number is not luhn valid')
128128
return card_number
129129

130+
@classmethod
131+
def _identify_brand(cls, card_number: str) -> tuple[PaymentCardBrand, list[int]]:
132+
"""Identify the brand and required length for a card number.
133+
134+
Args:
135+
card_number: The card number to identify.
136+
137+
Returns:
138+
A tuple of (brand, required_length)
139+
"""
140+
# VISA
141+
if card_number[0] == '4':
142+
return PaymentCardBrand.visa, [13, 16, 19]
143+
144+
# Mastercard
145+
if (51 <= int(card_number[:2]) <= 55) or (2221 <= int(card_number[:4]) <= 2720):
146+
return PaymentCardBrand.mastercard, [16]
147+
148+
# American Express
149+
if card_number[:2] in {'34', '37'}:
150+
return PaymentCardBrand.amex, [15]
151+
152+
# MIR
153+
if 2200 <= int(card_number[:4]) <= 2204:
154+
return PaymentCardBrand.mir, list(range(16, 20))
155+
156+
# Maestro
157+
if card_number[:4] in {'5018', '5020', '5038', '5893', '6304', '6759', '6761', '6762', '6763'} or card_number[
158+
:6
159+
] in ('676770', '676774'):
160+
return PaymentCardBrand.maestro, list(range(12, 20))
161+
162+
# Discover
163+
if card_number.startswith('65') or 644 <= int(card_number[:3]) <= 649 or card_number.startswith('6011'):
164+
return PaymentCardBrand.discover, list(range(16, 20))
165+
166+
# Verve
167+
if (
168+
506099 <= int(card_number[:6]) <= 506198
169+
or 650002 <= int(card_number[:6]) <= 650027
170+
or 507865 <= int(card_number[:6]) <= 507964
171+
):
172+
return PaymentCardBrand.verve, [16, 18, 19]
173+
174+
# Dankort
175+
if card_number[:4] in {'5019', '4571'}:
176+
return PaymentCardBrand.dankort, [16]
177+
178+
# Troy
179+
if card_number.startswith('9792'):
180+
return PaymentCardBrand.troy, [16]
181+
182+
# UnionPay
183+
if card_number[:2] in {'62', '81'}:
184+
return PaymentCardBrand.unionpay, [16, 19]
185+
186+
# JCB
187+
if 3528 <= int(card_number[:4]) <= 3589:
188+
return PaymentCardBrand.jcb, [16, 19]
189+
190+
# Diners Club
191+
if card_number[:2] in {'30', '36', '38', '39'}:
192+
return PaymentCardBrand.diners_club, list(range(14, 20))
193+
194+
# More Diners Club
195+
if card_number.startswith('55'):
196+
return PaymentCardBrand.diners_club, [16]
197+
198+
# Other / Unknown
199+
return PaymentCardBrand.other, []
200+
130201
@staticmethod
131202
def validate_brand(card_number: str) -> PaymentCardBrand:
132203
"""Validate length based on
@@ -142,56 +213,7 @@ def validate_brand(card_number: str) -> PaymentCardBrand:
142213
Raises:
143214
PydanticCustomError: If the card number is not valid.
144215
"""
145-
brand = PaymentCardBrand.other
146-
147-
if card_number[0] == '4':
148-
brand = PaymentCardBrand.visa
149-
required_length = [13, 16, 19]
150-
elif (51 <= int(card_number[:2]) <= 55) or (2221 <= int(card_number[:4]) <= 2720):
151-
brand = PaymentCardBrand.mastercard
152-
required_length = [16]
153-
elif card_number[:2] in {'34', '37'}:
154-
brand = PaymentCardBrand.amex
155-
required_length = [15]
156-
elif 2200 <= int(card_number[:4]) <= 2204:
157-
brand = PaymentCardBrand.mir
158-
required_length = list(range(16, 20))
159-
elif card_number[:4] in {'5018', '5020', '5038', '5893', '6304', '6759', '6761', '6762', '6763'} or card_number[
160-
:6
161-
] in (
162-
'676770',
163-
'676774',
164-
):
165-
brand = PaymentCardBrand.maestro
166-
required_length = list(range(12, 20))
167-
elif card_number.startswith('65') or 644 <= int(card_number[:3]) <= 649 or card_number.startswith('6011'):
168-
brand = PaymentCardBrand.discover
169-
required_length = list(range(16, 20))
170-
elif (
171-
506099 <= int(card_number[:6]) <= 506198
172-
or 650002 <= int(card_number[:6]) <= 650027
173-
or 507865 <= int(card_number[:6]) <= 507964
174-
):
175-
brand = PaymentCardBrand.verve
176-
required_length = [16, 18, 19]
177-
elif card_number[:4] in {'5019', '4571'}:
178-
brand = PaymentCardBrand.dankort
179-
required_length = [16]
180-
elif card_number.startswith('9792'):
181-
brand = PaymentCardBrand.troy
182-
required_length = [16]
183-
elif card_number[:2] in {'62', '81'}:
184-
brand = PaymentCardBrand.unionpay
185-
required_length = [16, 19]
186-
elif 3528 <= int(card_number[:4]) <= 3589:
187-
brand = PaymentCardBrand.jcb
188-
required_length = [16, 19]
189-
elif card_number[:2] in {'30', '36', '38', '39'}:
190-
brand = PaymentCardBrand.diners_club
191-
required_length = list(range(14, 20))
192-
elif card_number.startswith('55'):
193-
brand = PaymentCardBrand.diners_club
194-
required_length = [16]
216+
brand, required_length = PaymentCardNumber._identify_brand(card_number)
195217

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

0 commit comments

Comments
 (0)