checkIsValid method

void checkIsValid()

Validates each field of the CardDetails object in entry order, namely _cardNumber -> expirationString -> securityCode -> postalCode

If all fields are filled out and valid, CardDetails.isComplete == true and CardDetails.validState == ValidState.ok.

Implementation

void checkIsValid() {
  try {
    int currentHash = hash;
    if (currentHash == _lastCheckHash) {
      return;
    }

    _complete = false;
    _lastCheckHash = currentHash;
    if (_cardNumber == null &&
        expirationString == null &&
        securityCode == null &&
        postalCode == null) {
      _validState = CardDetailsValidState.blank;
      return;
    }
    final nums = _cardNumber!
        .replaceAll(' ', '')
        .split('')
        .map(
          (i) => int.parse(i),
        )
        .toList();
    if (!_luhnAlgorithmCheck(nums)) {
      _validState = CardDetailsValidState.invalidCard;
      return;
    }
    if (_cardNumber == null || !cardNumberFilled) {
      _validState = CardDetailsValidState.missingCard;
      return;
    }
    if (expirationString == null) {
      _validState = CardDetailsValidState.missingDate;
      return;
    }
    final expSplits = expirationString!.split('/');
    if (expSplits.length != 2 || expSplits.last == '') {
      _validState = CardDetailsValidState.missingDate;
      return;
    }
    final month = int.parse(
        expSplits.first[0] == '0' ? expSplits.first[1] : expSplits.first);
    if (month < 1 || month > 12) {
      _validState = CardDetailsValidState.invalidMonth;
      return;
    }
    final year = 2000 + int.parse(expSplits.last);
    final date = DateTime(year, month);
    if (date.isBefore(DateTime.now())) {
      _validState = CardDetailsValidState.dateTooEarly;
      return;
    } else if (date
        .isAfter(DateTime.now().add(const Duration(days: 365 * 50)))) {
      _validState = CardDetailsValidState.dateTooLate;
      return;
    }
    expirationDate = date;
    if (securityCode == null) {
      _validState = CardDetailsValidState.missingCVC;
      return;
    }
    if (provider != null && securityCode!.length != provider!.cvcLength) {
      _validState = CardDetailsValidState.invalidCVC;
      return;
    }
    if (postalCode == null) {
      _validState = CardDetailsValidState.missingZip;
      return;
    }
    if (!RegExp(r'^\d{5}(-\d{4})?$').hasMatch(postalCode!)) {
      _validState = CardDetailsValidState.invalidZip;
      return;
    }
    _complete = true;
    _validState = CardDetailsValidState.ok;
  } catch (err, st) {
    if (kDebugMode) {
      print('Error while validating CardDetails: $err\n$st');
    }
    _complete = false;
    _validState = CardDetailsValidState.error;
  }
}