Menu

Valider un numéro de carte bancaire : les contrôles qui comptent

Comment valider correctement un numéro de carte bancaire : l'ordre des contrôles, les messages dont les utilisateurs ont besoin, pourquoi le navigateur ne suffit pas et les pièges qui passent la revue.

Publié le

  • données de test
  • paiements
  • validation

La validation échoue rarement parce que l’arithmétique est difficile. Lorsque vous validez un numéro de carte bancaire dans une vraie application, les échecs viennent du fait d’exécuter les contrôles dans le mauvais ordre, de faire confiance au navigateur, et de signaler chaque type de problème avec le même message peu utile. Les règles elles-mêmes s’expriment en quelques lignes ; la discipline réside dans leur enchaînement et dans la décision de ce que chaque défaillance signifie.

Cet article couvre ce à quoi sert la validation, l’ordre qui évite les résultats absurdes, la frontière entre vérifier une valeur et autoriser un paiement, et les tests qui attrapent de vrais défauts plutôt que de confirmer ce que vous croyez déjà.

À quoi sert réellement la validation

Le but de valider un numéro de carte est de rejeter une entrée qui ne peut pas fonctionner, et de le faire avant que quoi que ce soit de coûteux ne se produise. Cela évite à l’utilisateur de soumettre un formulaire qui échouera, cela garde les valeurs mal formées hors de vos propres enregistrements, et cela réduit le trafic inutile vers une passerelle de paiement.

Il vaut la peine d’être explicite sur ce à quoi elle ne sert pas. Ce n’est pas un contrôle de fraude, ce n’est pas une preuve de propriété, et ce n’est pas un substitut à l’autorisation. Un numéro qui passe toutes les règles que vous pouvez appliquer localement peut malgré tout être refusé par l’émetteur, et un numéro que vous rejetez peut appartenir à un vrai client si vos règles sont fausses. Ce dernier point est celui qui coûte de l’argent, car rejeter une carte valide est invisible pour vous et exaspérant pour le client.

Quels contrôles doivent s’exécuter en premier ?

L’ordre détermine si vos erreurs ont un sens. La séquence qui se comporte bien commence large et se resserre :

  1. La présence. Un champ vide n’est pas un numéro mal formé, et le dire ainsi évite un message déroutant.
  2. Le jeu de caractères. Décidez quels séparateurs vous tolérez, retirez-les, et refusez tout le reste. Faites-le avant la longueur, afin qu’un numéro collé avec des espaces ne soit pas jugé sur son nombre brut de caractères.
  3. La longueur. Comparez à l’intervalle du réseau détecté plutôt qu’à une valeur universelle unique ; les longueurs valides varient entre réseaux et produits.
  4. Le préfixe. Une fois la longueur plausible, vérifiez que les premiers chiffres appartiennent à un réseau que vous avez réellement l’intention de prendre en charge.
  5. La somme de contrôle. Calculez le contrôle modulo dix décrit dans le guide de l’algorithme de Luhn et comparez-le au dernier chiffre.

Exécuter la somme de contrôle en premier produit le pire comportement, car la procédure de somme de contrôle renverra volontiers un résultat pour un fragment de trois chiffres ou une chaîne contenant des lettres, et l’utilisateur reçoit alors un message au sujet d’un contrôle échoué sur lequel il ne peut rien faire.

La validation côté client suffit-elle ?

Non, et la raison n’est pas seulement que JavaScript peut être désactivé. Un contrôle côté navigateur est une courtoisie envers la personne qui saisit : il donne un retour immédiat et évite un aller-retour. Ce n’est pas un contrôle de sécurité, car tout ce qui s’exécute dans le navigateur est sous le contrôle de l’utilisateur, et parce que le code client n’est pas le seul moyen pour des valeurs d’atteindre votre système.

Le serveur doit répéter la même séquence, indépendamment. Si les deux ne sont pas d’accord — l’un acceptant ce que l’autre rejette — alors vous avez trouvé soit un bug, soit une règle non documentée, et cela ressortira tôt ou tard sous la forme d’un ticket d’assistance au sujet d’une carte qui fonctionne sur une page et pas sur une autre.

Il existe aussi une troisième couche : le prestataire de paiement effectue ses propres contrôles et rejettera des valeurs que votre code a acceptées. C’est normal, et c’est la raison pour laquelle votre flux doit gérer une erreur de passerelle avec élégance plutôt que de supposer qu’un numéro localement valide sera traité.

Que doit dire un message d’erreur ?

Des problèmes différents appellent des réponses différentes, et un champ qui dit seulement que le numéro de carte est invalide laisse l’utilisateur deviner.

Un ensemble utile couvre les situations réalistes. Un champ vide est une invite, pas une erreur. Trop court ou trop long est un décompte, formulé en fonction de la saisie propre à l’utilisateur. Un caractère non pris en charge devrait indiquer quels caractères sont acceptés, car l’utilisateur ne distingue souvent pas une lettre parasite d’un séparateur que vous tolérez. Une longueur qui ne correspond à aucun réseau pris en charge est généralement le signe que le mauvais réseau a été détecté, et non que l’utilisateur a inventé une carte. Une somme de contrôle échouée est le seul cas où le message honnête est que le numéro semble mal saisi, ce qui suggère un seul chiffre erroné sans affirmer que la carte est mauvaise.

Remarquez qu’aucun de ces messages ne doit prétendre que la carte est fausse. Le formulaire ne le sait pas, et dire à un vrai client que sa carte n’est pas réelle est une expérience d’assistance mémorable.

Un contrôle réussi n’est pas un paiement approuvé

C’est la distinction qui garde les équipes honnêtes. Tout ce qui est décrit ci-dessus est une affirmation sur la forme d’une chaîne. L’approbation ne vient que d’une demande d’autorisation auprès de l’émetteur, et elle dépend du compte, du solde, des règles de risque propres à l’émetteur et de toute authentification qu’on demande au client d’accomplir.

Ainsi, lorsqu’un environnement de test produit une carte qui satisfait chaque contrôle local, la description exacte est que la valeur est structurellement valide et jamais émise. Elle passera votre validation et sera refusée par n’importe quelle vraie passerelle, ce qui est précisément ce qui la rend sûre pour tester la validation elle-même.

La même logique vaut dans l’autre sens. Un numéro qui échoue à votre test de somme de contrôle est une entrée mal formée ; un numéro qui passe et qui est quand même refusé est un résultat métier. Fusionner les deux dans un même chemin d’erreur rend les deux plus difficiles à déboguer.

Pour les développeurs : ordre, normalisation et les tests qui comptent

Trois habitudes font tenir ce code dans la durée.

Placez la séquence en un seul endroit. Longueur, caractères, préfixe et somme de contrôle devraient vivre dans une routine unique à l’ordre défini, appelée depuis le client comme depuis le serveur. La logique dupliquée est l’endroit où les deux couches divergent silencieusement.

Normalisez une fois, et gardez l’original. Retirez les séparateurs, conservez les chiffres sous forme de chaîne, et ne laissez jamais un type numérique toucher la valeur. Stockez la forme nettoyée pour la comparaison et, si vous en avez besoin pour l’affichage, la forme groupée aussi — mais dérivez l’une de l’autre plutôt que de stocker deux copies indépendantes qui peuvent diverger.

Testez ensuite les échecs, pas le succès. Les cas qui trouvent de vrais bugs sont un numéro valide avec un chiffre modifié, un numéro contenant une lettre, un numéro avec un zéro initial, une soumission vide, une valeur de longueur maximale, et un collage contenant des séparateurs. Pour chacun, vérifiez le message précis que reçoit votre utilisateur, et pas seulement que la validation a échoué.

Il vaut aussi la peine d’auditer par où la valeur peut voyager. Les utilitaires de validation ont tendance à être réutilisés, et une routine écrite pour un formulaire est parfois appelée avec des valeurs arrivées d’une file ou d’un import. Ces appelants ont besoin que les mêmes règles s’appliquent, et ils ont rarement un utilisateur à qui montrer un message — ce qui signifie que l’erreur doit être consignée quelque part où un humain la lira.

Enfin, surveillez ce que le champ fait des données après leur acceptation. Les règles de masquage, de stockage et de journalisation sont régies par la norme de l’industrie des cartes plutôt que par vos propres préférences, et les notes de conformité résument les parties qui touchent un environnement de test. Le guide du format détaille les règles de longueur et de préfixe mentionnées ci-dessus.

S’exercer sur des numéros générés

Le moyen le plus rapide de vérifier un validateur est de le pointer vers des données dont vous connaissez le résultat attendu à l’avance. Le générateur de numéros de carte produit des lots de numéros bien formés par construction, donc tout rejet est soit un bug du validateur, soit une règle que vous ne vouliez pas écrire. Générez un ensemble, corrompez délibérément un chiffre dans une copie, et confirmez que les deux sont classés différemment avec deux messages différents.

Étapes suivantes

Écrivez l’ordre des contrôles sous forme de commentaire au-dessus de la routine, assurez-vous que le serveur l’applique indépendamment, et ajoutez une fixture négative pour chaque fixture positive. Si votre formulaire collecte aussi une date ou un code de sécurité, la liste de contrôle du formulaire de paiement recense les flux environnants auxquels ces champs appartiennent.

Continuer la lecture

Articles sur Générateur de numéros de carte bancaire fictifs (cartes de test)