Menu

Creditcardnummer valideren: de controles die ertoe doen

Hoe je een creditcardnummer goed valideert: de volgorde van de controles, de meldingen die gebruikers nodig hebben, waarom de browser niet genoeg is, en de valkuilen die reviews overleven.

Gepubliceerd

  • testdata
  • betalingen
  • validatie

Validatie mislukt zelden omdat de rekenkunde moeilijk is. Wanneer je in een echte applicatie een creditcardnummer valideert, komen de fouten doordat de controles in de verkeerde volgorde worden gedaan, doordat de browser wordt vertrouwd, en doordat elk soort probleem met dezelfde onbehulpzame melding wordt gerapporteerd. De regels zelf zijn in een paar regels uit te drukken; de discipline zit in het op volgorde zetten ervan en in het bepalen wat elke fout betekent.

Dit artikel behandelt waar validatie voor dient, de volgorde die onzinnige resultaten voorkomt, de grens tussen het controleren van een waarde en het autoriseren van een betaling, en de tests die echte defecten vinden in plaats van te bevestigen wat je toch al geloofde.

Waar validatie werkelijk voor dient

Het doel van het valideren van een kaartnummer is het weigeren van invoer die onmogelijk kan werken, en dat te doen voordat er iets duurs gebeurt. Het bespaart de gebruiker het indienen van een formulier dat zal mislukken, het houdt misvormde waarden buiten je eigen administratie, en het vermindert nutteloos verkeer naar een betaalgateway.

Het is de moeite waard expliciet te zijn over waar het niet voor dient. Het is geen fraudcontrole, het is geen bewijs van eigendom, en het is geen vervanging voor autorisatie. Een nummer dat elke regel haalt die je lokaal kunt toepassen, kan nog steeds door de uitgever worden geweigerd, en een nummer dat je afwijst kan bij een echte klant horen als je regels onjuist zijn. Dat laatste punt kost geld, omdat het afwijzen van een geldige kaart onzichtbaar is voor jou en woedend maakt voor de klant.

Welke controles moeten eerst draaien?

De volgorde bepaalt of je fouten zinvol zijn. De reeks die zich goed gedraagt, begint breed en vernauwt:

  1. Aanwezigheid. Een leeg veld is geen misvormd nummer, en dat zeggen voorkomt een verwarrende melding.
  2. Tekenset. Bepaal welke scheidingstekens je tolereert, verwijder ze, en weiger al het andere. Doe dit vóór de lengte, zodat een nummer dat met spaties is geplakt niet op zijn ruwe tekental wordt beoordeeld.
  3. Lengte. Vergelijk met het bereik voor het gedetecteerde netwerk in plaats van met één universele waarde; geldige lengtes verschillen per netwerk en product.
  4. Prefix. Zodra de lengte aannemelijk is, controleer dan of de leidende cijfers bij een netwerk horen dat je daadwerkelijk wilt ondersteunen.
  5. Controlesom. Bereken de modulus-tien-controle die in de gids over het Luhn-algoritme wordt beschreven en vergelijk die met het laatste cijfer.

De controlesom als eerste draaien levert het slechtste gedrag op, omdat de controlesomprocedure met plezier een resultaat teruggeeft voor een fragment van drie cijfers of een reeks met letters, en de gebruiker dan een melding over een mislukte controle krijgt waarop hij niet kan handelen.

Is client-side validatie genoeg?

Nee, en de reden is niet alleen dat JavaScript kan worden uitgeschakeld. Een controle aan de browserkant is een vriendelijkheid voor wie typt: ze geeft directe feedback en bespaart een retourtje. Het is geen beheersmaatregel, omdat alles wat in de browser draait onder controle van de gebruiker staat, en omdat clientcode niet de enige manier is waarop waarden je systeem bereiken.

De server moet dezelfde reeks onafhankelijk herhalen. Als de twee het oneens zijn — de ene accepteert wat de andere weigert — dan heb je ofwel een bug gevonden ofwel een ongedocumenteerde regel, en die zal uiteindelijk opduiken als een supportticket over een kaart die op de ene pagina werkt en op de andere niet.

Er is ook een derde laag: de betaalprovider voert zijn eigen controles uit en zal waarden afwijzen die jouw code accepteerde. Dat is normaal, en het is de reden dat je stroom een gatewayfout sierlijk moet afhandelen in plaats van aan te nemen dat een lokaal geldig nummer wordt verwerkt.

Wat moet een foutmelding zeggen?

Verschillende problemen vragen verschillende antwoorden, en een veld dat alleen zegt dat het kaartnummer ongeldig is, laat de gebruiker gissen.

Een behulpzame set dekt de realistische situaties. Leeg is een aansporing, geen fout. Te kort of te lang is een telling, geformuleerd in termen van wat de gebruiker zelf invoerde. Een niet-ondersteund teken moet zeggen welke tekens wel worden geaccepteerd, omdat de gebruiker het verschil tussen een losse letter en een scheidingsteken dat je tolereert vaak niet kan zien. Een lengte die bij geen enkel ondersteund netwerk past, is meestal een teken dat het verkeerde netwerk is gedetecteerd, niet dat de gebruiker een kaart heeft verzonnen. Een mislukte controlesom is het enige geval waarin de eerlijke melding is dat het nummer verkeerd getypt lijkt, wat op één verkeerd cijfer wijst zonder te beweren dat de kaart slecht is.

Merk op dat geen van deze meldingen mag beweren dat de kaart nep is. Het formulier weet dat niet, en een echte klant vertellen dat zijn kaart niet echt is, is een gedenkwaardige supportervaring.

Een geslaagde controle is geen goedgekeurde betaling

Dit is het onderscheid dat teams eerlijk houdt. Alles wat hierboven is beschreven, is een uitspraak over de vorm van een reeks. Goedkeuring komt alleen van een autorisatieverzoek bij de uitgever, en hangt af van het account, het saldo, de eigen risicoregels van de uitgever en eventuele authenticatie die de klant moet voltooien.

Wanneer een testomgeving dus een kaart produceert die elke lokale controle doorstaat, is de nauwkeurige beschrijving dat de waarde structureel geldig en nooit uitgegeven is. Ze zal je validatie passeren en door elke echte gateway worden geweigerd, wat precies is wat haar veilig maakt voor het testen van de validatie zelf.

Dezelfde logica werkt de andere kant op. Een nummer dat je controlesomtest niet haalt, is misvormde invoer; een nummer dat slaagt en toch wordt geweigerd, is een bedrijfsuitkomst. Die twee samenvoegen tot één foutpad maakt beide moeilijker te debuggen.

Voor ontwikkelaars: volgorde, normalisatie en de tests die ertoe doen

Drie gewoonten zorgen dat deze code de tijd doorstaat.

Zet de reeks op één plek. Lengte, tekens, prefix en controlesom horen in één routine met een vastgelegde volgorde, aangeroepen vanuit zowel de client als de server. Gedupliceerde logica is waar de twee lagen stilletjes uit elkaar drijven.

Normaliseer één keer, en bewaar het origineel. Verwijder scheidingstekens, houd de cijfers als een string, en laat nooit een numeriek type de waarde aanraken. Bewaar de opgeschoonde vorm voor vergelijking en, als je die nodig hebt voor weergave, ook de gegroepeerde vorm — maar leid de ene af uit de andere in plaats van twee onafhankelijke kopieën op te slaan die van mening kunnen verschillen.

Test daarna de fouten, niet het succes. De gevallen die echte bugs vinden, zijn een geldig nummer met één cijfer veranderd, een nummer met een letter erin, een nummer met een voorloopnul, een lege inzending, een waarde van maximale lengte, en een plakactie met scheidingstekens. Assert voor elk de specifieke melding die je gebruiker ontvangt, niet alleen dat de validatie faalde.

Het is ook de moeite waard te controleren waar de waarde kan reizen. Validatiehelpers worden vaak hergebruikt, en een routine die voor een formulier is geschreven, wordt soms aangeroepen met waarden die uit een wachtrij of een import kwamen. Die aanroepers hebben dezelfde regels nodig, en ze hebben zelden een gebruiker aan wie ze een melding kunnen tonen — wat betekent dat de fout ergens moet worden vastgelegd waar een mens het leest.

Houd ten slotte in de gaten wat het veld met de data doet nadat die is geaccepteerd. Maskerings-, opslag- en loggingregels worden bepaald door de standaard van de kaartindustrie in plaats van door je eigen voorkeuren, en de compliancenotities vatten de delen samen die een testomgeving raken. De opmaakgids detailleert de lengte- en prefixregels die hierboven worden genoemd.

Oefenen op gegenereerde nummers

De snelste manier om een validator te controleren is hem te richten op data waarvan je de verwachte uitkomst vooraf kent. De kaartnummersgenerator produceert batches met nummers die door constructie goed gevormd zijn, dus elke afwijzing is ofwel een bug in de validator ofwel een regel die je niet van plan was te schrijven. Genereer een set, beschadig bewust één cijfer in een kopie, en bevestig dat de twee anders worden geclassificeerd met twee verschillende meldingen.

Volgende stappen

Schrijf de controleorde op als een opmerking boven de routine, zorg dat de server haar onafhankelijk toepast, en voeg één negatieve fixture toe voor elke positieve. Als je formulier ook een datum of een beveiligingscode verzamelt, somt de checklist voor betaalformulieren de omliggende stromen op waartoe die velden behoren.

Verder lezen

Handleidingen over Generator voor valse creditcardnummers (testkaarten)