Prendi due carte di pagamento di reti diverse e i numeri non si somigliano. Una può avere sedici cifre raggruppate a quattro a quattro, un’altra quindici cifre raggruppate quattro, sei e cinque, e le cifre finali obbediscono alla stessa somma di controllo mentre le lunghezze non corrispondono affatto. Costruire numeri di carte di test per rete significa lavorare deliberatamente con quelle differenze, perché un’integrazione che vede sempre e solo una marca è un’integrazione che non ha mai eseguito la maggior parte del proprio codice.
Questo articolo espone le differenze che contano, mostra come leggere gli intervalli pubblicati e spiega perché un numero con il prefisso giusto appartiene comunque a nessuno.
Ogni rete ha il proprio piano di numerazione
Una rete di carte registra gli intervalli di prefissi emittente che riconoscerà e il numero di cifre che una carta in ciascun intervallo porterà. Quella registrazione è ciò che permette a un terminale di pagamento di decidere, senza alcuna chiamata di rete, a quale marca appartiene una carta e se il numero sia anche solo plausibile.
Il risultato è un piccolo insieme di famiglie anziché un’unica forma universale. Alcune reti usano una lunghezza quasi esclusivamente; altre supportano diverse lunghezze per diversi livelli di prodotto o regioni. Anche i codici di sicurezza differiscono, sia per quante cifre contengono sia per il lato della carta su cui sono stampati. Un insieme di test che ignora quelle differenze supererà la revisione e fallirà in produzione.
Come si sceglie un prefisso per un caso di test?
Lavora all’indietro dal ramo che vuoi esercitare. Se il tuo modulo cambia layout in base alla marca rilevata, ti serve almeno un numero per marca che attivi un layout distinto. Se la tua validazione ha un ramo per un numero a quindici cifre, ti serve un numero di quella lunghezza. Se il tuo pagamento gestisce un codice di sicurezza a quattro cifre, ti serve una carta la cui rete ne usi uno.
Poi controlla che il prefisso scelto sia pubblicato anziché inventato. Usare un intervallo che nessuna rete ha registrato produce un numero che il tuo stesso rilevamento del prefisso rifiuterà, il che fa sembrare il test un fallimento della logica di rilevamento anziché della fixture.
Una scorciatoia pratica è generare un numero per ogni marca che supporti e conservare l’intero insieme come una fixture con un nome, così che l’insieme possa essere rigenerato ogni volta che viene aggiunta una marca o cambia una regola di lunghezza.
Gli intervalli pubblicati in sintesi
La tabella seguente riassume gli intervalli di prefissi documentati pubblicamente e le forme che li accompagnano. Descrive piani di numerazione, non prodotti o emittenti specifici.
| Rete | Intervalli di prefissi pubblicati | Lunghezza tipica | Codice di sicurezza |
|---|---|---|---|
| Visa | inizia con 4 | 16 cifre, con forme a 13 e più lunghe anch’esse registrate | 3 cifre, retro |
| Mastercard | da 51 a 55, e da 2221 a 2720 | 16 cifre | 3 cifre, retro |
| American Express | 34 e 37 | 15 cifre | 4 cifre, fronte |
| Discover | 6011, 65, da 644 a 649, e da 622126 a 622925 | 16 cifre, forme più lunghe registrate | 3 cifre, retro |
| JCB | da 3528 a 3589 | 16 cifre, forme più lunghe registrate | 3 cifre, retro |
| Diners Club | da 300 a 305, 36, e da 38 a 39 | 14 cifre, con 16 usate anch’esse | 3 cifre, retro |
| UnionPay | 62 | 16 cifre, forme più lunghe registrate | 3 cifre, retro |
| Maestro | 50, e da 56 a 69 | variabile entro il limite dello standard | 3 cifre, retro |
Due avvertenze vanno accanto alla tabella. Gli intervalli sono registrati dalle reti e cambiano occasionalmente, quindi un rilevatore dovrebbe essere scritto per tollerare aggiunte anziché trattare l’elenco come definitivo. E la lunghezza è una proprietà dell’intervallo, non della marca nel suo complesso: una regola che dice che una particolare rete ha sempre sedici cifre finirà prima o poi per essere sbagliata.
Perché anche la lunghezza del codice di sicurezza differisce?
Che American Express usi quattro cifre non è un upgrade di sicurezza rispetto a tre; è semplicemente come è scritta la specifica di quella rete. L’effetto pratico ricade sul modulo, che deve sapere quanti caratteri accettare.
Se la tua interfaccia offre un unico campo con un massimo fisso di tre caratteri, un codice American Express verrà troncato silenziosamente e il cliente vedrà un fallimento che non ha senso per lui. L’approccio robusto è accettare la lunghezza attesa dalla rete una volta nota la marca, e consentire un massimo leggermente più generoso quando non lo è, così che un incolla non perda mai un carattere che all’utente servirà riavere.
Un prefisso corrispondente significa che il numero è reale?
No. Il prefisso ti dice a quale intervallo un numero dichiara di appartenere, e nulla più. Qualsiasi stringa di cifre che inizia con un intervallo registrato può essere completata con cifre centrali arbitrarie e una cifra finale calcolata, producendo qualcosa che ogni controllo locale accetterà.
Lo stesso vale per i dati generati: un numero è strutturalmente valido e non è mai stato emesso a nessuno. È una proprietà su cui vale la pena contare anziché un limite, perché significa che il valore può essere usato in una demo o in una fixture senza alcun rischio che si risolva in un conto reale. Significa anche che un controllo di formato superato non dovrebbe mai essere descritto all’utente come conferma che la sua carta esiste.
Per gli sviluppatori: costruire una matrice di test per rete
Una matrice di test trasforma un elenco di marche in un elenco di decisioni, e vale la pena di scriverla in una tabella a quattro colonne: la marca, l’intervallo di prefissi usato, il risultato di rilevamento atteso e il comportamento del modulo che ti aspetti di conseguenza.
Da lì, tre regole mantengono utile la matrice. Includi esattamente un numero per ogni comportamento distinto anziché molti numeri per marca, perché le fixture ridondanti aggiungono manutenzione senza aggiungere copertura. Registra la lunghezza attesa per ogni voce, così che una modifica a una regola di lunghezza si manifesti come un test fallito anziché come un allentamento non notato. E mantieni almeno un numero il cui prefisso non appartenga ad alcun intervallo che supporti, così che il percorso di marca sconosciuta venga esercitato anziché dato per scontato.
Fai attenzione alla funzione di rilevamento stessa. Le implementazioni che confrontano solo la prima cifra accorpano ogni carta bancaria, e quelle che verificano gli intervalli nell’ordine sbagliato possono lasciare che un intervallo più stretto venga inghiottito da uno più ampio. Entrambi i bug sono invisibili finché non arriva una carta specifica, ed è esattamente ciò che la matrice esiste per prevenire.
Infine, ricorda che il rilevamento del formato non è autorizzazione. Una matrice di test è un’affermazione sul tuo codice, e nessuna disposizione di prefissi ti dirà se una carta è valida per un pagamento. La guida alla validazione copre dove il rilevamento appartiene nella sequenza dei controlli, e la guida al formato spiega come il prefisso si rapporta al resto del numero.
Produrre una carta per rete
Per costruire l’insieme di fixture, apri il generatore di numeri di carta, scegli una rete e copia il risultato; ripeti per ogni marca che supporti, poi conserva la raccolta insieme a una nota su quale comportamento ciascuna voce è destinata ad attivare. Generare anziché copiare intervalli dalla documentazione mantiene il lotto internamente coerente e ti dà una quantità che può essere estesa ogni volta che viene aggiunto un nuovo metodo di pagamento.
Le note PCI DSS vale la pena di leggerle prima che quell’insieme venga salvato in un repository condiviso, e la guida alle carte di test dei fornitori spiega quando un numero sandbox programmato è una scelta migliore di uno sintetico.
Passi successivi
Prepara la matrice, genera una carta per ogni comportamento distinto e aggiungi una fixture per un intervallo che deliberatamente non supporti, così che il percorso sconosciuto resti coperto. Poi rivedi la funzione di rilevamento rispetto alla tabella, partendo dagli intervalli più stretti, per confermare che nessun ramo sia irraggiungibile.