Creditcard regex is not working in flutter

186

Solution 1

For live validation, you need to make sure that each subsequent digit can only be entered if the current substring is valid.

You can use

^5(?:[1-5][0-9]{0,14})?$                   # VISA
^5(?:[1-5][0-9]{0,14})?$                   # MASTER CARD
^3(?:[47][0-9]{0,13})?$                    # AEXPRESS CARD
^3(?:(?:0[0-5]?|[68][0-9]?)[0-9]{0,11})?$  # DINER CARD
^6(?:(?:01{0,2}|5[0-9]{0,2})[0-9]{0,12})?$ # DISCOVER CARD

The updated code will look like:

Widget getCreditCardType(String creditCardNumber) {
  if (RegExp(r"^4[0-9]{0,15}$").hasMatch(creditCardNumber)) {
    // visa card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/visa.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else if (RegExp(r"^5(?:[1-5][0-9]{0,14})?$").hasMatch(creditCardNumber)) {
    // master card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/master.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else if (RegExp(r"^3(?:[47][0-9]{0,13})?$").hasMatch(creditCardNumber)) {
    // AExpress card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/american-express.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else if (RegExp(r"^3(?:(?:0[0-5]?|[68][0-9]?)[0-9]{0,11})?$")
      .hasMatch(creditCardNumber)) {
    // diner card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/dinners-club.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else if (RegExp(r"^6(?:(?:01{0,2}|5[0-9]{0,2})[0-9]{0,12})?$")
      .hasMatch(creditCardNumber)) {
    // discover card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/discover.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else if (RegExp(r"^(?:2(?:1(?:31?)?)?|1(?:80{0,2})?|3(?:5\d{0,3})?)\d{0,11}$")
      .hasMatch(creditCardNumber)) {
    // JCB card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/jcb.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else {
    return const Icon(Icons.credit_card);
  }
}

Solution 2

I've tried the function you wrote down, and it appears that the regex pattern only recognize the full/complete format of the credit card. So it is a "validation regex" instead of "classification regex".

Complete Visa number recognized Complete AE number recognized

It doesn't recognize incomplete credit card numbers, so it will always return the last else part.

Incomplete Visa number not recognized

Share:
186
Admin
Author by

Admin

Updated on January 04, 2023

Comments

  • Admin
    Admin 10 months

    I am trying to determine which credit card is it? and render Image Widget accordingly. but somehow its not working, I don't know If I miss something or is my approach is wrong

    Here's the code snippet

    Its always render the last else part.

    Input image

    Input Suffix Icon part where I am rendering container based on number

    VxState.watch(context, on: [HandleInputChanges]);
    TextField(
         maxLength: 16,
         decoration: InputDecoration(
              counter: const Offstage(),
              suffixIcon: getCreditCardType(store.moniPay.cardNo) // Here I am rendering image,
         hintText: "Input card number",
         onChanged: (String? value) {
              HandleInputChanges(value.toString(), 'cardno');
          })
    

    And here's the getCreditCardType method

    Widget getCreditCardType(String creditCardNumber) {
      if (RegExp(r"^4[0-9]{12}(?:[0-9]{3})?$").hasMatch(creditCardNumber)) {
        // visa card
        return Container(
            decoration: const BoxDecoration(
          image: DecorationImage(
            image: AssetImage("assets/images/visa.png"),
            fit: BoxFit.contain,
          ),
        ));
      } else if (RegExp(r"^5[1-5][0-9]{14}$").hasMatch(creditCardNumber)) {
        // master card
        return Container(
            decoration: const BoxDecoration(
          image: DecorationImage(
            image: AssetImage("assets/images/master.png"),
            fit: BoxFit.contain,
          ),
        ));
      } else if (RegExp(r"^3[47][0-9]{13}$").hasMatch(creditCardNumber)) {
        // AExpress card
        return Container(
            decoration: const BoxDecoration(
          image: DecorationImage(
            image: AssetImage("assets/images/american-express.png"),
            fit: BoxFit.contain,
          ),
        ));
      } else if (RegExp(r"^3(?:0[0-5]|[68][0-9])[0-9]{11}$")
          .hasMatch(creditCardNumber)) {
        // diner card
        return Container(
            decoration: const BoxDecoration(
          image: DecorationImage(
            image: AssetImage("assets/images/dinners-club.png"),
            fit: BoxFit.contain,
          ),
        ));
      } else if (RegExp(r"^6(?:011|5[0-9]{2})[0-9]{12}$")
          .hasMatch(creditCardNumber)) {
        // discover card
        return Container(
            decoration: const BoxDecoration(
          image: DecorationImage(
            image: AssetImage("assets/images/discover.png"),
            fit: BoxFit.contain,
          ),
        ));
      } else if (RegExp(r"^(?:2131|1800|35\\d{3})\\d{11}$")
          .hasMatch(creditCardNumber)) {
        // JCB card
        return Container(
            decoration: const BoxDecoration(
          image: DecorationImage(
            image: AssetImage("assets/images/jcb.png"),
            fit: BoxFit.contain,
          ),
        ));
      } else {
        return const Icon(Icons.credit_card);
      }
    }
    
    • Wiktor Stribiżew
      Wiktor Stribiżew over 1 year
      Do you need "live input validation"? Try replacing the first regex (RegExp(r"^4[0-9]{12}(?:[0-9]{3})?$")) with ^4[0-9]{0,15}$.
    • Sagar Chavada
      Sagar Chavada over 1 year
      @WiktorStribiżew yes, I need live input validation, and thank you that work for visa card, any idea about master card and JCB card.
  • Sagar Chavada
    Sagar Chavada over 1 year
    Thanks, now I realise what is the issue, any idea how we can achive live validation here instead of writing full number