Source code for terminusgps.authorizenet.validators
import calendar
import datetime
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
[docs]
def validate_credit_card_number(value: str) -> None:
"""
Raises :py:exc:`~django.core.exceptions.ValidationError` if the value is an invalid credit card number.
Uses the `Luhn algorithm <https://en.wikipedia.org/wiki/Luhn_algorithm>`_ to validate the credit card number.
:param value: A credit card number string.
:type value: :py:obj:`str`
:raises ValidationError: If the value contains non-digit characters.
:raises ValidationError: If the value fails the Luhn algorithm.
:returns: Nothing.
:rtype: :py:obj:`None`
"""
if not value.isdigit():
raise ValidationError(
_("Credit card number can only contain digits. Got '%(value)s'."),
code="invalid",
params={"value": value},
)
card_number = [int(num) for num in reversed(value)]
even_digits = card_number[1::2]
odd_digits = card_number[0::2]
checksum = 0
checksum += sum(
[digit * 2 if digit * 2 <= 9 else (digit * 2) % 9 or 9 for digit in even_digits]
)
checksum += sum([digit for digit in odd_digits])
if checksum % 10 != 0:
raise ValidationError(_("Invalid credit card number."), code="invalid")
[docs]
def validate_credit_card_expiry_month(value: str) -> None:
"""
Raises :py:exc:`~django.core.exceptions.ValidationError` if the value is an invalid credit card expiration date month.
:param value: A credit card expiration year string.
:type value: :py:obj:`str`
:raises ValidationError: If the value contains non-digit characters.
:raises ValidationError: If the value is negative.
:raises ValidationError: If the value isn't between 1-12.
:returns: Nothing.
:rtype: :py:obj:`None`
"""
if not value.isdigit():
raise ValidationError(
_("Expiration month can only contain digits, got '%(value)s'."),
code="invalid",
params={"value": value},
)
if not int(value) > 0:
raise ValidationError(
_("Expiration month can only be a positive value, got '%(value)s'."),
code="invalid",
params={"value": value},
)
try:
calendar.Month(int(value))
except ValueError:
raise ValidationError(
_("Expiration month must be between 1-12, got '%(value)s'."),
code="invalid",
params={"value": value},
)
[docs]
def validate_credit_card_expiry_year(value: str) -> None:
"""
Raises :py:exc:`~django.core.exceptions.ValidationError` if the value is an invalid credit card expiration date year.
:param value: A credit card expiration year string.
:type value: :py:obj:`str`
:raises ValidationError: If the value contains non-digit characters.
:raises ValidationError: If the value is negative.
:raises ValidationError: If the value is a year in the past.
:returns: Nothing.
:rtype: :py:obj:`None`
"""
if not value.isdigit():
raise ValidationError(
_("Expiration year can only contain digits, got '%(value)s'."),
code="invalid",
params={"value": value},
)
if not int(value) > 0:
raise ValidationError(
_("Expiration year can only be a positive value, got '%(value)s'."),
code="invalid",
params={"value": value},
)
input_year = datetime.datetime.strptime(value, "%y").year
this_year = datetime.datetime.now().year
if not input_year >= this_year:
raise ValidationError(
_("Expiration year cannot be in the past, got '%(value)s'."),
code="invalid",
params={"value": value},
)