Creditcard regex is not working in flutter
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".
It doesn't recognize incomplete credit card numbers, so it will always return the last else part.
Admin
Updated on January 04, 2023Comments
-
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 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 over 1 yearDo 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 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 over 1 yearThanks, now I realise what is the issue, any idea how we can achive live validation here instead of writing full number