Formatierung, Kartentyp und Luhn-Prüfsumme im Zusammenspiel
Eine Kreditkarten-Eingabemaske ist mehr als das Einfügen von Leerzeichen alle vier Ziffern. Kartentyp-Erkennung, unterschiedliche Gruppierungslängen bei American Express, die Luhn-Prüfsumme und ein Cursor, der beim Tippen nicht ständig zurückspringt, machen aus einer simplen Formatierung ein kleines, aber anspruchsvolles Alpine.js Projekt.
Inhaltsverzeichnis
- 1. Warum eine Kreditkarten-Eingabemaske mehr als Formatierung ist
- 2. Kartentyp live erkennen: Visa, Mastercard, American Express
- 3. Ziffern in Vierergruppen formatieren, mit Sonderfall Amex
- 4. Cursor-Position beim Formatieren nicht verlieren
- 5. Der Luhn-Algorithmus: Prüfsumme ohne Server-Anfrage
- 6. Ablaufdatum und Prüfziffer mit passenden Regeln
- 7. Barrierefreie Fehlermeldungen und Autofill-Kompatibilität
- 8. Sicherheitsgrenzen: was die Client-Maske nicht leisten darf
- 9. Eingabemasken-Ansätze im Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Warum eine Kreditkarten-Eingabemaske mehr als Formatierung ist
Eine unformatierte Zahlenfolge aus sechzehn Ziffern ist für Menschen schwer zu lesen und noch schwerer auf Tippfehler zu prüfen. Eine gute Kreditkarten-Eingabemaske gruppiert die Ziffern visuell, erkennt den Kartentyp anhand der ersten Ziffern und gibt sofortiges Feedback, ob die eingegebene Nummer überhaupt strukturell gültig sein kann, lange bevor eine Zahlung tatsächlich autorisiert wird.
Der naive Ansatz, bei jedem Tastendruck ein Leerzeichen nach jeder vierten Ziffer einzufügen, funktioniert nur für Kartentypen mit einheitlicher Vierergruppierung. American Express nutzt jedoch ein 4-6-5-Muster, was bedeutet, dass eine Kreditkarten-Eingabemaske den erkannten Kartentyp kennen muss, bevor sie überhaupt entscheidet, wo Leerzeichen eingefügt werden.
Der dritte Baustein ist die Luhn-Prüfsumme, ein einfacher mathematischer Algorithmus, der die meisten Tippfehler bei Kreditkartennummern schon vor dem Absenden entdeckt. Zusammen ergeben Kartentyp-Erkennung, korrekte Gruppierung und Luhn-Prüfung eine Kreditkarten-Eingabemaske, die sich wie eine professionelle Zahlungslösung anfühlt, obwohl sie komplett clientseitig mit Alpine.js läuft.
2. Kartentyp live erkennen: Visa, Mastercard, American Express
Jeder Kartenanbieter nutzt ein festes Präfix-Muster für seine Kartennummern: Visa beginnt immer mit einer 4, Mastercard mit 51 bis 55 oder dem neueren Bereich 2221 bis 2720, American Express mit 34 oder 37. Diese Präfixe lassen sich mit einfachen regulären Ausdrücken abgleichen, sobald die ersten ein bis vier Ziffern eingegeben wurden.
Die Kreditkarten-Eingabemaske sollte den erkannten Typ nicht nur intern speichern, sondern auch visuell zurückmelden, etwa durch ein kleines Logo-Icon, das während der Eingabe erscheint. Das gibt dem Nutzer sofortiges Vertrauen, dass die Eingabe korrekt interpretiert wird, und erlaubt es der Maske, ab diesem Zeitpunkt die richtige Gruppierungsregel anzuwenden.
// Card type detection based on IIN (Issuer Identification Number) prefixes
function creditCardField() {
return {
rawNumber: '',
cardType: null,
detectCardType(digits) {
if (/^4/.test(digits)) return 'visa';
if (/^5[1-5]/.test(digits) || /^2(22[1-9]|2[3-9]|[3-6]|7[0-1]|720)/.test(digits)) return 'mastercard';
if (/^3[47]/.test(digits)) return 'amex';
return null;
},
onInput(event) {
const digits = event.target.value.replace(/\D/g, '');
this.rawNumber = digits;
this.cardType = this.detectCardType(digits);
},
};
}
3. Ziffern in Vierergruppen formatieren, mit Sonderfall Amex
Sobald der Kartentyp bekannt ist, entscheidet die Kreditkarten-Eingabemaske über das passende Gruppierungsmuster. Visa und Mastercard folgen dem einfachen 4-4-4-4-Muster für sechzehn Ziffern. American Express hingegen nutzt fünfzehn Ziffern in einem 4-6-5-Muster, was bedeutet, dass ein generischer Vierergruppen-Formatter für Amex-Karten falsch formatierte und damit verwirrende Ausgaben produzieren würde.
Die Formatierungsfunktion sollte deshalb ein Array mit Gruppengrößen entgegennehmen, das je nach erkanntem Kartentyp unterschiedlich aussieht. Diese Trennung von Rohdaten und Anzeigeformat ist wichtig: der interne Zustand speichert immer nur die reinen Ziffern, während die Formatierung erst beim Rendern angewendet wird.
function creditCardField() {
return {
rawNumber: '',
cardType: null,
// Group sizes differ per card type: Amex uses 4-6-5, others use 4-4-4-4
groupSizes: {
visa: [4, 4, 4, 4],
mastercard: [4, 4, 4, 4],
amex: [4, 6, 5],
default: [4, 4, 4, 4],
},
get formatted() {
const sizes = this.groupSizes[this.cardType] ?? this.groupSizes.default;
const groups = [];
let position = 0;
for (const size of sizes) {
const chunk = this.rawNumber.slice(position, position + size);
if (!chunk) break;
groups.push(chunk);
position += size;
}
return groups.join(' ');
},
};
}
4. Cursor-Position beim Formatieren nicht verlieren
Sobald Leerzeichen programmatisch in ein Textfeld eingefügt werden, springt der Cursor bei den meisten naiven Implementierungen ans Ende des Felds zurück. Der Nutzer tippt dann mitten in der Kartennummer, sieht aber, wie der Cursor nach jeder Eingabe ans Ende der Kreditkarten-Eingabemaske hüpft, was das Korrigieren einzelner Ziffern praktisch unmöglich macht.
Die Lösung ist, die Cursor-Position vor der Neuformatierung zu merken, die Anzahl der neu eingefügten Leerzeichen bis zur ursprünglichen Position zu zählen, und den Cursor anschließend an die korrigierte Position zu setzen. Das erfordert einen direkten Zugriff auf selectionStart und setSelectionRange() des Input-Elements, was in Alpine über eine Methode auf dem $refs-Objekt erfolgt.
function creditCardField() {
return {
rawNumber: '',
onInput(event) {
const input = event.target;
const previousLength = input.value.length;
const cursorPosition = input.selectionStart;
this.rawNumber = input.value.replace(/\D/g, '').slice(0, 16);
const newValue = this.formatted;
this.$nextTick(() => {
input.value = newValue;
// Adjust cursor for inserted spaces before the original position
const lengthDiff = newValue.length - previousLength;
const newPosition = Math.max(0, cursorPosition + lengthDiff);
input.setSelectionRange(newPosition, newPosition);
});
},
};
}
5. Der Luhn-Algorithmus: Prüfsumme ohne Server-Anfrage
Der Luhn-Algorithmus ist eine einfache Prüfsummenformel, die praktisch alle gängigen Kreditkartennummern erfüllen. Er verdoppelt jede zweite Ziffer von rechts, zieht neun ab, wenn das Ergebnis über neun liegt, summiert alle Ziffern und prüft, ob die Summe durch zehn teilbar ist. Diese Prüfung entdeckt zuverlässig einzelne Zifferndreher und die meisten Vertauschungen benachbarter Ziffern, ohne dass eine Netzwerk-Anfrage nötig wäre.
Wichtig ist, dass eine gültige Luhn-Prüfsumme nur bedeutet, dass die Nummer strukturell plausibel ist, nicht dass die Karte tatsächlich existiert oder gedeckt ist. Die Kreditkarten-Eingabemaske nutzt Luhn ausschließlich, um offensichtliche Tippfehler früh abzufangen, während die eigentliche Autorisierung immer beim Zahlungsdienstleister stattfindet.
function creditCardField() {
return {
rawNumber: '',
// Luhn checksum: catches typos before any network request
isLuhnValid() {
const digits = this.rawNumber.split('').map(Number).reverse();
let sum = 0;
digits.forEach((digit, index) => {
if (index % 2 === 1) {
digit *= 2;
if (digit > 9) digit -= 9;
}
sum += digit;
});
return this.rawNumber.length >= 13 && sum % 10 === 0;
},
};
}
6. Ablaufdatum und Prüfziffer mit passenden Regeln
Neben der Kartennummer gehört zu jeder Kreditkarten-Eingabemaske auch das Ablaufdatum im Format MM/JJ und der CVC-Code auf der Rückseite der Karte. Das Ablaufdatum sollte automatisch einen Schrägstrich nach den ersten zwei Ziffern einfügen und gleichzeitig prüfen, ob der Monat zwischen 01 und 12 liegt und das Datum in der Zukunft liegt, nicht bereits abgelaufen ist.
Die Länge des CVC-Codes hängt ebenfalls vom Kartentyp ab: American Express nutzt vier Ziffern, alle anderen gängigen Anbieter drei. Die Kreditkarten-Eingabemaske sollte deshalb die maximale Eingabelänge des CVC-Feldes dynamisch an den zuvor erkannten Kartentyp anpassen, statt eine feste Länge für alle Karten vorzugeben.
7. Barrierefreie Fehlermeldungen und Autofill-Kompatibilität
Browser-Autofill füllt Kreditkartenfelder oft ohne Leerzeichen oder mit abweichender Formatierung aus. Eine robuste Kreditkarten-Eingabemaske muss deshalb auch beim @input-Ereignis nach einem Autofill dieselbe Bereinigung und Neuformatierung durchlaufen wie bei manueller Eingabe, sonst zeigt das Feld nach dem Autofill eine inkonsistente Darstellung.
Für Screenreader-Nutzer sollte das Kartennummernfeld ein autocomplete="cc-number"-Attribut tragen, das Ablaufdatum autocomplete="cc-exp" und der CVC autocomplete="cc-csc". Diese Standard-Attribute ermöglichen nicht nur Passwort-Manager-Integration, sondern auch, dass assistive Technologien den Zweck jedes Feldes korrekt ankündigen. Ein ungültiges Luhn-Ergebnis sollte über aria-invalid und eine klare Textmeldung kommuniziert werden, nicht nur über eine rote Umrandung.
8. Sicherheitsgrenzen: was die Client-Maske nicht leisten darf
Eine Kreditkarten-Eingabemaske in Alpine.js darf niemals die einzige Sicherheitsgrenze einer Zahlung sein. PCI-DSS-Vorgaben verlangen, dass rohe Kartennummern in den meisten Konfigurationen niemals den eigenen Server erreichen, sondern direkt an einen zertifizierten Zahlungsdienstleister wie Stripe oder Adyen übermittelt werden, meist über ein eingebettetes iFrame-Formularfeld des Anbieters.
Die hier beschriebene Maske eignet sich deshalb primär für die Benutzerführung: Formatierung, Kartentyp-Anzeige und frühe Fehlererkennung. Sobald ein PCI-konformer Zahlungsanbieter im Spiel ist, übernimmt dessen eigenes, isoliertes Formularfeld die tatsächliche Eingabe der sensiblen Daten, während die Alpine-Komponente nur noch für die umgebende Formularlogik zuständig ist.
9. Eingabemasken-Ansätze im Vergleich
Die folgende Tabelle vergleicht typische Fallstricke beim Bau einer Kreditkarten-Eingabemaske mit dem empfohlenen Vorgehen.
| Aspekt | Fehleranfällig | Empfohlene Eingabemaske | Vorteil |
|---|---|---|---|
| Gruppierung | feste 4-4-4-4 für alle Karten | Gruppengröße je Kartentyp | korrekt für Amex 4-6-5 |
| Cursor | springt nach jeder Eingabe ans Ende | Position anhand Längendifferenz korrigieren | Korrektur in der Mitte möglich |
| Plausibilität | nur Längenprüfung | Luhn-Prüfsumme | entdeckt Tippfehler früh |
| CVC-Länge | fest drei Ziffern für alle | vier Ziffern für Amex, drei sonst | korrekt für alle Kartentypen |
| Speicherung | rohe Nummer an eigenen Server | PCI-konformer Zahlungsanbieter | keine PCI-DSS-Pflichten für euch |
Eine sauber gebaute Kreditkarten-Eingabemaske verbessert die Benutzerführung erheblich, ersetzt aber niemals die eigentliche Sicherheitsarchitektur einer Zahlungsintegration. Beide Ebenen ergänzen sich, wenn sie klar voneinander getrennt bleiben.
Mironsoft
Alpine.js Zahlungsformulare und PCI-konforme Checkout-Integration
Zahlungsformular, das sich unprofessionell anfühlt?
Wir bauen euch eine Kreditkarten-Eingabemaske mit Kartentyp-Erkennung, Luhn-Prüfung und sauberer Integration in PCI-konforme Zahlungsanbieter für euren Magento-Checkout.
Eingabemaske
Formatierung, Kartentyp-Erkennung und Luhn-Prüfung nach Maß
Zahlungsanbieter-Integration
Stripe, Adyen und weitere PCI-konforme Anbieter anbinden
Barrierefreiheit
Autocomplete-Attribute und aria-invalid für Zahlungsfelder
10. Zusammenfassung
Eine gute Kreditkarten-Eingabemaske in Alpine.js kombiniert vier Bausteine: Kartentyp-Erkennung anhand des Präfixes, kartentypabhängige Gruppierung, eine Cursor-Korrektur, die Eingaben in der Mitte der Nummer weiterhin erlaubt, und die Luhn-Prüfsumme als frühe Plausibilitätsprüfung ohne Server-Anfrage. Ablaufdatum und CVC-Länge folgen denselben kartentypabhängigen Regeln.
Wichtig bleibt die klare Grenze: die Maske verbessert die Bedienung, ersetzt aber niemals die PCI-konforme Übertragung sensibler Kartendaten an einen zertifizierten Zahlungsdienstleister. Wer diese Trennung von Anfang an einhält, bekommt eine Kreditkarten-Eingabemaske, die professionell wirkt und gleichzeitig die Sicherheitsanforderungen der Zahlungsindustrie respektiert.
Kreditkarten-Eingabemaske mit Alpine.js — Das Wichtigste auf einen Blick
Kartentyp
Präfix-Erkennung für Visa, Mastercard und Amex steuert Gruppierung und CVC-Länge.
Cursor
Position nach der Neuformatierung anhand der Längendifferenz korrigieren, nicht ans Ende springen.
Luhn
Prüfsumme entdeckt Tippfehler clientseitig, ersetzt aber keine echte Autorisierung.
Sicherheit
Rohe Kartennummern gehören in ein PCI-konformes Anbieter-Formular, nicht auf den eigenen Server.