Home > Net >  Creditcard regex is not working in flutter
Creditcard regex is not working in flutter

Time:05-25

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);
  }
}

CodePudding user response:

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

CodePudding user response:

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);
  }
}
  • Related